Unity'de neden Vector2 ve Vector3 eklemek belirsizdir?


11

Aşağıdaki iki vektör göz önüne alındığında:

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

Bu çizgi belirsiz:

v3 += v2; // Unity reports dimension ambiguity

bu ödev değil:

v3 = v2; // Unity assigns despite different dimensions

Bu neden?


Harika yanıtlar için Anko ve Xavi Montero'ya çok teşekkür ederim. Sorunu yeniden oluşturmaya çalışırken sorumun değiştirilmesi gerektiğini fark ettim. Gerçek şu ki, transform.position'a bir Vector2 atanırken transform.position = a + b; burada İKİ ve B Vector2 doğru bir şekilde derlenir ve x ve Y'yi atar! Bunun yerine, satırı transform.position + = a olarak değiştirdiğimde çalışmaz. // veya b Unity 5.0.0f kullanıyorum ve komut dosyası, derleyiciyi etkilemeyen ancak senaryoyu yeniden oluşturmanız için önemli bilgiler olabilecek bir UI öğesine (Resim) eklenmiştir.
SteakOverflow

Bana ne yapacağımı söylüyorsun. Soruyu ve cevaplarınızı buna göre değiştirelim mi yoksa yeni bir soru başlatalım mı?
SteakOverflow

Vector3 + Vector2 ve Vector3 + = Vector2, ne olursa olsun asla çalışmayacaktır, çünkü her ikisi de dolaylı olarak diğerine dönüştürülebilir ve yapmak istediğiniz şeye göre açıkça yayınlamanız gerekir. Vector3 = Vector2 çalışıyor çünkü belirsizlik yok. Yeni bir soru değiştirme veya yayınlama gereğini görmüyorum.

Soruyu değiştirmek için söylüyorum çünkü dava açıkladığımdan biraz farklı, bu da cevabınızın akışını frenleyebilir.
SteakOverflow

Endişelenme, hiçbir şey kırılmaz.

Yanıtlar:


12

Tam sayı mesajı:

hata CS0121: Aşağıdaki yöntemler veya özellikler arasında çağrı belirsiz: UnityEngine.Vector2.operator +(UnityEngine.Vector2, UnityEngine.Vector2)' andUnityEngine.Vector3.operator + (UnityEngine.Vector3, UnityEngine.Vector3) '

Birlik, dolaylı Vector3olarak a Vector2ve tersini dönüştürmek için bir yol sağladı . Bu durum sizin durumunuzda bir belirsizliğe neden olur çünkü her iki + operatörü de uygulanabilir.

Kadronuzun Vector2a Vector3derleyici kullanmayı bilir Böylece, uygulama operasyonda açıkça UnityEngine.Vector3.operator +(UnityEngine.Vector3, UnityEngine.Vector3).

Merak ediyorsanız, bu hatanın Microsoft belgeleri burada .


Düzenlemenizden sonra düzenleyin:

Vec3 += Vec2yukarıda açıklanan aynı nedenden dolayı belirsizdir. Vec3 += Vec2Aslında olduğunu düşünün Vec3 = Vec3 + Vec2. Vec3 + Vec2Her iki sonuçlara yol açabileceğini Vector2ve Vector3istediğini belirtmek için neden cevap olarak sebebiyle örtülü dönüşümlere, bu.

Vec3 = Vec2belirsiz değildir çünkü Vec2 örtük olarak a'ya dönüştürülür Vector3ve sonra ilk Vec3'e atanır. Yani tüm işlem gerçekten Vector3 = Vector3Vec2'yi Vector3manuel olarak yapmak zorunda kalmadan .


Bu yüzden Unity, Vector3'lerin x ve y'lerinin Vector2'lerin x ve y'lerinden atanmasını ve z'm 0f olarak ayarlanmasını istediğimi varsayar. Sağ?
SteakOverflow

Evet, Vec3 = Vec2'nin Vec3 = (Vector3) Vec2'ye eşdeğer olduğunu hayal edin. Manuel olarak yayın yapmanıza gerek yoktur çünkü bu durumda bundan başka bir şey olamaz.

Evet, aslında sorum "Vector2 atarken neden Vector3'e yayınlamam gerekiyor?" Mükemmel soruları yazarken ve hazırlarken en iyisi değilim: / Teşekkürler Alex. Merakım tatmin oldu.
SteakOverflow

3

Varsları yeniden adlandırmama izin verin (açıklık için):

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

Cevap

Bunun nedeni pos3d + pos2dhattın bölümüdür . Bu kısım gerçekten belirsiz olsa da +=. Neden birini, neden diğerini açıklayayım.

Analiz 1

Bu hatta

transform.position = pos3d + pos2d;

derleyici pos3d + pos2d, sonucun nereye yerleştirileceğine bakılmaksızın, devam etmeden önce ifadeyi değerlendirmeye çalışır .

Bunu yapmak için, sistem önce bir Vector3 artı Vector2 ekleyen genel statik fonksiyonları bulmaya çalışır, örneğin bu olası imza:

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

veya örneğin bu olası imza:

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

Bununla birlikte, API'da bu imzalardan herhangi biri yoktur, bu nedenle derleyici parametreleri bilinen imzalara "aktarmaya" çalışır.

Derleyici bu iki olası imzayı bulur:

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

Bunlar burada belgelenmiştir: http://docs.unity3d.com/ScriptReference/Vector3-operator_add.html ve burada: http://docs.unity3d.com/ScriptReference/Vector2-operator_add.html

Yani iki olasılık var:

Her iki dökümün de mümkün olması nedeniyle, pos2d bir Vector3'e dökülebilir ve pos3d bir Vector2'ye castabale olur, daha sonra derleyici aynı kaynak kodunu derlemenin olası yollarını bulur (otomatik gizli dökümler mevcutsa).

Pos3d'yi Vector2'ye dökmek ve ikinci imzayla devam etmek ya da pos2d'yi Vector3'e dökmek ve ilk imzayla devam etmek mümkündür.

İfade pos3d + pos2dilk olarak değerlendirilirken, "sonucun nereye uygulanacağı" dikkate alınmadan önce, derleyici hangi kodlamayı gerçekleştireceğinizi bilmez.

3D'ye geçmek istiyorsanız, şunu yazabilirsiniz:

transform.position = pos3d + ( Vector3 )pos2d;

ve sorun giderildi, şimdi açık olduğu gibi: önce pos2d'yi Vector3 türünde başka bir nesneye taşıyın, sonra Vector3 + Vector3 toplamını yapın. Bu statik imza varsa,

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

hiç bir belirsizlik olmadan kullanılacak.

Analiz 2

Öte yandan,

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

belirsizlik yoktur: İlk satır Vector3'e bir Vector3 atar (şüphesiz).

İkinci satır

transform.position = transform.position + pos2d;

transform.position özelliğiyle yalnızca bir kez değerlendirilir ve bu nedenle bu Microsoft sayfasında +=operatörle ilgili gördüğünüz gibi tür dikkate alınır :

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

Buna ek olarak "+ = operatörü doğrudan aşırı yüklenemez, ancak kullanıcı tanımlı tipler + operatörünü aşırı yükleyebilir (operatöre bakın). Düşündüğümüz bu yüzden Vector3'ın +=operatör yazan yere microsoft tarafından açıklandığı gibi davranır:

x += y

eşittir

x = x + y

ancak x sadece bir kez değerlendirilir. + İşlecinin anlamı, x ve y türlerine (sayısal işlenenler için toplama, dize işlenenleri için birleştirme vb.) Bağlıdır.

bu yüzden ikinci yaklaşımın Vector3imzası olan sınıfın + işleneni çağırdığından emin olabiliriz :

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

bu nedenle bunu başarmanın başka bir yolu bulunmayan örtülü gizli döküm sayesinde pos2d'yi Vector3'e dönüştürmekten başka bir yol yoktur.

Yardım etmek için umut !!


Düzenle

In Unity 5.0.1f1 Personalile MonoDevelop-Unit 4.0.1Alex M. dediği gibi, hatları:

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

hala hatayı veriyor "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)'"

yani + = her iki imzayı da kullanıyor

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

sonucun "nereye" konacağını bilmesine bakılmaksızın (sanırım bir Vector2 çıktısı hedefe dökülebilir (Vector3) ve eğer bu döküm mümkün değilse, belki, derleyici uygun olanı seçecektir çıktı türü).

Puanınız için teşekkürler Alex M.


+=ya da çalışmıyor, hala bir Vector3+ Vector2. Cevabımı gör.

Doğru, seninkini onayladı, benimkini düzenleyecek.
Xavi Montero

Yorumunuzu ekleyecek şekilde düzenlendi.
Xavi Montero

transform.position + = pos2d derleniyor. Yarın daha hassas olacağım (sadece bir sürüm hatası olabilir)
SteakOverflow

Düzenlemelerden sonra sırayla kayboldum ... yani ... pos3d += pos2d(düzenlenmiş sorunuza göre) başarısız ama transform.position += pos2dderler (yukarıdaki yorumunuza göre) ?? Kadar tuhaf görünüyor .positionolduğunu Vector3- Eğer anlamı buysa açıkça görülmüyor.
Xavi Montero
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.