Döner aynalar


9

Aşağıdaki kodu kullanarak oyun karakterimi hedefe izlemek için döndürüyorum:

        transform.rotation = Quaternion.Slerp(startQuaternion, lookQuaternion, turningNormalizer*turningSpeed/10f)

startQuaternion, yeni bir hedef verildiğinde karakterin geçerli dönüşüdür.

lookQuaternion, karakterin bakması gereken yöndür ve şu şekilde ayarlanır:

    destinationVector = currentWaypoint.transform.position - transform.position;
    lookQuaternion = Quaternion.LookRotation(destinationVector, Vector3.up);

turningNormalizer sadece Time.deltaTimeartırılır ve turningSpeededitörde verilen statik bir değerdir.

Sorun şu ki, karakter çoğu zaman olması gerektiği gibi dönerken, 180 dereceye yakın olması gerektiğinde problemleri var. Sonra zaman zaman dönmeyi sallar ve yansıtır:

resim açıklamasını buraya girin

Bu zayıf çizilmiş görüntüde karakter (sağda) soldaki daireye doğru dönmeye başlar. Sadece sola veya sağa çevirmek yerine bu "ayna dansı" nı başlatır:

  1. Yeni yüze doğru dönmeye başlar
  2. Sonra aniden aynı açıya ancak diğer tarafa oturur ve dönmeye devam eder

Hedefe bakana kadar bu "yansıtma" yı yapar. Bu kuaterniyonlar, slerping / lerping veya başka bir şeyle mi ilgili?

EDIT1: Görünüşe göre sorun döndürmenin kendisinden kaynaklanmıyor. Daha olası olan konu, karakterin dönerken yüzeye doğru hareket etmesidir. Açıyı sınırlandırmak için, yüz ve hedef arasında, karakterin hareket etmesine izin verildiğinde, titreşim / yansıtma dönüşünü azaltır ve bazen ortadan kaldırır.

Bu elbette daha fazla soru getiriyor, karakter neden aynı anda hareket edip döndüremiyor? Hareket için kullanılan kod:

transform.Translate(Vector3.forward * runningSpeed/10f * Time.deltaTime);

'LookQuaternion' her karede güncelleniyor mu? Eğer öyleyse, benim varsayımım, bazı küçük yanlışlıkların, oyuncunun görünüm rotasyonunu 'aştığı' ve bir tür yeni yönün 'doğrudan arkasının' diğer tarafında olduğu bir tür titremeye yol açmasıdır . .
Steven Stadnicki

Yanıtlar:


5

3B uzayda her yönelim 2 farklı birim kuaterniyon ile temsil edilebilir qve -q(bileşen bazında negatif q). Örneğin, 3x3 kimlik matrisi Iile temsil edilen yönelim 2 kuaterniyonla temsil edilebilir:

 q:  { 0,  0,  0},  1
-q:  {-0, -0, -0}, -1

Her ikisi de 3D uzayda aynı yönelimi temsil eder, nokta ürünleri tam olarak -1, her biri diğer yarıkürede, tam olarak hiper kürenin karşı taraflarında bulunur.

Slerp'in dönmesi daha uzun ark aldığında gözlemlediğiniz sonuç, aynı yarımkürede yer almayan 2 kuaterniyon arasında slenping olur. Bu olursa, onları sıkmadan önce bunlardan birini yok edin, o zaman slerp daha kısa ark alacaktır.

Dot ürünü bunun olup olmadığını anlamak için kolay bir araçtır. Her iki kuaterniyonun nokta çarpımı daha azsa 0, aynı yarımkürede yatmazlar. Dolayısıyla, her ikisinin de nokta ürünü daha azsa 0, sadece bileşen bakımından diğer dördüncülüğü, onları ezmeden önce yok edin.


Bunu denediğim gibi seni doğru anladım mı acaba if(Quaternion.Dot (lookQuaternion, startQuaternion) < 0) { startQuaternion = Quaternion.Inverse(startQuaternion); }Ama bu sorunu çözmedi. Kötü biçimlendirme için üzgünüm, bu yorum bölümünü evcilleştiremiyorum.
Esa

Neredeyse ama değil Inverse, bu daha farklı bir işlem Negate. if(Quaternion.Dot (lookQuaternion, q) < 0) { q.x = -q.x; q.y = -q.y; q.z = -q.z; q.w = -q.w; }C # kullanmıyorum, ancak docu'nun görünüşüne göre, doğrudan Negate-İşlevini de kullanabileceğiniz anlaşılıyor .
Maik Semder

if(Quaternion.Dot (lookQuaternion, startQuaternion) < 0) { startQuaternion = Quaternion.Negate(startQuaternion); }
Maik Semder

Korkarım bunlar sorunu çözmedi. Soruyu güncelledim.
Esa

Evet, muhtemelen farklı hataların bir karışımı. Test kurulumunuzu basitleştirin, aynı anda çeviri ve döndürmeyi değil aynı anda bir şeyi test edin. Önce birinin, sonra diğerinin ve sonra ikisinin birlikte çalıştığından emin olun. Sadece rotasyona odaklanın, 170 derecede başlangıç, sıfıra inme, nerede yanlış gittiğini görün ve buraya gönderin gibi iyi bilinen yönlendirme değerlerini kullanın
Maik Semder 28:13

1

Sorununuz, kuaterniyonlarınızı oluşturan iki vektörün 180 dereceyi oluşturmasıdır, bu yüzden hangi yayı enterpolasyon yaparken sorulması gereken soru? üst yay veya alt yay ??

Temel olarak aynalamaya neden olan şey budur, her enterpolasyon yaptığınızda, açıyı korurken başka bir yol alıyor.

Bu bağlantıya göre .

Teta 180 derece olduğunda sonuç tanımsızdır çünkü dönecek en kısa yön yoktur, bu durumun doğru bir şekilde ele alındığını düşünmüyorum, qa veya qb'ye normal olan rastgele bir eksen seçersek daha iyi olurdu, Bunu yapmanın en iyi yolu için herhangi bir fikri takdir edin.

Yapmanız gereken başlangıç ​​kuaterniyonunuzu bir ara kuaterniyonla enterpolasyon yapmak (hangi yayın alınacağını belirlemek için) ve ulaşıldığında gerçek kuaterniyona devam etmek için ara kuaterniyonu kullanın.


1

Gördüğünüzden şüphelendiğiniz sorunun kodunuzla bir ilgisi yoktur, daha ziyade bir kürenin yüzeyi boyunca enterpolasyonla ilgili temel bir sorundur (bu durumda, viewDirection için). Bir küredeki iki nokta arasında (neredeyse) tek bir büyük daire vardır - örneğin, 'başlangıç' noktamızı keyfi olarak kuzey kutbuna sabitleyen büyük daire, bitiş noktasının üzerinde bulunduğu meridyen olacaktır. Bir noktadan diğerine enterpolasyon bu büyük daire boyunca hareket eder.

Şimdi, bir küre üzerindeki çoğu nokta için, yakındaki noktalar yakındaki büyük çevrelere karşılık gelir; örneğin, Los Angeles ve Phoenix'in yatıştığı meridyenler birbirine oldukça yakındır. Ancak varış noktası orijinal noktanın antipodu olduğunda - başlangıç ​​noktasının kuzey kutbuna güney kutbu - artık ikisi arasında tek bir büyük daire yoktur, bunun yerine birindeki tüm büyük daireler diğerinden geçer. Daha da kötüsü, bu güney kutbunun yakınındaki noktaların 'en fazla puan' olmadığı anlamına gelir; birbirine yakın iki nokta ve güney kutbunun yakınında her ikisi de çılgınca ıraksak meridyenlere sahip olabilir.

Gördüğünüz şeyin, meridyendeki - veya başka bir deyişle enterpolasyon arkındaki bu istikrarsızlığın bir tezahürü olduğundan şüpheleniyorum. Görünüm hedefi doğrudan karakterin arkasında olduğunda, karakterin konumunun 'Euler entegrasyonunda' birinci dereceden yanlışlık ve görünüm yönünü çerçeveden çerçeveye değiştirme yolu, çılgınca bu durumlara yol açacaktır. farklı enterpolasyon yayları bir çerçeveden diğerine ve bu muhtemelen gördüğünüz 'kademelendirmeye' yol açacaktır.

Bununla ilgili olarak, akla gelen en iyi şey, 'hedef' bakış yönünü her kareyi yeniden hesaplamamaktır; bunun yerine, birkaç karenin açıklığı için aynı olanı kullanın, ardından yeni bir kareyi hesaplayın ve bunu birkaç kare, vb. için kullanın. Gerekirse, bir hedeften diğerine birkaç karenin üzerinde enterpolasyon yapabilirsiniz, böylece hareket yönü aniden değişmiyor.

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.