Permítanme cambiar el nombre de los vars (para mayor claridad):
Vector3 pos3d = new Vector3 (1f, 2f, 3f);
Vector2 pos2d = new Vector2 (1f, 2f);
Responder
Es por la sección pos3d + pos2d
de la línea. Esta parte es realmente ambigua mientras que la +=
no lo es. Permítanme aclarar por qué uno y por qué el otro.
Análisis 1
En esta linea
transform.position = pos3d + pos2d;
el compilador primero intenta evaluar la expresión pos3d + pos2d
antes de continuar, independientemente de dónde se colocará el resultado.
Para hacerlo, el sistema primero intenta encontrar cualquier función estática pública que agregue un Vector3 más un Vector2, por ejemplo, esta posible firma:
public static Vector3 operator +(Vector3 a, Vector2 b);
o por ejemplo esta posible firma:
public static Vector2 operator +(Vector3 a, Vector2 b);
Sin embargo, no hay ninguna de esas firmas en la API, por lo que el compilador intenta "transmitir" parámetros a firmas conocidas.
Luego, el compilador encuentra esas dos firmas potenciales:
public static Vector3 operator +(Vector3 a, Vector3 b);
public static Vector2 operator +(Vector2 a, Vector2 b);
Estos están documentados aquí:
http://docs.unity3d.com/ScriptReference/Vector3-operator_add.html
y aquí:
http://docs.unity3d.com/ScriptReference/Vector2-operator_add.html
Entonces hay dos posibilidades:
Por lo tanto, dado que ambas versiones son posibles, pos2d se puede convertir en un Vector3 y pos3d se puede convertir en un Vector2, el compilador busca posibles formas de compilar el mismo código fuente (siempre y cuando se instalen automáticamente las versiones ocultas).
Es posible convertir pos3d en Vector2 y continuar con la segunda firma, o bien transmitir pos2d en Vector3 y continuar con la primera firma.
Como la expresión pos3d + pos2d
se evalúa primero, antes de tomar en cuenta "dónde se aplicará el resultado", entonces el compilador no sabe qué conversión le gustaría, como codificador, realizar.
Si quieres moverte hacia 3D, puedes escribir esto:
transform.position = pos3d + ( Vector3 )pos2d;
y el problema desapareció, como ahora está claro: primero mueva pos2d a otro objeto de tipo Vector3, luego haga la suma de Vector3 + Vector3. Siempre que exista esta firma estática
public static Vector3 operator +(Vector3 a, Vector3 b);
disponible, ese será usado sin ambigüedad alguna.
Análisis 2
Por otro lado, cuando lo haces
transform.position = pos3d;
transform.position += pos2d;
no hay ambigüedad: la primera línea asigna un Vector3 a un Vector3 (sin dudas).
La segunda línea es equivalente a
transform.position = transform.position + pos2d;
Con la particularidad, transform.position solo se evalúa una vez y, por lo tanto, el tipo se tiene en cuenta, como puede ver en esta página de Microsoft sobre el +=
operador:
https://msdn.microsoft.com/en-us/library/sa7629ew.aspx
Además, dice "El operador + = no se puede sobrecargar directamente, pero los tipos definidos por el usuario pueden sobrecargar el operador + (ver operador)". entonces deberíamos pensar que el operador del Vector3
s +=
actúa como lo describe microsoft donde dice:
x += y
es equivalente a
x = x + y
excepto que x solo se evalúa una vez. El significado del operador + depende de los tipos de x e y (suma para operandos numéricos, concatenación para operandos de cadena, etc.).
así que podemos estar seguros de que el segundo enfoque invoca el operando + de la Vector3
clase, que tiene la firma:
public static Vector3 operator +(Vector3 a, Vector3 b);
así que no hay otra forma de lograr esto que no sea convertir la pos2d en un Vector3 gracias a un elenco oculto implícito que no puede ser de ninguna otra forma.
Espero ayudar!
Editar
En Unity 5.0.1f1 Personal
con MonoDevelop-Unit 4.0.1
, como dice Alex M., las líneas:
transform.position = pos3d;
transform.position += pos2d;
todavía emite el error "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)'"
entonces realmente el + = está usando ambas firmas
public static Vector3 operator +(Vector3 a, Vector3 b);
public static Vector2 operator +(Vector2 a, Vector2 b);
independientemente del hecho de saber "dónde" se colocará el resultado (supongo que la salida de un Vector2 se puede convertir al destino (Vector3) y si ese lanzamiento no es posible, tal vez, el compilador elegiría el que tenga el adecuado Tipo de salida).
Gracias por el punto Alex M.