Позвольте мне переименовать переменные (для ясности):
Vector3 pos3d = new Vector3 (1f, 2f, 3f);
Vector2 pos2d = new Vector2 (1f, 2f);
Ответ
Это из-за сечения pos3d + pos2d
линии. Эта часть действительно неоднозначна, в то время +=
как нет. Позвольте мне уточнить, почему одно и почему другое.
Анализ 1
В этой строке
transform.position = pos3d + pos2d;
компилятор сначала пытается вычислить выражение, pos3d + pos2d
прежде чем продолжить, независимо от того, куда будет помещен результат.
Для этого система сначала пытается найти любую общедоступную статическую функцию, которая добавляет Vector3 плюс Vector2, например, такую возможную сигнатуру:
public static Vector3 operator +(Vector3 a, Vector2 b);
или, например, эта возможная подпись:
public static Vector2 operator +(Vector3 a, Vector2 b);
Тем не менее, в API нет ни одной из этих сигнатур, поэтому компилятор пытается «привести» параметры к известным сигнатурам.
Затем компилятор находит эти две потенциальные сигнатуры:
public static Vector3 operator +(Vector3 a, Vector3 b);
public static Vector2 operator +(Vector2 a, Vector2 b);
Они описаны здесь:
http://docs.unity3d.com/ScriptReference/Vector3-operator_add.html
и здесь:
http://docs.unity3d.com/ScriptReference/Vector2-operator_add.html.
Итак, есть две возможности:
Так как возможны оба приведения, pos2d может быть преобразован в Vector3, а pos3d - в Vector2, компилятор затем находит возможные способы компиляции одного и того же исходного кода (при условии наличия автоматических скрытых приведений).
Можно либо привести pos3d в Vector2 и перейти ко второй подписи, либо привести pos2d в Vector3 и перейти к первой подписи.
Поскольку выражение pos3d + pos2d
вычисляется в первую очередь, прежде чем принимать во внимание «где будет применен результат», тогда компилятор не знает, какое приведение вы, как кодер, хотели бы выполнить.
Если вы хотите перейти к 3D, вы можете написать это:
transform.position = pos3d + ( Vector3 )pos2d;
и проблема исчезла, как теперь понятно: сначала переместите pos2d в другой объект типа Vector3, затем выполните суммирование Vector3 + Vector3. При условии, что есть эта статическая подпись
public static Vector3 operator +(Vector3 a, Vector3 b);
доступно, что один будет использоваться без двусмысленности вообще.
Анализ 2
С другой стороны, когда вы делаете
transform.position = pos3d;
transform.position += pos2d;
нет никакой двусмысленности: первая строка назначает Vector3 в Vector3 (без сомнения).
Вторая строка эквивалентна
transform.position = transform.position + pos2d;
с учетом специфики transform.position оценивается только один раз, и поэтому принимается во внимание тип, как вы можете видеть на этой странице Microsoft об +=
операторе:
https://msdn.microsoft.com/en-us/library/sa7629ew.aspx
Кроме того, в нем говорится: «Оператор + = не может быть перегружен напрямую, но пользовательские типы могут перегружать оператор + (см. Оператор)». поэтому мы должны думать, что оператор Vector3
s +=
действует так, как описано в Microsoft, где он говорит:
x += y
эквивалентно
x = x + y
за исключением того, что х оценивается только один раз. Значение оператора + зависит от типов x и y (сложение для числовых операндов, конкатенация для строковых операндов и т. Д.).
поэтому мы можем быть уверены, что второй подход вызывает операнд + Vector3
класса, который имеет сигнатуру:
public static Vector3 operator +(Vector3 a, Vector3 b);
так что нет другого способа добиться этого, кроме как преобразовать pos2d в Vector3 благодаря неявному скрытому приведению, которое не может быть в любой другой форме.
Надеюсь помочь !!
редактировать
В связи Unity 5.0.1f1 Personal
с тем MonoDevelop-Unit 4.0.1
, как говорит Алекс М., строки:
transform.position = pos3d;
transform.position += pos2d;
все еще наложил ошибку "Assets/Scripts/CubeScript.cs(15,27): error CS0121: The call is ambiguous between the following methods or properties: 'UnityEngine.Vector2.operator +(UnityEngine.Vector2, UnityEngine.Vector2)' and 'UnityEngine.Vector3.operator +(UnityEngine.Vector3, UnityEngine.Vector3)'"
так что на самом деле + = использует обе подписи
public static Vector3 operator +(Vector3 a, Vector3 b);
public static Vector2 operator +(Vector2 a, Vector2 b);
независимо от того, что уже известно, «где» результат должен быть помещен (я полагаю, что вывод Vector2 можно преобразовать в место назначения (Vector3), и, возможно, если это приведение было невозможно, возможно, компилятор выберет тот, который имеет тип выхода).
Спасибо за точку зрения Алекс М.