Dados los siguientes dos vectores:
Vector3 v3 = Vector3.one;
Vector2 v2 = Vector2.one;
Esta línea es ambigua:
v3 += v2; // Unity reports dimension ambiguity
mientras que esta tarea no es:
v3 = v2; // Unity assigns despite different dimensions
¿Por qué es esto?
Respuestas:
Mensaje de problema completo:
La unidad proporcionó una forma de convertir implícitamente
Vector3
a aVector2
y viceversa. Esto provoca una ambigüedad en su caso porque se pueden aplicar ambos operadores +.Transmita su
Vector2
aVector3
explícitamente en esa operación, para que el compilador sepa usarUnityEngine.Vector3.operator +(UnityEngine.Vector3, UnityEngine.Vector3)
.Si tiene curiosidad, los documentos de Microsoft para ese error específico están aquí .
Editar después de su edición:
Vec3 += Vec2
es ambiguo por la misma razón descrita anteriormente. ImaginaVec3 += Vec2
estar de hechoVec3 = Vec3 + Vec2
.Vec3 + Vec2
puede producir tantoVector2
yVector3
como respuesta debido a las conversiones implícitas, es por eso que debe especificar lo que desea.Vec3 = Vec2
no es ambiguo porque Vec2 se convierte implícitamente en ayVector3
luego se asigna al Vec3 inicial. Por lo tanto, toda la operación es realmenteVector3 = Vector3
sin tener que lanzar Vec2Vector3
manualmente.fuente
Permítanme cambiar el nombre de los vars (para mayor claridad):
Responder
Es por la sección
pos3d + pos2d
de la línea. Esta parte es realmente ambigua mientras que la+=
no lo es. Permítanme aclarar por qué uno y por qué el otro.Análisis 1
En esta linea
el compilador primero intenta evaluar la expresión
pos3d + pos2d
antes de continuar, independientemente de dónde se colocará el resultado.Para hacerlo, el sistema primero intenta encontrar cualquier función estática pública que agregue un Vector3 más un Vector2, por ejemplo, esta posible firma:
o por ejemplo esta posible firma:
Sin embargo, no hay ninguna de esas firmas en la API, por lo que el compilador intenta "transmitir" parámetros a firmas conocidas.
Luego, el compilador encuentra esas dos firmas potenciales:
Estos están documentados aquí: http://docs.unity3d.com/ScriptReference/Vector3-operator_add.html y aquí: http://docs.unity3d.com/ScriptReference/Vector2-operator_add.html
Entonces hay dos posibilidades:
Por lo tanto, dado que ambas versiones son posibles, pos2d se puede convertir en un Vector3 y pos3d se puede convertir en un Vector2, el compilador busca posibles formas de compilar el mismo código fuente (siempre y cuando se instalen automáticamente las versiones ocultas).
Es posible convertir pos3d en Vector2 y continuar con la segunda firma, o bien transmitir pos2d en Vector3 y continuar con la primera firma.
Como la expresión
pos3d + pos2d
se evalúa primero, antes de tomar en cuenta "dónde se aplicará el resultado", entonces el compilador no sabe qué conversión le gustaría, como codificador, realizar.Si quieres moverte hacia 3D, puedes escribir esto:
y el problema desapareció, como ahora está claro: primero mueva pos2d a otro objeto de tipo Vector3, luego haga la suma de Vector3 + Vector3. Siempre que exista esta firma estática
disponible, ese será usado sin ambigüedad alguna.
Análisis 2
Por otro lado, cuando lo haces
no hay ambigüedad: la primera línea asigna un Vector3 a un Vector3 (sin dudas).
La segunda línea es equivalente a
Con la particularidad, transform.position solo se evalúa una vez y, por lo tanto, el tipo se tiene en cuenta, como puede ver en esta página de Microsoft sobre el
+=
operador:https://msdn.microsoft.com/en-us/library/sa7629ew.aspx
Además, dice "El operador + = no se puede sobrecargar directamente, pero los tipos definidos por el usuario pueden sobrecargar el operador + (ver operador)". entonces deberíamos pensar que el operador del
Vector3
s+=
actúa como lo describe microsoft donde dice:así que podemos estar seguros de que el segundo enfoque invoca el operando + de la
Vector3
clase, que tiene la firma:así que no hay otra forma de lograr esto que no sea convertir la pos2d en un Vector3 gracias a un elenco oculto implícito que no puede ser de ninguna otra forma.
Espero ayudar!
Editar
En
Unity 5.0.1f1 Personal
conMonoDevelop-Unit 4.0.1
, como dice Alex M., las líneas:todavía emite el error
"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)'"
entonces realmente el + = está usando ambas firmas
independientemente del hecho de saber "dónde" se colocará el resultado (supongo que la salida de un Vector2 se puede convertir al destino (Vector3) y si ese lanzamiento no es posible, tal vez, el compilador elegiría el que tenga el adecuado Tipo de salida).
Gracias por el punto Alex M.
fuente
+=
tampoco funciona, sigue siendo unVector3
+Vector2
. Mira mi respuesta.pos3d += pos2d
(según su pregunta editada) falla pero setransform.position += pos2d
compila (según su comentario anterior) ?? Parece extraño como.position
esVector3
: no puedo ver claramente si eso es lo que quieres decir.