Error cs0019 operator cannot be applied to operands of type vector3 and vector3

I am trying to get a rectangle to move between two positions which I refer to as _positionA and _positionB. Both are of type Vector3. The rectangle moves just fine. However, when it reaches _positi...

To simplify the answer, Vector3 is a custom struct provided by the UnityEngine namespace. When we create custom class or struct types, we must also define its operators. As such, there is no default logic for the >= operator. As pointed out by Evgeny Vasilyev, _rect_tfm.position == _positionB makes sense, as we can directly check the Vector3.x, Vector3.y and Vector3.z values. _rect_tfm.position >= _positionB does not make as much sense, due to the fact that a Vector3 is represented by three separate values.

We could overload the Vector3 class to contain the suitable operators in theory, but that seems rather complicated. Instead, it would be easier to simply extend the Vector3 class with a suitable method. That being said, it seems that your intending to use this logic for movement. As such, you might find it much easier to use the Vector3.Lerp method; if so, read further below.

Adding extension methods to Vector3

As previously mentioned, applying <= or >= to a Vector3 is often illogical. For movement, you probably want to read further for the Vector3.Lerp method. That said, you might want to apply the <= => arithmetic for other reasons, so I will give you an easy alternate.

Instead of applying the logic of Vector3 <= Vector3 or Vector3 >= Vector3, I propose extending the Vector3 class to include methods for isGreaterOrEqual(Vector3 other) and isLesserOrEqual(Vector3). We can add extension methods to a struct or class by declaring them in a static class that does not inherit. We also include the target class or struct as the first parameter, using the this keyword. Note that in my example, I assume that you mean to ensure that all three main values (x, y and z) are all greater or equal, or lesser or equal, respectively. You can provide your own logic, here, as you require.

public static class ExtendingVector3
{
    public static bool IsGreaterOrEqual(this Vector3 local, Vector3 other)
    {
        if(local.x >= other.x && local.y >= other.y && local.z >= other.z)
        {
            return true;
        }
        else
        {
            return false;
        }
    }

    public static bool IsLesserOrEqual(this Vector3 local, Vector3 other)
    {
        if(local.x <= other.x && local.y <= other.y && local.z <= other.z)
        {
            return true;
        }
        else
        {
            return false;
        }
    }
}

When we attempt to call these methods from the Vector3 class, local will represent the Vector3 instance we are calling the method from. You will note that the methods are static; extension methods must be static, but you still have to call them from an instance. Given the above extension methods, you can now apply them directly to your Vector3 types.

Vector3 left;
Vector3 right;

// Is left >= right?
bool isGreaterOrEqual = left.IsGreaterOrEqual(right);

// Is left <= right?
bool isLesserOrEqual = left.IsLesserOrEqual(right);

Moving Vector3 with Vector3.Lerp

Calling the Vector3.Lerp method allows us to determine the exact position between two Vector3 values at a given time. An added benefit of this method is that the Vector3 will not overshoot its target. Vector3.Lerp takes three parameters; the start position, the end position, and the current position represented as a value between 0 and 1. It outputs the resulting position as a Vector3, which we can directly set as the current position.

Solving your problem, I propose using Vector3.Lerp to move to a targetPosition. After calling the Move method in each Update, we can check if we have reached said target; Lerp.Vector3 will not overshoot, so transform.position == targetPosition becomes reliable. We can now check the position, and change the targetPosition to leftPosition or rightPosition to reverse the movement, accordingly.

public Vector3 leftPosition, rightPosition;
public float speed;
public Vector3 targetPosition;

private void Awake()
{
    targetPosition = rightPosition;
}

private void Update()
{
    Move();

    if(transform.position == targetPosition)
    {
        // We have arrived at our intended position. Move towards the other position.
        if(targetPosition == rightPosition)
        {
            // We were moving to the right; time to move to the left.
            targetPosition = leftPosition;
        }
        else
        {
            // We were moving to the left; time to move to the right.
            targetPosition = rightPosition;
        }
    }
}

private void Move()
{
    // First, we need to find out the total distance we intend to move.
    float distance = Vector3.Distance(transform.position, targetPosition);

    // Next, we need to find out how far we intend to move.
    float movement = speed * Time.deltaTime;

    // We find the increment by simply dividing movement by distance.
    // This will give us a decimal value. If the decimal is greater than
    // 1, we are moving more than the remaining distance. Lerp 
    // caps this number at 1, which in turn, returns the end position.
    float increment = movement / distance;

    // Lerp gives us the absolute position, so we pass it straight into our transform.
    transform.position = Vector3.Lerp(transform.position, targetPosition, increment);
}

You can see this demonstrated in the following animation. I translate the blue cube with Vector3.LerpUnclamped, which gives us a similar result to simple unchecked translation. I translate the red cube using Vector3.Lerp. Left unchecked, the blue cube moves off into oblivion; while the red cube stops exactly where I intend it to. You can read more about this type of movement in the Stack Overflow documentation.

Left unchecked, the blue cube moves off into oblivion; while the red cube stops exactly where I intend it to.

Вообщем решил я сделать скрипт стрельбы лазерным оружием, по задумке оно должно выдавать непрерывный лазерный луч наносящий урон, попадая на стены наносить декаль дырки от выстрела, но вот дело в том что декаль я сделал как префаб в котором quad с нанесенной текстурой дырки, и если просто нанести ее туда же где и raycast.hit, то происходит оверлэппинг и декаль мерцает, я решил решить проблему добавив зазор между декалью и raycast hit но после этого код не работает выдавая ошибку error CS0019: Operator ‘*’ cannot be applied to operands of type ‘Vector3’ and ‘double’
Подскажите, как мне лучше всего реализовать нанесение декалей? И кстати вопрос еще не в тему, как отрисовать лазер?
Версия Unity 2020.3.25f1

C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
 
public class raycast_shooting : MonoBehaviour
{
    public bool isLaser;
    public int damage;
    public KeyCode fire;
    public Transform fps;
    public float fireRate;
    public float nextFire;
    public LineRenderer laserline;
    public GameObject decal;
    public Transform decals;
    public Transform gunEnd;
 
    void ShotEffect() { 
    
    }
 
    // Update is called once per frame
    void Update()
    {
        if (Input.GetKey(fire))
        {
            nextFire = Time.time + fireRate;
            Ray ray = new Ray(fps.position, fps.forward);
            RaycastHit hit;
            if (Physics.Raycast(ray, out hit))
            {
                GameObject g = Instantiate<GameObject>(decal);
                g.transform.position = hit.point + hit.normal * 0.01;
                g.transform.rotation = Quaternion.LookRotation(-hit.normal);
                g.transform.SetParent(decals);
            }
        }
    }
}

__________________
Помощь в написании контрольных, курсовых и дипломных работ, диссертаций здесь

Оператор * РЕШЕНО

Оператор * РЕШЕНО

Пишу вот так:

Используется csharp

GameObject theSplat=(GameObject)Instantiate(splat,hit.point+(hit.normal * 2.5),Quaternion.identity);

Говорит:
Assets/Scripts/player_shoot.cs(38,106): error CS0019: Operator `*’ cannot be applied to operands of type `UnityEngine.Vector3′ and `double’

Что не так? :-?

Последний раз редактировалось bumer7721 12 авг 2012, 15:42, всего редактировалось 1 раз.

Аватара пользователя
bumer7721
UNIт
 
Сообщения: 102
Зарегистрирован: 29 июл 2011, 14:18

Re: Оператор *

Сообщение Syberex 12 авг 2012, 14:05

Говорит, что не может применить оператор * (умножение) к операндам типа Vector3 (hit.normal) и double (2.5).

А так если?

Используется csharp

GameObject theSplat=(GameObject)Instantiate(splat,hit.point+(hit.normal * 2.5f),Quaternion.identity);
 

Аватара пользователя
Syberex
Адепт
 
Сообщения: 2292
Зарегистрирован: 14 янв 2011, 20:35
Откуда: Кострома
  • Сайт

Re: Оператор *

Сообщение Paul Siberdt 12 авг 2012, 14:39

Зато все на сишарпах ваяют, млять! Цирк! :ymparty: X(

Аватара пользователя
Paul Siberdt
Адепт
 
Сообщения: 5317
Зарегистрирован: 20 июн 2009, 21:24
Откуда: Moscow, Russia
Skype: siberdt
  • Сайт

Re: Оператор *

Сообщение bumer7721 12 авг 2012, 15:41

СПАСИБО!!! Помогло, я просто провтыкал, последнее время lua писал

Аватара пользователя
bumer7721
UNIт
 
Сообщения: 102
Зарегистрирован: 29 июл 2011, 14:18

Re: Оператор * РЕШЕНО

Сообщение Левш@ 12 авг 2012, 15:55

типа Vector3 (hit.normal) и double (2.5)

hit.normal != Vector3
hit.normal = Quaternion

Vector3 = hit.point

Аватара пользователя
Левш@
Адепт
 
Сообщения: 4073
Зарегистрирован: 14 окт 2009, 16:34
Откуда: IBERIA
Skype: bars_levsha
  • Сайт

Re: Оператор * РЕШЕНО

Сообщение Syberex 12 авг 2012, 16:16

Левш@ писал(а):

типа Vector3 (hit.normal) и double (2.5)

hit.normal != Vector3
hit.normal = Quaternion

Vector3 = hit.point

Как так квантернион? :D Можно ссылку?
И в сообщении об ошибке про квантернион ни слова, даже если предположить, что это так — как тогда растолковать сообщение об ошибке? Там что double * квантернион, получаем double и умножаем на Vector3 ???

Аватара пользователя
Syberex
Адепт
 
Сообщения: 2292
Зарегистрирован: 14 янв 2011, 20:35
Откуда: Кострома
  • Сайт

Re: Оператор * РЕШЕНО

Сообщение Левш@ 12 авг 2012, 16:22

Как так квантернион?

Сорьки, погорячился… :) hit.normal = вектор направление.
Имелось ввиду что это не point.position :ymsmug:

Аватара пользователя
Левш@
Адепт
 
Сообщения: 4073
Зарегистрирован: 14 окт 2009, 16:34
Откуда: IBERIA
Skype: bars_levsha
  • Сайт


Вернуться в Почемучка

Кто сейчас на конференции

Сейчас этот форум просматривают: Yandex [Bot] и гости: 22



The compiler is telling you that there is no operator overload between those two types.

Here are the operator overloads for Quaternion:

public static bool operator ==(Quaternion lhs, Quaternion rhs);

public static bool operator !=(Quaternion lhs, Quaternion 

public static Quaternion operator *(Quaternion lhs, Quaternion rhs);

public static Vector3 operator *(Quaternion rotation, Vector3 point);

Here are the operator overloads for Vector3:

public static Vector3 operator +(Vector3 a, Vector3 b);

public static Vector3 operator /(Vector3 a, float d);

public static bool operator ==(Vector3 lhs, Vector3 rhs);

public static bool operator !=(Vector3 lhs, Vector3 rhs);

public static Vector3 operator *(Vector3 a, float d);

public static Vector3 operator *(float d, Vector3 a);

public static Vector3 operator -(Vector3 a, Vector3 b);

public static Vector3 operator -(Vector3 a);

As you can see that while there is an overload with a Quaternion on the left side and Vector3 on the right, there are none that work in the opposite direction.

private static object[] GetEnumLookupData<TEnum>() where TEnum: Enum
{
    var data = Enum.GetValues(typeof(TEnum))
        .OfType<TEnum>()
        .Where(e => e != default(TEnum))
        .Select(e => new {Id = e, Name = e.ToString()})
        .ToArray();

    return data;
}

This does not compile, but returns a error:

CS0019: Operator ‘!=’ cannot be applied to operands of type ‘TEnum’ and ‘TEnum’

What am I missing here? Isn’t it clear that TEnum is a value type?

The funniest thing is that if I omit (TEnum) in default(TEnum), so it is now e != default it compiles, but default generates porbably just a null because I see 0 value in created EF Core migration. WTF?!

I tried to use EqualityComparer<TEnum>.Default.Equals(...) and it kinda worked, however, EF Core 2.1 has a bug: migrations with seeding of data with emun as primary key are unstable. This bug is fixed only in EF Core 2.2 preview.
So I changed to int and …

private static object[] GetEnumLookupData<TEnum>() where TEnum: struct, Enum
{
    var comparer = EqualityComparer<TEnum>.Default;

    var data = Enum.GetValues(typeof(TEnum))
        .OfType<TEnum>()
        .Where(e => !comparer.Equals(e, default))
        .Select(e => new {Id = (int)e, Name = e.ToString()})
        .ToArray();

    return data;
}

CS0030 Cannot convert type ‘TEnum’ to ‘int’

Понравилась статья? Поделить с друзьями:
  • Error cs0019 operator cannot be applied to operands of type char and string
  • Error cs0019 operator cannot be applied to operands of type bool and int
  • Error cs0019 operator cannot be applied to operands of type bool and double
  • Error cs0006 не удалось найти файл метаданных microsoft vsa dll
  • Error cs0006 metadata file could not be found