Gegeben sind die folgenden zwei Vektoren:
Vector3 v3 = Vector3.one;
Vector2 v2 = Vector2.one;
Diese Zeile ist nicht eindeutig:
v3 += v2; // Unity reports dimension ambiguity
während diese Aufgabe nicht ist:
v3 = v2; // Unity assigns despite different dimensions
Warum ist das?
Antworten:
Vollständige Problemmeldung:
Einheit vorgesehen , um eine Art und Weise , um implizit eine umwandeln
Vector3
zu aVector2
und umgekehrt. Dies führt in Ihrem Fall zu einer Mehrdeutigkeit, da beide + Operatoren angewendet werden können.Werfen Sie Ihre
Vector2
zu einemVector3
explizit in dieser Operation, so dass der Compiler zu verwenden weißUnityEngine.Vector3.operator +(UnityEngine.Vector3, UnityEngine.Vector3)
.Wenn Sie neugierig sind, Microsofts docs für diesen speziellen Fehler sind hier .
Nach der Bearbeitung bearbeiten:
Vec3 += Vec2
ist aus dem oben beschriebenen Grund nicht eindeutig. Stellen Sie sichVec3 += Vec2
vor, Sie wären tatsächlichVec3 = Vec3 + Vec2
.Vec3 + Vec2
kann beides ergebenVector2
undVector3
als Antwort aufgrund impliziter Konvertierungen müssen Sie angeben, was Sie wollen.Vec3 = Vec2
ist nicht mehrdeutig, da Vec2 implizit in a konvertiertVector3
und dann dem anfänglichen Vec3 zugewiesen wird. Der gesamte Vorgang ist also wirklichVector3 = Vector3
ohne dass Sie Vec2Vector3
manuell in einen übertragen müssen.quelle
Lassen Sie mich die Vars umbenennen (der Klarheit halber):
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
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:
oder zum Beispiel diese mögliche Signatur:
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:
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:
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
verfügbar, dass eine ohne Mehrdeutigkeit verwendet wird.
Analyse 2
Auf der anderen Seite, wenn Sie es tun
Es gibt keine Mehrdeutigkeit: In der ersten Zeile wird ein Vektor3 einem Vektor3 zugewiesen (keine Zweifel).
Die zweite Zeile entspricht
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:Wir können also sicher sein, dass der zweite Ansatz den Operanden + der
Vector3
Klasse aufruft , der die Signatur hat: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
mitMonoDevelop-Unit 4.0.1
, wie Alex M. sagt, die Linien: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
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.
quelle
+=
funktioniert auch nicht, es ist immer noch einVector3
+Vector2
. Siehe meine Antwort.pos3d += pos2d
(gemäß Ihrer bearbeiteten Frage) schlägt fehl, wird abertransform.position += pos2d
kompiliert (gemäß Ihrem Kommentar oben)? Würde seltsam erscheinen wie es.position
istVector3
- Ich kann nicht klar erkennen, ob Sie das meinen.