Permettez-moi de renommer les vars (pour plus de clarté):
Vector3 pos3d = new Vector3 (1f, 2f, 3f);
Vector2 pos2d = new Vector2 (1f, 2f);
Réponse
C'est à cause de la section pos3d + pos2d
de la ligne. Cette partie est vraiment ambiguë alors que ce +=
n'est pas le cas. Permettez-moi de clarifier pourquoi l'un et pourquoi l'autre.
Analyse 1
Dans cette ligne
transform.position = pos3d + pos2d;
le compilateur essaie d'abord d'évaluer l'expression pos3d + pos2d
avant de continuer, quel que soit l'endroit où le résultat va être placé.
Pour ce faire, le système essaie d'abord de trouver toute fonction statique publique qui ajoute un Vector3 plus un Vector2, par exemple cette signature possible:
public static Vector3 operator +(Vector3 a, Vector2 b);
ou par exemple cette signature possible:
public static Vector2 operator +(Vector3 a, Vector2 b);
Néanmoins, il n'y a aucune de ces signatures dans l'API, donc le compilateur essaie de «transtyper» les paramètres en signatures connues.
Ensuite, le compilateur trouve ces deux signatures potentielles:
public static Vector3 operator +(Vector3 a, Vector3 b);
public static Vector2 operator +(Vector2 a, Vector2 b);
Ceux-ci sont documentés ici:
http://docs.unity3d.com/ScriptReference/Vector3-operator_add.html
et ici:
http://docs.unity3d.com/ScriptReference/Vector2-operator_add.html
Il y a donc deux possibilités:
Donc, comme les deux castings sont possibles, pos2d peut être casté en un Vector3 et pos3d est castabale en un Vector2, le compilateur trouve ensuite des façons possibles de compiler le même code source (à condition que des castings cachés automatiques soient en place).
Il est possible de transposer pos3d dans Vector2 et de procéder à la deuxième signature, ou de transposer pos2d dans Vector3 et de procéder à la première signature.
Comme l'expression pos3d + pos2d
est évaluée en premier, avant de prendre en considération "où le résultat sera appliqué", alors le compilateur ne sait pas quel casting souhaitez-vous, en tant que codeur, qu'il souhaite effectuer.
Si vous voulez vous diriger vers la 3D, vous pouvez écrire ceci:
transform.position = pos3d + ( Vector3 )pos2d;
et le problème a disparu, comme maintenant il est clair: déplacez d'abord pos2d dans un autre objet de type Vector3, puis faites la somme de Vector3 + Vector3. Pourvu qu'il y ait cette signature statique
public static Vector3 operator +(Vector3 a, Vector3 b);
disponible, celui-ci sera utilisé sans aucune ambiguïté.
Analyse 2
D'un autre côté, quand vous faites
transform.position = pos3d;
transform.position += pos2d;
il n'y a pas d'ambiguïté: la première ligne assigne un Vector3 à un Vector3 (pas de doute).
La deuxième ligne équivaut à
transform.position = transform.position + pos2d;
avec la particularité que transform.position n'est évalué qu'une seule fois, et donc le type est pris en considération, comme vous pouvez le voir dans cette page Microsoft sur l' +=
opérateur:
https://msdn.microsoft.com/en-us/library/sa7629ew.aspx
Il indique en outre "L'opérateur + = ne peut pas être surchargé directement, mais les types définis par l'utilisateur peuvent surcharger l'opérateur + (voir opérateur)." nous devons donc penser que le Vector3
l » +=
opérateur agit comme décrit par Microsoft où il est dit:
x += y
est équivalent à
x = x + y
sauf que x n'est évalué qu'une seule fois. La signification de l'opérateur + dépend des types de x et y (ajout pour les opérandes numériques, concaténation pour les opérandes de chaîne, etc.).
nous pouvons donc être sûrs que la deuxième approche invoque l'opérande + de la Vector3
classe, qui a la signature:
public static Vector3 operator +(Vector3 a, Vector3 b);
il n'y a donc pas d'autre moyen d'y parvenir que de convertir le pos2d en un Vector3 grâce à une distribution cachée implicite qui ne peut pas être d'une autre forme.
Au plaisir d'aider !!
Éditer
En Unity 5.0.1f1 Personal
avec MonoDevelop-Unit 4.0.1
, comme Alex M. dit, les lignes:
transform.position = pos3d;
transform.position += pos2d;
jette toujours l'erreur "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)'"
donc vraiment le + = utilise les deux signatures
public static Vector3 operator +(Vector3 a, Vector3 b);
public static Vector2 operator +(Vector2 a, Vector2 b);
indépendamment du fait de savoir déjà "où" le résultat doit être placé (je suppose que la sortie d'un Vector2 peut être casté vers la destination (Vector3) et si ce cast n'était pas possible probablement, peut-être, le compilateur choisirait celui avec le bon le type de sortie).
Merci pour le point Alex M.