Lassen Sie mich die Vars umbenennen (der Klarheit halber):
Vector3 pos3d = new Vector3 (1f, 2f, 3f);
Vector2 pos2d = new Vector2 (1f, 2f);
Antworten
Es liegt am Abschnitt pos3d + pos2d
der Linie. Dieser Teil ist wirklich mehrdeutig, während das +=
nicht ist. Lassen Sie mich erklären, warum einer und warum der andere.
Analyse 1
In dieser Zeile
transform.position = pos3d + pos2d;
Der Compiler versucht zunächst, den Ausdruck auszuwerten, pos3d + pos2d
bevor er fortfährt, unabhängig davon, wo das Ergebnis platziert werden soll.
Zu diesem Zweck versucht das System zunächst, eine öffentliche statische Funktion zu finden, die einen Vector3 plus einen Vector2 hinzufügt, beispielsweise diese mögliche Signatur:
public static Vector3 operator +(Vector3 a, Vector2 b);
oder zum Beispiel diese mögliche Signatur:
public static Vector2 operator +(Vector3 a, Vector2 b);
Da die API jedoch keine dieser Signaturen enthält, versucht der Compiler, Parameter in bekannte Signaturen umzuwandeln.
Dann findet der Compiler diese beiden möglichen Signaturen:
public static Vector3 operator +(Vector3 a, Vector3 b);
public static Vector2 operator +(Vector2 a, Vector2 b);
Diese sind hier dokumentiert:
http://docs.unity3d.com/ScriptReference/Vector3-operator_add.html
und hier:
http://docs.unity3d.com/ScriptReference/Vector2-operator_add.html
Es gibt also zwei Möglichkeiten:
Da beide Castings möglich sind, kann pos2d in einen Vector3 umgewandelt werden und pos3d wird in einen Vector2 umgewandelt. Der Compiler sucht dann nach Möglichkeiten, denselben Quellcode zu kompilieren (vorausgesetzt, automatische versteckte Castings sind vorhanden).
Es ist entweder möglich, pos3d in Vector2 umzuwandeln und mit der zweiten Signatur fortzufahren, oder pos2d in Vector3 umzuwandeln und mit der ersten Signatur fortzufahren.
Da der Ausdruck pos3d + pos2d
zuerst ausgewertet wird, bevor er berücksichtigt, "wo das Ergebnis angewendet wird", weiß der Compiler nicht, welche Umwandlung Sie als Codierer ausführen möchten.
Wenn Sie sich in Richtung 3D bewegen möchten, können Sie Folgendes schreiben:
transform.position = pos3d + ( Vector3 )pos2d;
und das Problem ist weg, wie jetzt klar ist: Verschieben Sie zuerst pos2d in ein anderes Objekt vom Typ Vector3 und dann die Summe von Vector3 + Vector3. Vorausgesetzt, es gibt diese statische Signatur
public static Vector3 operator +(Vector3 a, Vector3 b);
verfügbar, dass eine ohne Mehrdeutigkeit verwendet wird.
Analyse 2
Auf der anderen Seite, wenn Sie es tun
transform.position = pos3d;
transform.position += pos2d;
Es gibt keine Mehrdeutigkeit: In der ersten Zeile wird ein Vektor3 einem Vektor3 zugewiesen (keine Zweifel).
Die zweite Zeile entspricht
transform.position = transform.position + pos2d;
Mit der Besonderheit wird die transform.position nur einmal ausgewertet, und daher wird der Typ berücksichtigt, wie Sie auf dieser Microsoft-Seite über den +=
Operator sehen können:
https://msdn.microsoft.com/en-us/library/sa7629ew.aspx
Außerdem heißt es: "Der Operator + = kann nicht direkt überladen werden, aber benutzerdefinierte Typen können den Operator + überladen (siehe Operator)." so sollten wir denken , das Vector3
ist +=
Betreiber wie von Microsoft beschrieben wirkt , wo es heißt:
x += y
ist äquivalent zu
x = x + y
außer dass x nur einmal ausgewertet wird. Die Bedeutung des Operators + hängt von den Typen von x und y ab (Addition für numerische Operanden, Verkettung für Zeichenfolgenoperanden usw.).
Wir können also sicher sein, dass der zweite Ansatz den Operanden + der Vector3
Klasse aufruft , der die Signatur hat:
public static Vector3 operator +(Vector3 a, Vector3 b);
Es gibt also keinen anderen Weg, dies zu erreichen, als die pos2d dank einer impliziten versteckten Besetzung, die keine andere Form haben kann, in einen Vector3 umzuwandeln.
Hoffe zu helfen !!
Bearbeiten
In Unity 5.0.1f1 Personal
mit MonoDevelop-Unit 4.0.1
, wie Alex M. sagt, die Linien:
transform.position = pos3d;
transform.position += pos2d;
Wirf immer noch den Fehler "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)'"
Das + = verwendet also wirklich beide Signaturen
public static Vector3 operator +(Vector3 a, Vector3 b);
public static Vector2 operator +(Vector2 a, Vector2 b);
Unabhängig von der Tatsache, dass bereits bekannt ist, "wo" das Ergebnis platziert werden soll (ich denke, weil die Ausgabe eines Vector2 an das Ziel (Vector3) umgewandelt werden kann und wenn diese Umwandlung wahrscheinlich nicht möglich wäre, würde der Compiler wahrscheinlich den mit dem richtigen auswählen Ausgabetyp).
Danke für den Punkt Alex M.