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.
Вообщем решил я сделать скрипт стрельбы лазерным оружием, по задумке оно должно выдавать непрерывный лазерный луч наносящий урон, попадая на стены наносить декаль дырки от выстрела, но вот дело в том что декаль я сделал как префаб в котором quad с нанесенной текстурой дырки, и если просто нанести ее туда же где и raycast.hit, то происходит оверлэппинг и декаль мерцает, я решил решить проблему добавив зазор между декалью и raycast hit но после этого код не работает выдавая ошибку error CS0019: Operator ‘*’ cannot be applied to operands of type ‘Vector3’ and ‘double’
Подскажите, как мне лучше всего реализовать нанесение декалей? И кстати вопрос еще не в тему, как отрисовать лазер?
Версия Unity 2020.3.25f1
C# | ||
|
__________________
Помощь в написании контрольных, курсовых и дипломных работ, диссертаций здесь
Оператор * РЕШЕНО
Оператор * РЕШЕНО
Пишу вот так:
Используется 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
Зато все на сишарпах ваяют, млять! Цирк!
-
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 = QuaternionVector3 = hit.point
Как так квантернион? Можно ссылку?
И в сообщении об ошибке про квантернион ни слова, даже если предположить, что это так — как тогда растолковать сообщение об ошибке? Там что double * квантернион, получаем double и умножаем на Vector3 ???
-
Syberex - Адепт
- Сообщения: 2292
- Зарегистрирован: 14 янв 2011, 20:35
- Откуда: Кострома
-
- Сайт
Re: Оператор * РЕШЕНО
Левш@ 12 авг 2012, 16:22
Как так квантернион?
Сорьки, погорячился… hit.normal = вектор направление.
Имелось ввиду что это не point.position
-
Левш@ - Адепт
- Сообщения: 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’