Biarkan saya mengganti nama vars (untuk kejelasan):
Vector3 pos3d = new Vector3 (1f, 2f, 3f);
Vector2 pos2d = new Vector2 (1f, 2f);
Menjawab
Itu karena bagian pos3d + pos2d
dari garis. Bagian ini sangat ambigu sedangkan yang +=
tidak. Biarkan saya menjelaskan mengapa yang satu dan mengapa yang lain.
Analisis 1
Di baris ini
transform.position = pos3d + pos2d;
kompiler pertama kali mencoba untuk mengevaluasi ekspresi pos3d + pos2d
sebelum melanjutkan, terlepas dari di mana hasilnya akan ditempatkan.
Untuk melakukannya, sistem pertama-tama mencoba menemukan fungsi statis publik yang menambahkan Vector3 plus Vector2, misalnya tanda tangan yang mungkin ini:
public static Vector3 operator +(Vector3 a, Vector2 b);
atau misalnya tanda tangan ini:
public static Vector2 operator +(Vector3 a, Vector2 b);
Namun demikian, tidak ada tanda tangan di API sehingga kompiler mencoba untuk "membuang" parameter ke tanda tangan yang dikenal.
Kemudian kompiler menemukan dua tanda tangan potensial:
public static Vector3 operator +(Vector3 a, Vector3 b);
public static Vector2 operator +(Vector2 a, Vector2 b);
Ini didokumentasikan di sini:
http://docs.unity3d.com/ScriptReference/Vector3-operator_add.html
dan di sini:
http://docs.unity3d.com/ScriptReference/Vector2-operator_add.html
Jadi ada dua kemungkinan:
Jadi karena kedua coran dimungkinkan, pos2d dapat dilemparkan ke Vector3 dan pos3d dilemparkan ke dalam Vector2, kompiler kemudian menemukan cara yang memungkinkan untuk mengkompilasi kode sumber yang sama (asalkan coran tersembunyi otomatis tersedia).
Entah mungkin untuk memasukkan pos3d ke Vector2 dan melanjutkan dengan tanda tangan kedua, atau melemparkan pos2d ke Vector3 dan melanjutkan dengan tanda tangan pertama.
Ketika ekspresi pos3d + pos2d
dievaluasi terlebih dahulu, sebelum mempertimbangkan "di mana hasilnya akan diterapkan" maka kompiler tidak tahu apa yang akan dilemparkan oleh Anda - sebagai pembuat kode - seperti yang ingin dilakukan.
Jika Anda ingin beralih ke 3D, Anda dapat menulis ini:
transform.position = pos3d + ( Vector3 )pos2d;
dan masalahnya hilang, seperti sekarang jelas: pertama pindahkan pos2d ke objek lain dari tipe Vector3, kemudian lakukan penjumlahan dari Vector3 + Vector3. Asalkan ada tanda tangan statis ini
public static Vector3 operator +(Vector3 a, Vector3 b);
tersedia, yang akan digunakan tanpa ambiguitas sama sekali.
Analisis 2
Di sisi lain, ketika Anda melakukannya
transform.position = pos3d;
transform.position += pos2d;
tidak ada ambiguitas: Baris pertama menetapkan Vector3 menjadi Vector3 (tidak ada keraguan).
Baris kedua setara dengan
transform.position = transform.position + pos2d;
dengan kekhasan transform.posisi hanya dievaluasi sekali, dan oleh karena itu jenisnya dipertimbangkan, seperti yang Anda lihat di halaman Microsoft ini tentang +=
operator:
https://msdn.microsoft.com/en-us/library/sa7629ew.aspx
Selain itu tertulis "Operator + = tidak dapat kelebihan beban secara langsung, tetapi tipe yang ditentukan pengguna dapat membebani operator + (lihat operator)." jadi kita harus berpikir Vector3
's +=
Operator bertindak seperti yang dijelaskan oleh microsoft yang mengatakan:
x += y
setara dengan
x = x + y
kecuali bahwa x hanya dievaluasi satu kali. Arti dari operator + tergantung pada jenis x dan y (penambahan untuk operan numerik, penggabungan untuk operan string, dan sebagainya).
jadi kita bisa yakin bahwa pendekatan kedua memanggil + operan Vector3
kelas, yang memiliki tanda tangan:
public static Vector3 operator +(Vector3 a, Vector3 b);
jadi tidak ada cara lain untuk mencapai ini selain mengubah pos2d menjadi Vector3 berkat gips tersembunyi tersirat yang tidak bisa dari bentuk lain.
Berharap untuk membantu !!
Edit
Dalam Unity 5.0.1f1 Personal
dengan MonoDevelop-Unit 4.0.1
, seperti kata Alex M., baris:
transform.position = pos3d;
transform.position += pos2d;
masih melakukan kesalahan "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)'"
jadi sebenarnya + = menggunakan kedua tanda tangan
public static Vector3 operator +(Vector3 a, Vector3 b);
public static Vector2 operator +(Vector2 a, Vector2 b);
terlepas dari fakta sudah tahu "di mana" hasilnya akan ditempatkan (saya kira karena mengeluarkan Vector2 dapat dicast ke tujuan (Vector3) dan jika pemeran itu tidak mungkin mungkin, mungkin, kompiler akan memilih yang dengan tepat tipe keluaran).
Terima kasih untuk poinnya Alex M.