Deixe-me renomear os vars (para maior clareza):
Vector3 pos3d = new Vector3 (1f, 2f, 3f);
Vector2 pos2d = new Vector2 (1f, 2f);
Responda
É por causa da seção pos3d + pos2d
da linha. Esta parte é realmente ambígua enquanto a +=
não é. Deixe-me esclarecer por que um e por que o outro.
Análise 1
Nesta linha
transform.position = pos3d + pos2d;
o compilador primeiro tenta avaliar a expressão pos3d + pos2d
antes de continuar, independentemente de onde o resultado será colocado.
Para fazer isso, o sistema primeiro tenta encontrar qualquer função estática pública que adicione um Vector3 mais um Vector2, por exemplo, esta possível assinatura:
public static Vector3 operator +(Vector3 a, Vector2 b);
ou, por exemplo, esta possível assinatura:
public static Vector2 operator +(Vector3 a, Vector2 b);
No entanto, não há nenhuma dessas assinaturas na API; portanto, o compilador tenta "converter" parâmetros em assinaturas conhecidas.
Em seguida, o compilador encontra essas duas assinaturas em potencial:
public static Vector3 operator +(Vector3 a, Vector3 b);
public static Vector2 operator +(Vector2 a, Vector2 b);
Eles estão documentados aqui:
http://docs.unity3d.com/ScriptReference/Vector3-operator_add.html
e aqui:
http://docs.unity3d.com/ScriptReference/Vector2-operator_add.html
Portanto, existem duas possibilidades:
Portanto, como ambas as peças fundidas são possíveis, o pos2d pode ser fundido em um Vector3 e o pos3d é fundido em um Vector2, o compilador encontra maneiras possíveis de compilar o mesmo código fonte (desde que as fundições ocultas automáticas estejam no lugar).
É possível converter pos3d no vetor2 e prosseguir com a segunda assinatura, ou converter pos2d no vetor3 e prosseguir com a primeira assinatura.
Como a expressão pos3d + pos2d
é avaliada primeiro, antes de levar em consideração "onde o resultado será aplicado", o compilador não sabe qual conversão você - como codificador - gostaria de executar.
Se você deseja avançar para o 3D, pode escrever o seguinte:
transform.position = pos3d + ( Vector3 )pos2d;
e o problema desapareceu, como agora está claro: primeiro mova pos2d para outro objeto do tipo Vector3, depois faça a soma de Vector3 + Vector3. Desde que exista essa assinatura estática
public static Vector3 operator +(Vector3 a, Vector3 b);
disponível, esse será usado sem nenhuma ambiguidade.
Análise 2
Por outro lado, quando você faz
transform.position = pos3d;
transform.position += pos2d;
não há ambiguidade: a primeira linha atribui um Vector3 a um Vector3 (sem dúvida).
A segunda linha é equivalente a
transform.position = transform.position + pos2d;
com a particularidade, o transform.position é avaliado apenas uma vez e, portanto, o tipo é levado em consideração, como você pode ver nesta página da Microsoft sobre o +=
operador:
https://msdn.microsoft.com/en-us/library/sa7629ew.aspx
Além disso, diz "O operador + = não pode ser sobrecarregado diretamente, mas os tipos definidos pelo usuário podem sobrecarregar o operador + (consulte operador)". por isso, devemos pensar que o Vector3
's +=
operador atua como descrito pela Microsoft, onde ele diz:
x += y
é equivalente a
x = x + y
exceto que x é avaliado apenas uma vez. O significado do operador + depende dos tipos de xey (adição para operandos numéricos, concatenação para operandos de cadeia de caracteres e assim por diante).
para ter certeza de que a segunda abordagem chama o operando + da Vector3
classe, que tem a assinatura:
public static Vector3 operator +(Vector3 a, Vector3 b);
portanto, não há outra maneira de conseguir isso além da conversão do pos2d em um Vector3, graças a uma conversão oculta implícita que não pode ter outra forma.
Espero ajudar !!
Editar
Em Unity 5.0.1f1 Personal
com MonoDevelop-Unit 4.0.1
, como Alex M. diz, as linhas:
transform.position = pos3d;
transform.position += pos2d;
ainda lança o erro "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)'"
então realmente o + = está usando as duas assinaturas
public static Vector3 operator +(Vector3 a, Vector3 b);
public static Vector2 operator +(Vector2 a, Vector2 b);
independentemente do fato de já saber "onde" o resultado deve ser colocado (acho que porque a saída de um Vector2 é passível de conversão para o destino (Vector3)) e se essa conversão não foi possível, provavelmente, talvez, o compilador escolheria aquele com a devida tipo de saída).
Obrigado pelo ponto Alex M.