Vorrei rinominare i var (per chiarezza):
Vector3 pos3d = new Vector3 (1f, 2f, 3f);
Vector2 pos2d = new Vector2 (1f, 2f);
Risposta
È a causa della sezione pos3d + pos2d
della linea. Questa parte è davvero ambigua mentre non lo +=
è. Vorrei chiarire perché l'uno e perché l'altro.
Analisi 1
In questa linea
transform.position = pos3d + pos2d;
il compilatore tenta innanzitutto di valutare l'espressione pos3d + pos2d
prima di procedere, indipendentemente da dove verrà posizionato il risultato.
Per fare ciò, il sistema tenta innanzitutto di trovare qualsiasi funzione statica pubblica che aggiunge un Vector3 più un Vector2, ad esempio questa possibile firma:
public static Vector3 operator +(Vector3 a, Vector2 b);
o per esempio questa possibile firma:
public static Vector2 operator +(Vector3 a, Vector2 b);
Tuttavia non c'è nessuna di quelle firme nell'API, quindi il compilatore prova a "trasmettere" i parametri a firme conosciute.
Quindi il compilatore trova queste due potenziali firme:
public static Vector3 operator +(Vector3 a, Vector3 b);
public static Vector2 operator +(Vector2 a, Vector2 b);
Questi sono documentati qui:
http://docs.unity3d.com/ScriptReference/Vector3-operator_add.html
e qui:
http://docs.unity3d.com/ScriptReference/Vector2-operator_add.html
Quindi ci sono due possibilità:
Quindi, poiché sono possibili entrambi i casting, pos2d può essere lanciato su un Vector3 e pos3d è castabale in un Vector2, il compilatore trova quindi i modi possibili per compilare lo stesso codice sorgente (a condizione che siano presenti casting nascosti automatici).
È possibile sia lanciare pos3d in Vector2 e procedere con la seconda firma, sia lanciare pos2d in Vector3 e procedere con la prima firma.
Dato che l'espressione pos3d + pos2d
viene valutata per prima, prima di prendere in considerazione "dove verrà applicato il risultato", il compilatore non sa quale cast vorresti -come programmatore-vorrebbe che eseguisse.
Se vuoi passare al 3D, puoi scrivere questo:
transform.position = pos3d + ( Vector3 )pos2d;
e il problema è scomparso, come ora è chiaro: prima sposta pos2d in un altro oggetto di tipo Vector3, quindi fai la somma di Vector3 + Vector3. A condizione che sia presente questa firma statica
public static Vector3 operator +(Vector3 a, Vector3 b);
disponibile, quello verrà usato senza alcuna ambiguità.
Analisi 2
D'altra parte, quando lo fai
transform.position = pos3d;
transform.position += pos2d;
non c'è ambiguità: la prima riga assegna un Vector3 in un Vector3 (senza dubbio).
La seconda riga è equivalente a
transform.position = transform.position + pos2d;
con la particolarità, il file transform.position viene valutato una sola volta, quindi il tipo viene preso in considerazione, come puoi vedere in questa pagina Microsoft +=
sull'operatore:
https://msdn.microsoft.com/en-us/library/sa7629ew.aspx
Inoltre dice "L'operatore + = non può essere sovraccaricato direttamente, ma i tipi definiti dall'utente possono sovraccaricare l'operatore + (vedi operatore)." quindi dovremmo pensare che il Vector3
's +=
operatore agisce come descritto da Microsoft in cui si dice:
x += y
è equivalente a
x = x + y
tranne che x viene valutato solo una volta. Il significato dell'operatore + dipende dai tipi di xey (aggiunta per operandi numerici, concatenazione per operandi stringa e così via).
quindi possiamo essere certi che il secondo approccio invoca l'operando + della Vector3
classe, che ha la firma:
public static Vector3 operator +(Vector3 a, Vector3 b);
quindi non c'è altro modo per raggiungere questo obiettivo se non quello di convertire pos2d in un Vector3 grazie a un cast implicito nascosto che non può essere di qualsiasi altra forma.
Spero di aiutare !!
modificare
In Unity 5.0.1f1 Personal
con MonoDevelop-Unit 4.0.1
, come dice Alex M., le linee:
transform.position = pos3d;
transform.position += pos2d;
ancora lanciare l'errore "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)'"
quindi davvero + = utilizza entrambe le firme
public static Vector3 operator +(Vector3 a, Vector3 b);
public static Vector2 operator +(Vector2 a, Vector2 b);
indipendentemente dal fatto di sapere già "dove" deve essere posizionato il risultato (immagino perché l'output di un Vector2 è castable alla destinazione (Vector3) e se quel cast non fosse possibile probabilmente, forse, il compilatore sceglierebbe quello con il giusto tipo di uscita).
Grazie per il punto Alex M.