유니티에서 Vector2와 Vector3를 추가하는 것이 모호하지만 할당이 아닌 이유는 무엇입니까?


11

다음 두 벡터가 주어집니다.

Vector3 v3 = Vector3.one;
Vector2 v2 = Vector2.one;

이 줄은 모호합니다.

v3 += v2; // Unity reports dimension ambiguity

이 과제는 그렇지 않습니다 :

v3 = v2; // Unity assigns despite different dimensions

왜 이런거야?


Anko와 Xavi Montero에게 큰 답변을 주셔서 감사합니다. 문제를 재현하려고 노력하면서 내 질문이 바뀌어야한다는 것을 깨달았습니다. 사실은 transform.position에 Vector2를 할당 할 때 발생합니다. 따라서 transform.position = a + b; 여기서 a와 b는 모두 Vector2가 올바르게 컴파일되고 x와 y가 할당됩니다! 대신 줄을 transform.position + = a;로 변경하면 작동하지 않습니다. // 또는 b Unity 5.0.0f를 사용하고 있으며 스크립트는 컴파일러에는 영향을 미치지 않지만 시나리오를 재현하는 데 중요한 정보 일 수있는 UI 요소 (이미지)에 첨부되어 있습니다.
SteakOverflow

그래서 너희들은 무엇을해야하는지 말해줘. 질문과 답변을 적절히 바꾸어야합니까, 아니면 새로운 질문을 시작할까요?
SteakOverflow

Vector3 + Vector2 및 Vector3 + = Vector2는 모두 암시 적으로 다른 것으로 변환 할 수 있으며 원하는 작업에 따라 명시 적으로 캐스팅해야하기 때문에 원하는대로 작동하지 않습니다. Vector3 = Vector2는 모호성이 없기 때문에 작동합니다. 새 질문을 변경하거나 게시 할 필요가 없습니다.

사례가 내가 설명한 것과 약간 다르기 때문에 질문을 변경하려고합니다. 응답의 흐름을 방해 할 수 있습니다.
SteakOverflow

아냐 걱정 하지마

답변:


12

전체 문제 메시지 :

오류 CS0121 : 다음 메소드 또는 속성간에 호출이 모호합니다. UnityEngine.Vector2.operator +(UnityEngine.Vector2, UnityEngine.Vector2)' andUnityEngine.Vector3.operator + (UnityEngine.Vector3, UnityEngine.Vector3) '

유니티는 암시 적으로 변환 할 수있는 방법 제공 Vector3A와 Vector2반대의 경우도 마찬가지입니다. + 연산자를 모두 적용 할 수 있으므로이 경우 모호성이 발생합니다.

당신의 캐스트 Vector2A를 Vector3컴파일러가 사용하는 알고 그래서, 해당 작업에 명시 적으로 UnityEngine.Vector3.operator +(UnityEngine.Vector3, UnityEngine.Vector3).

궁금한 점이 있으면 해당 오류에 대한 Microsoft의 문서가 여기 있습니다 .


편집 후 편집 :

Vec3 += Vec2위에서 설명한 것과 같은 이유로 모호합니다. Vec3 += Vec2실제로 있다고 상상해보십시오 Vec3 = Vec3 + Vec2. Vec3 + Vec2모두를 얻을 수 Vector2Vector3당신이 당신이 원하는 것을 지정해야하는 이유 답변으로 인해 암시 적 변환에, 그입니다.

Vec3 = Vec2Vec2가 암시 적으로 a로 변환 Vector3된 다음 초기 Vec3에 할당 되므로 모호하지 않습니다 . 따라서 전체 작업은 실제로 Vector3 = Vector3Vec2를 Vector3수동으로 캐스팅 할 필요가 없습니다.


그래서 Unity는 Vector3의 x와 y를 Vector2의 x와 y에서 할당하고 z를 0f로 설정한다고 가정합니다. 권리?
SteakOverflow

예, Vec3 = Vec2는 Vec3 = (Vector3) Vec2와 같습니다. 이 경우 실제로 다른 것이 될 수 없으므로 수동으로 캐스팅 할 필요가 없습니다.

예, 실제로 제 질문의 제목은 "Vector2를 할당 할 때 Vector3로 캐스팅 할 필요가없는 이유"와 같은 제목 일 수 있습니다. 나는 완벽한 질문을 작성하고 작성하는 데 최고가 아닙니다 : / 감사합니다 Alex. 나의 호기심이 (과도하게) 만족되었습니다.
SteakOverflow

3

명확성을 위해 vars의 이름을 바꾸겠습니다.

Vector3 pos3d = new Vector3 (1f, 2f, 3f);
Vector2 pos2d = new Vector2 (1f, 2f);

대답

pos3d + pos2d선의 단면 때문입니다 . 이 부분은 +=그렇지 않은 동안 실제로 모호합니다 . 왜 하나와 다른 하나를 설명하겠습니다.

분석 1

이 라인에서

transform.position = pos3d + pos2d;

컴파일러 pos3d + pos2d는 먼저 결과를 배치 할 위치에 관계없이 진행하기 전에 표현식을 평가하려고합니다 .

이를 위해 시스템은 먼저 Vector3와 Vector2를 추가하는 공개 정적 함수 (예 :이 가능한 서명)를 찾으려고합니다.

public static Vector3 operator +(Vector3 a, Vector2 b);

또는 예를 들어이 가능한 서명 :

public static Vector2 operator +(Vector3 a, Vector2 b);

그럼에도 불구하고 API에는 이러한 서명이 없으므로 컴파일러는 매개 변수를 알려진 서명으로 "캐스트"하려고합니다.

그런 다음 컴파일러는이 두 가지 잠재적 인 서명을 찾습니다.

public static Vector3 operator +(Vector3 a, Vector3 b);
public static Vector2 operator +(Vector2 a, Vector2 b);

이 여기에 설명되어 있습니다 : http://docs.unity3d.com/ScriptReference/Vector3-operator_add.html 여기 : http://docs.unity3d.com/ScriptReference/Vector2-operator_add.html

따라서 두 가지 가능성이 있습니다.

따라서 두 캐스팅이 모두 가능하므로 pos2d를 Vector3으로 캐스팅하고 pos3d를 Vector2로 캐스팅하면 컴파일러는 동일한 소스 코드를 컴파일 할 수있는 방법을 찾습니다 (자동 숨김 캐스팅이 제공되는 경우).

pos3d를 Vector2에 캐스트하고 두 번째 서명을 진행하거나 pos2d를 Vector3에 캐스트하고 첫 번째 서명을 진행할 수 있습니다.

식이 pos3d + pos2d먼저 평가 될 때 "결과가 적용될 위치"를 고려하기 전에 컴파일러는 수행 할 코더와 같은 캐스트를 알지 못합니다.

3D로 이동하려면 다음과 같이 작성할 수 있습니다.

transform.position = pos3d + ( Vector3 )pos2d;

pos2d를 Vector3 유형의 다른 객체로 옮긴 다음 Vector3 + Vector3의 합을 수행하십시오. 이 정적 서명이 있다면

public static Vector3 operator +(Vector3 a, Vector3 b);

모호하지 않고 사용됩니다.

분석 2

반면에 할 때

transform.position = pos3d;
transform.position += pos2d; 

모호함이 없습니다. 첫 번째 줄은 Vector3을 Vector3에 할당합니다 (의심 할 것 없음).

두 번째 줄은

transform.position = transform.position + pos2d;

특히 변환기에 대한이 Microsoft 페이지에서 볼 수 있듯이 transform.position은 한 번만 평가되므로 유형을 고려합니다 +=.

https://msdn.microsoft.com/en-us/library/sa7629ew.aspx

또한 "+ = 연산자는 직접 오버로드 할 수 없지만 사용자 정의 형식은 + 연산자를 오버로드 할 수 있습니다 (연산자 참조)." 따라서 Vector3+=연산자는 다음과 같이 Microsoft에서 설명한대로 작동 한다고 생각해야합니다 .

x += y

에 해당

x = x + y

x는 한 번만 평가됩니다. + 연산자의 의미는 x 및 y의 유형 (숫자 피연산자에 대한 추가, 문자열 피연산자에 대한 연결 등)에 따라 다릅니다.

따라서 두 번째 접근 방식이 Vector3클래스 의 + 피연산자를 호출 하고 서명 이 있는지 확인할 수 있습니다 .

public static Vector3 operator +(Vector3 a, Vector3 b);

따라서 다른 형식이 될 수없는 암시 적 숨겨진 캐스트 덕분에 pos2d를 Vector3으로 변환하는 것 외에는이를 달성 할 수있는 다른 방법이 없습니다.

도와 드리겠습니다!


편집하다

Unity 5.0.1f1 PersonalMonoDevelop-Unit 4.0.1알렉스 M. 말한대로, 선 :

transform.position = pos3d;
transform.position += pos2d;

여전히 오류를 캐스트 "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)'"

실제로 + =는 두 서명을 모두 사용하고 있습니다.

public static Vector3 operator +(Vector3 a, Vector3 b);
public static Vector2 operator +(Vector2 a, Vector2 b);

이미 "where"를 알고 있다는 사실에 관계없이 결과를 배치해야합니다 (Vector2 출력이 대상 (Vector3)으로 캐스팅 가능하고 캐스팅이 불가능한 경우 컴파일러가 적절한 것을 선택합니다) 출력 유형).

알렉스 M.


+=작동하지 않지만 여전히 Vector3+ Vector2입니다. 내 대답을 참조하십시오.

맞아, 너의 생각을 높이고, 나의 것을 편집 할 것이다.
Xavi Montero

귀하의 의견을 반영하기 위해 방금 편집했습니다.
Xavi Montero

transform.position + = pos2d가 컴파일 중입니다. 나는 내일 더 정확할 것이다 (버전 버그 일 수도있다)
SteakOverflow

편집 후 순서대로 잃어 버렸습니다 ... 그래서 ... pos3d += pos2d(편집 된 질문에 따라) 실패하지만 transform.position += pos2d컴파일 (위의 의견에 따라) ?? 이상하게 보일 것 .position입니다 Vector3-그것이 당신이 의미하는 바인지 명확하게 볼 수 없습니다.
Xavi Montero
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.