Hãy để tôi đổi tên các vars (cho rõ ràng):
Vector3 pos3d = new Vector3 (1f, 2f, 3f);
Vector2 pos2d = new Vector2 (1f, 2f);
Câu trả lời
Đó là vì phần pos3d + pos2d
của dòng. Phần này thực sự mơ hồ trong khi phần +=
này thì không. Hãy để tôi làm rõ tại sao một và tại sao khác.
Phân tích 1
Trong dòng này
transform.position = pos3d + pos2d;
đầu tiên trình biên dịch sẽ cố gắng đánh giá biểu thức pos3d + pos2d
trước khi tiếp tục, bất kể kết quả sẽ được đặt ở đâu.
Để làm như vậy, trước tiên hệ thống sẽ cố gắng tìm bất kỳ hàm tĩnh công khai nào có thêm Vector3 cộng với Vector2, ví dụ chữ ký có thể này:
public static Vector3 operator +(Vector3 a, Vector2 b);
hoặc ví dụ chữ ký có thể này:
public static Vector2 operator +(Vector3 a, Vector2 b);
Tuy nhiên, không có bất kỳ chữ ký nào trong API để trình biên dịch cố gắng "truyền" các tham số thành các chữ ký đã biết.
Sau đó, trình biên dịch tìm thấy hai chữ ký tiềm năng đó:
public static Vector3 operator +(Vector3 a, Vector3 b);
public static Vector2 operator +(Vector2 a, Vector2 b);
Những tài liệu này được ghi lại ở đây:
http://docs.unity3d.com/ScriptReference/Vector3-operator_add.html
và tại đây:
http://docs.unity3d.com/ScriptReference/Vector2-operator_add.html
Vì vậy, có hai khả năng:
Vì vậy, vì cả hai vật đúc đều có thể, pos2d có thể được đúc thành Vector3 và pos3d được castabale thành Vector2, trình biên dịch sau đó tìm ra các cách có thể để biên dịch cùng mã nguồn (được cung cấp các phôi ẩn tự động).
Có thể truyền pos3d vào Vector2 và tiếp tục với chữ ký thứ hai hoặc chuyển pos2d vào Vector3 và tiếp tục với chữ ký đầu tiên.
Vì biểu thức pos3d + pos2d
được đánh giá đầu tiên, trước khi xem xét "nơi kết quả sẽ được áp dụng", trình biên dịch không biết bạn sẽ sử dụng bộ mã hóa nào - như trình mã hóa để thực hiện.
Nếu bạn muốn chuyển sang 3D, bạn có thể viết điều này:
transform.position = pos3d + ( Vector3 )pos2d;
và vấn đề không còn nữa, vì bây giờ thì rõ ràng: đầu tiên di chuyển pos2d sang một đối tượng khác thuộc loại Vector3, sau đó thực hiện tổng của Vector3 + Vector3. Với điều kiện là có chữ ký tĩnh này
public static Vector3 operator +(Vector3 a, Vector3 b);
có sẵn, cái đó sẽ được sử dụng mà không có sự mơ hồ nào cả.
Phân tích 2
Mặt khác, khi bạn làm
transform.position = pos3d;
transform.position += pos2d;
không có sự mơ hồ: Dòng đầu tiên gán Vector3 thành Vector3 (không có nghi ngờ).
Dòng thứ hai tương đương với
transform.position = transform.position + pos2d;
với tính đặc biệt, Transform.poseition chỉ được đánh giá một lần và do đó loại được xem xét, như bạn có thể thấy trong trang Microsoft này về +=
toán tử:
https://msdn.microsoft.com/en-us/l Library / sa7629ew.aspx
Ngoài ra, nó nói "Toán tử + = không thể bị quá tải trực tiếp, nhưng các kiểu do người dùng định nghĩa có thể quá tải toán tử + (xem toán tử)." vì vậy chúng ta nên nghĩ toán tử Vector3
của +=
toán tử hoạt động như được mô tả bởi microsoft nơi nó nói:
x += y
tương đương với
x = x + y
ngoại trừ x chỉ được đánh giá một lần. Ý nghĩa của toán tử + phụ thuộc vào loại x và y (bổ sung cho toán hạng số, nối cho toán hạng chuỗi, v.v.).
vì vậy chúng ta có thể chắc chắn cách tiếp cận thứ hai gọi + toán hạng của Vector3
lớp, có chữ ký:
public static Vector3 operator +(Vector3 a, Vector3 b);
Vì vậy, không có cách nào khác để đạt được điều này ngoài việc chuyển pos2d thành Vector3 nhờ vào một diễn viên ẩn ẩn không thể ở bất kỳ dạng nào khác.
Mong được giúp đỡ !!
Biên tập
Trong Unity 5.0.1f1 Personal
với MonoDevelop-Unit 4.0.1
, như Alex M. cho biết, các đường:
transform.position = pos3d;
transform.position += pos2d;
vẫn báo lỗi "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)'"
Vì vậy, thực sự + = đang sử dụng cả hai chữ ký
public static Vector3 operator +(Vector3 a, Vector3 b);
public static Vector2 operator +(Vector2 a, Vector2 b);
bất kể thực tế là đã biết "kết quả" sẽ được đặt ở đâu (tôi đoán bởi vì việc xuất ra Vector2 có thể được chuyển đến đích (Vector3) và nếu có thể, thì trình biên dịch sẽ chọn một kết quả phù hợp Loại đầu ra).
Cảm ơn vì điểm Alex M.