Perilaku atau logika kemudi seperti apa yang dapat saya gunakan untuk membuat ponsel mengelilingi orang lain?

10

Saya menggunakan pencarian jalan di permainan saya untuk memimpin massa ke pemain lain (untuk mengejar mereka). Ini berfungsi untuk membuat mereka melampaui pemain, tapi saya ingin mereka berhenti sedikit sebelum tujuan mereka (jadi memilih simpul kedua dari belakang bekerja dengan baik).

Namun, ketika banyak gerombolan mengejar ponsel mereka kadang-kadang "menumpuk satu sama lain". Apa cara terbaik untuk menghindari ini? Saya tidak ingin memperlakukan massa sebagai buram dan terhalang (karena mereka tidak, Anda dapat berjalan melalui mereka) tetapi saya ingin massa memiliki beberapa rasa struktur.

Contoh:

Bayangkan bahwa setiap ular membimbing dirinya sendiri kepada saya dan harus mengelilingi "Setsuna". Perhatikan bagaimana kedua ular telah memilih untuk menggonggong saya? Ini bukan persyaratan yang ketat; bahkan sedikit diimbangi tidak apa-apa. Tetapi mereka harus "mengelilingi" Setsuna.

masukkan deskripsi gambar di sini

Vaughan Hilts
sumber
1
Apakah penumpukan hanya menjadi perhatian di tujuan atau juga saat transit? Saya menduga yang terakhir.
SpartanDonut
Yang terakhir, @SpartanDonut
Vaughan Hilts
@KromStern Saya menambahkan gambar, semoga membantu.
Vaughan Hilts

Jawaban:

15

Berikan agen Anda "muatan elektrostatik" yang lemah untuk membuat mereka saling tolak, di sepanjang garis hukum Coulomb .

Dengan asumsi untuk kesederhanaan bahwa massa harus mendorong satu sama lain dengan kekuatan yang setara, itu harus cukup untuk menerapkan kekuatan antara setiap pasangan massa dengan besarnya some_constant / distance^2, di mana some_constantkekuatan tolakan yang dapat dikonfigurasi dan distancejarak memisahkan mereka.

Kekuatan tolakan kemudian jatuh dengan kuadrat jarak.

Nature of Code memiliki contoh yang bagus (dengan demo langsung) di sini . Ini terlihat seperti ini:

gabungan mengikuti dan memisahkan perilaku

Mencocokkan setiap elemen dengan elemen lainnya adalah operasi kuadratik-waktu ( O(n^2)). Jika Anda memiliki sangat banyak agen, Anda mungkin ingin mengoptimalkan perhitungan gaya dengan pendekatan Barnes-Hut , yang membawanya ke log-linear ( O(n log n)) tetapi membutuhkan quadtree .

Anko
sumber
Tautan hebat, Anko. Sangat dihargai! Saya harus memberikan seluruh situs ini membaca ulang.
Vaughan Hilts
Starcraft (1, setidaknya) melakukan sesuatu yang mirip dengan unit terbangnya. Tapi itu hanya terjadi ketika mereka berhenti bergerak, yaitu ketika mereka sedang bergerak mereka menggumpal satu sama lain (benar-benar mengabaikan satu sama lain sebagai hambatan), tetapi ketika mereka berhenti mereka semua mulai menyebar keluar dari apa yang tampak seperti menjadi pusat lokal dari beberapa area reguler (persegi / lingkaran, mungkin) yang meliputi mereka. Ini tidak terlihat secantik contoh dalam jawaban, tetapi mungkin menggunakan lebih sedikit sumber daya CPU, dan mungkin lebih mudah untuk kode juga ...
Shivan Dragon
@ShivanDragon SC2 menghadirkan perilaku yang sama, mereka semua bertemu di tempat tujuan di tengah keramaian, lalu keluar untuk penampilan yang realistis dan menyenangkan (sehingga bagian-bagian mereka tidak terpotong-potong).
Kroltan
2
Beberapa jenis kekuatan memukul mundur bisa menjadi ide yang bagus, tetapi detailnya rumit. Saya bereksperimen dengan ini di ruang bertema RTS dan merekomendasikan untuk tidak mengikuti fisika terlalu dekat dan lebih baik memodelkannya sehingga berperilaku baik. Beberapa pengamatan: 1) Karena ini bukan simulasi fisika saya hanya akan menerapkan gaya jarak pendek. 2) Ini tidak dapat mencegah benda hingga tumpang tindih 3) Potensi keras dengan mudah menyebabkan kesalahan numerik, seperti partikel yang dibiaskan pada kecepatan tinggi. 4) Setelah Anda memiliki sejumlah besar partikel dan tekanan di tengah naik, hal-hal cenderung menjadi jelek.
CodesInChaos
1

Pendekatan saya mirip dengan @ Anko, tetapi berdasarkan pada karya Millington dan Funge dari Artificial Intelligence for Games .

Ini akan terlihat seperti perilaku Pemisahan, tetapi Anda harus mempertimbangkan bahwa kecepatan ini harus dihitung dengan kecepatan agen dalam fungsi Pembaruannya.

public Vector3 GetSeparationVel (float threshold, float decayCoefficient)
{
    threshold = threshold * threshold;
    Vector3 separationVelocity = Vector3.Zero;
    for (int i = 0; i < enemies.Length; i++) {
        if (enemies[i] == this) {
            continue;
        }
        Vector3 direction = this.position - enemies[i].position;
        float distance = direction.LengthSquared();
        float strenght = 0.0f;
        if (distance < (threshold)) {
            strenght = Math.Min(decayCoefficient / distance, this.maxAccel);
            direction.Normalize();
            separationVelocity += strenght * direction;
        }
    }
}
reefaktor
sumber