Unity'nin OnCollisionEnter bana neden yüzey normalleri vermiyor ve bunları almanın en güvenilir yolu nedir?


11

Unity'nin çarpışma olayı, gerçekleşen çarpışma hakkında size bazı bilgiler veren bir Çarpışma nesnesi verir ( vuruş normalleri olan ContactPoints listesi dahil ).

Ama elde edemeyeceğiniz çarptığınız çarpıştırıcının yüzey normalleri. İşte açıklamak için bir ekran görüntüsü. Kırmızı çizgi geldi ContactPoint.normalve mavi çizgi geldi RaycastHit.normal.

resim açıklamasını buraya girin

Bu, Unity'nin basitleştirilmiş bir API sağlamak için bilgi gizleme örneği mi? Yoksa standart 3D gerçek zamanlı çarpışma algılama teknikleri sadece bu bilgileri toplamıyor mu?

Ve sorunun ikinci kısmı için, bir çarpışma için normal bir yüzey elde etmenin kesin ve nispeten etkili bir yolu nedir?

Yeniden yayınlamanın size yüzey normalleri verdiğini biliyorum, ancak tüm senaryolar için bunu gerçekleştirmek için birkaç tane raycast yapmam gerekiyor gibi görünüyor (belki bir temas noktası / normal kombinasyon ilk oyuncudaki çarpıştırıcıyı özlüyor, ya da belki de tüm ortalamaları yapmanız gerekiyor en iyi sonucu almak için temas noktalarının normalleri).

Mevcut yöntemim:

  1. Collision.contacts[0].pointİsabet normal boyunca yedekleyin

  2. Raycast için olumsuz vuruş normal float.MaxValue,Collision.collider

  3. Bu başarısız olursa, 1. ve 2. adımları negatif olmayan normal ile tekrarlayın

  4. Bu başarısız olursa, 1-3 arasındaki adımları Collision.contacts[1]

  5. Başarılı olana kadar veya tüm temas noktaları tükenene kadar 4'ü tekrarlayın.

  6. Vazgeç, geri dön Vector3.zero.

Bu her şeyi yakalıyor gibi görünüyor, ama tüm bu ırkçılar beni rahatsız ediyor ve bunun yeterli durumlar için nasıl çalıştığını test edemiyorum. Daha iyi bir yol var mı?

DÜZENLEME Bu gerçekten 3D çarpışmada olan şeyse, genel durumda neden Unity'ye özgü bir şey kadar hoş karşılanır.


Bu sadece merak için mi, yoksa bir şeyler yapmaya ve takılmaya mı çalışıyorsun? Yani, neden normal yüzeye ihtiyacınız olduğunu düşünüyorsunuz? Belirtilmemiş bir soruna bir çözümü nasıl "düzeltmek" yerine, nasıl bir etki yaratmaya çalıştığınız hakkında bir soru sorun ve birisi bunu çözmenize yardımcı olabilir. :)
Sean Middleditch

@SeanMiddleditch Kabul etmiyorum. Soru iyi konuldu ve tam da aradığım şeydi. Bu soru ve cevapları yanlış yaptığım bazı şeyleri düzeltmeme yardımcı oldu.
SteakOverflow

Yanıtlar:


12

Bu gerçekten işlerin çarpışmada olduğu şekildedir. Sadece 3D değil, aynı zamanda 2D. Aşağıdaki örneği alın:

Çakışan AABB'ler

Yeşil ve kırmızı AABB'ler çarpışıyor ve kontak manifoldu mavi alan. Temas noktaları bir yerde mavi alanda olacaktır (algoritma ile tam olarak değişebilir, ancak mavi / kırmızı / yeşilin buluştuğu köşeler ideal-ish'dir).

Hangi yüzey normal döndürülmelidir? Kırmızı AABB'nin üst kenarı mı yoksa sol kenarı mı? Yeşil kutu düşüyorsa, belki de üst kenarı makul bir şekilde tahmin edebiliriz. eğer sağa hareket ederse, belki de sol kenarı makul bir şekilde tahmin edebiliriz. Ya aşağı ve sağa hareket ediyor olsaydı? En az penetrasyon eksenini alıyor muyuz? En yüksek hızın hız ekseni? İkisinden de sezgisel mi? Kutular köşelerde tam olarak çarpışırsa ne olurdu?

Potansiyel olarak tris / yüzlerden oluşan karmaşık bir 3D yüzeye uzatın. Hâlâ az sayıda ideal-ish temas noktasına sahip olacaksınız. Hangi yüzey normal döndürülmelidir? Tüm üç kafes boyunca normal yüzey (çoğu nesne için mantıklı değil)? Noktalar doğrudan çarpışan kutunun köşelerini "altında" (diğer birçok şekil için iyi tanımlanmamıştır)? Oluşturulan temas noktalarına en yakın yüzü bulmaya mı çalışıyorsunuz (temas noktaları doğrudan kafes yüzeylerinden hesaplanmadığı için ikinci bir geçiş gerekir)? En yakın yüzü bulursanız, yüzün normalliğini alıyor musunuz veya "pürüzsüz" nesneler için doğru normali elde etmek için yüzün köşelerini temas noktasında enterpolasyonlu musunuz?

Asıl sorun, temas noktalarının tüm temas noktaları olmamasıdır . Çoğu durumda, bu sonuçta sonsuz bir nokta kümesi olurdu. Bunlar, iyi dağıtılmış birkaç nokta olup, çarpışma nesnelerini yeniden akışkan bir şekilde itmek için bahsedilen noktalara kuvvet uygulayarak fiziksel reaksiyonun yaklaşık olarak gerçekleştirilmesini makul bir şekilde mümkün kılar. Gerçek nesne temasının belirli noktaları / yerleri basitleştirilmiş bir matematiksel modelin arkasında soyutlanır. Bu nedenle, temastan normal olan belirli bir yüzey fikri genel durumda pek mantıklı değildir.

Tabii ki, nesneleriniz, dünyanız ve hareketiniz hakkında daha spesifik kısıtlamalar ve sınırlamalar ile, yüzey normalini anlatabilecek alternatif çarpışma algoritmaları oluşturabilirsiniz. Yukarıdaki 2D durumda, kutuların asla dönmediğini ve her birinin göreceli hızını ve son konumunu bildiğimizi varsayarsak, tam olarak ne zaman çarpışacaklarını ve hangi özelliklerin çarpışacağını öğrenmek için sürekli çarpışma algılamayı kullanabilir. çarpışma meydana geldiği tam özellik, daha sonra temas / çarpışma / yüzey normal olarak kullanılabilir. Platform oyunları tamamen bu varsayımlara ve özel hilelere dayanır (Bu yüzden Box2D veya Havok gibi genel bir fizik kütüphanesi kullanmak veya ışık Mario veya Sonic gibi klasik platformcularda asla bu tür sıkı, hassas kontroller üretmez; söylemek istiyorum '

Unity3D'de kullanılanlar gibi genel Newton fizik kütüphaneleri bu tür basitleştirmeleri ve varsayımları yapamazlar. Bu nedenle, çarpışma yüzeyi normalleri alamazsınız, genellikle temas noktalarına basitleştirilmiş bir temas manifoldu alırsınız ve hepsi bu.


Bu harika bir cevap ve tam olarak aradığım şey, teşekkür ederim. Buradaki sorun çarpışmadaki kinematik katı bir cisim üzerinde ikna edici bir yansıma vektörü almaktı. Bu tür bir bilginin (eğer varsa) 3 temas noktasını toplamak veya almak ve çapraz ürünü almak isteyip istemediğinizi seçmek istiyorsanız olağan yaklaşım mıdır?
michael.bartnett
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.