Bir yolda yürürken karakterlerimin nasıl düzgünleşmesini sağlar (koordinatlar listesi)?


15

A * algoritmasından çıktı - koordinatları olan bir listem var ve karakterlerimin bu yolu rotasyonlarla sorunsuz bir şekilde takip etmesini istiyorum.

Yani A gibi bir şeyim var ve C almak istiyorum

resim açıklamasını buraya girin

Bunu nasıl yapabilirim ?

DÜZENLE

Kendimi biraz daha açıklığa kavuşturmak için:

Bir düğümden diğerine nasıl yürüyeceğimi bildiğim için pürüzsüz tornalama ile daha çok ilgileniyorum .

DÜZENLE

Birçok kişi bunu yararlı bulduğunda (ben de) Daniel Shiffman'ın "Kodun doğası" na bağlantı gönderiyorum, burada oyun AI (ve fizik) problemlerini tartışıyor, örneğin direksiyon davranışları http://natureofcode.com/book/chapter- 6-otonom-maddeler / # chapter06_section8


Unity'de yerleşik yol bulma değil mi?
joltmode

@Tom Evet ama yine de sürümümü uyguladım. Bu sorunun amacı, yolda yürürken yumuşak dönüşler (dönüşler) elde etmektir.
Patryk

3
Google için bu konuda güzel bir terim 'Direksiyon Davranışı' :)
Roy T.

3
@RoyT. Elbette ! Bu birkaç hafta önce okuyordum ve zaten unuttum: / Bu harika matematik + fizik açıklaması natureofcode.com
Patryk

1
Sadece @Patryk'e bağlantı için teşekkür etmek istedim - gerçekten bilgilendirici görünüyor ve yönlendirme davranışı hakkında iyi bir kaynak arıyorum.
Hıristiyan

Yanıtlar:


7

Döşeme tabanlı bir ortamda düzgün yollar istiyorsanız , A * ara noktalarınıza bazı yol düzeltme uygulamanızın bir yolu yoktur . Matt Buckland, programlama oyunu AI hakkındaki kitabında, bir yolu düzeltmek için basit ve hızlı bir algoritma açıklar (temel olarak engellerinizle bir kesişmeye neden olmadan çıkarılabilen tüm kenarları kaldırın).

Bu gibi gereksiz kenarları çıkardıktan sonra ilk durumunuz ( A -> B ) çözülür. Grafiğinizdeki kenarları yumuşatmak birkaç yolla gerçekleştirilebilir. Büyük olasılıkla, Hermite spline'lar (sizin engel yoğunluğu ve kiremit-boyutuna biraz değişir) çalışacak. Başka bir seçenek de, geçerli hedeften yarım karo çıkar çıkmaz bir sonraki yol noktasına doğru yönelmeye başladığınız yönlendirme davranışları olabilir (bu gerçekten de "ajanınızın" ne kadar hızlı hareket ettiğine / döndüğüne bağlıdır).


9

Diğerlerinin de belirttiği gibi, ikinci durumda bir tür spline uygulamanız veya (aslında örneğinize daha iyi uymanız) birime bir tür direksiyon davranışı vermeniz gerekecektir.

Bununla birlikte, ilk durumda, hem yol hem de yol düzeltmeden daha iyi sonuçlar veren bir çözüm var. Buna Theta * denir ve birimlerin ızgara noktaları arasında herhangi bir yönde hareket etmesini sağlayan ızgaralar üzerindeki A * 'nın basit (ve nispeten yeni) bir uzantısıdır.

Teta * ve yol düzeltme

Teta * açıklayan güzel bir makale (hangi yukarıdaki görüntüyü çaldı) Orada burada


2

Daha insani gerçekçi bir hareket için, Direksiyon Davranışları ile entegre olmayı deneyin. (Klasik OpenSteer'ın C # sürümü http://sharpsteer.codeplex.com/ ) AStar çıktısını alıyorsunuz ve direksiyon davranışının hareketlerle ilgilenmesine izin veriyorsunuz (Örneklerden biri bunun nasıl yapılacağını tam olarak gösteriyor, bir yolu takip ederek geziniyor)


1

Noktadan noktaya navigasyon durumunda, açılardaki farkı kullandım (geçerli oyuncu yönü ile mevcut noktadan bir sonraki noktaya yön) ve sonra hareket gerçekleştikçe açıyı kademeli olarak son açıya değiştirdim. Bu oyunu kontrol et buraya uçaklar başka 1 noktasından hareket ama dönüş ani fakat yolun noktalarını belirleyebilir dikkatle birini izledikten üzerinde olmadığı. (oyun yalnızca mobil cihazlarda, tercihen iPhone / iPad'de çalışır).


Sonunda bunu yaptım.
Patryk

1

İle iyi şanslar yaşadım Catmull-Rom splines (@bummzack tarafından da önerilen bir tür kübik spline) . Bunların iyi yanı, spline'ın her zaman kontrol noktalarından geçecek olması, diğerlerinin de yapmamasıdır. Bunun gibi bir şey uygulayın:

t    = <time*>
t12  = t + 1.0
t23  = t
t34  = t - 1.0
t123 = (t + 1.0) / 2.0
t234 = t / 2

c1 = controlpoint[0];
c2 = controlpoint[1];
c3 = controlpoint[2];
c4 = controlpoint[3];

l12 = lerp(c1, c2, t12);
l23 = lerp(c2, c3, t23);
l34 = lerp(c3, c4, t34);
position = lerp(lerp(l12, l23, t123), lerp(l23, l34, t234), t);

* zaman , kontrol noktaları 1 ve 2 arasındaki bir değer [0,1] 'dir.


0

A-> B ızgara yerine navigasyon ağları kullanılarak çözülebilir. Bu, yol bulma veri üretiminde büyük bir değişiklik anlamına gelir.

C ve D gibi durumlar sadece köşe kesicidir: karakter bir yolda ve bir "köşede" hareket ediyorsa (önceki, akım, sonraki hücrelerin düz bir çizgide olmadığı hücre), hem önceki hem de sonraki hücre yönünde itin . Tek sorun, gerçek konumdan mesafeyi (itme mesafesi) belirlemektir. Bu muhtemelen giriş olarak mevcut hücreden uzaklığı gerektirir. Bunun gibi bir şey:

push_dir = average( prevcell.pos, nextcell.pos ) - curcell.pos;
push_dist = cell_half_width - distance( char.pos, curcell.pos );
char.pos += push_dir * push_dist;
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.