Mengikuti jalur dan mengendalikan lalu lintas
Terkadang kita membutuhkan karakter AI untuk berkeliaran di dunia game, mengikuti jalur yang ditentukan secara kasar atau ditentukan dengan tepat. Misalnya, dalam permainan balapan, lawan AI harus melakukan perjalanan di sepanjang jalan, dan di RTS, unit harus dapat bergerak ke titik yang diinginkan, bergerak di sepanjang medan dan memperhitungkan posisi masing-masing.
Agar tampak cerdas, agen AI harus dapat menentukan apa yang mereka lakukan, dan jika mereka tidak dapat mencapai titik yang diinginkan, maka mereka harus dapat merencanakan rute yang paling efektif dan mengubah jalur mereka ketika ada hambatan di jalan.
Menghindari rintangan adalah perilaku sederhana yang memungkinkan entitas AI mencapai titik target. Penting untuk dicatat bahwa perilaku yang diterapkan dalam posting ini adalah untuk perilaku seperti simulasi kerumunan, di mana tujuan utama setiap agen adalah untuk menghindari agen lain dan mencapai tujuan. Mereka tidak menentukan jalur yang paling efisien dan terpendek.
Persyaratan teknis
Membutuhkan Unity 2017 diinstal pada sistem dengan Windows 7 SP1 +, 8, 10, atau Mac OS X 10.9+. Kode dalam artikel ini tidak akan berfungsi pada Windows XP dan Vista, dan versi server Windows dan OS X belum diuji.
File kode untuk posting ini dapat ditemukan di
GitHub .
Untuk mempelajari kode ini dalam aksi, tonton
video ini .
Jala navigasi
Mari kita cari tahu cara menggunakan generator mesh navigasi Unity bawaan, yang dapat sangat menyederhanakan pencarian jalur untuk agen AI. Pada tahap awal Unity 5.x, fungsi NavMesh menjadi tersedia untuk semua pengguna, termasuk yang memiliki lisensi edisi pribadi, meskipun sebelumnya hanya berfungsi untuk Unity Pro. Sebelum rilis 2017.1, sistem telah diperbarui untuk menyediakan alur kerja berbasis komponen, tetapi karena membutuhkan paket tambahan yang dapat diunduh, yang pada saat penulisan ini hanya tersedia dalam versi pratinjau, kami akan mematuhi alur kerja berbasis adegan standar. Jangan khawatir, konsep kedua pendekatan itu serupa, dan ketika implementasi yang telah selesai akhirnya mencapai 2017.x, seharusnya tidak ada perubahan signifikan.
Pelajari lebih lanjut tentang sistem komponen NavMesh di Unity on
GitHub .
Sekarang kita akan mengeksplorasi semua kemungkinan yang dapat ditawarkan oleh sistem ini kepada kita. Untuk mencari jalur AI, adegan harus disajikan dalam format tertentu; pada peta 2D, grid dua dimensi (array) digunakan untuk mencari jalur menggunakan algoritma A *. Agen AI perlu tahu di mana hambatannya, terutama yang statis. Berurusan dengan tabrakan antara objek yang bergerak secara dinamis adalah masalah lain yang biasa disebut sebagai perilaku kemudi. Unity memiliki alat bawaan untuk menghasilkan NavMesh, mewakili adegan dalam konteks yang nyaman bagi agen AI untuk menemukan jalur optimal ke target. Untuk memulai, buka proyek demo dan buka adegan NavMesh.
Kartu belajar
Setelah membuka adegan demo NavMesh, seharusnya terlihat seperti pada tangkapan layar:
Adegan hambatan dan kemiringanIni akan menjadi kotak pasir kami untuk menjelaskan dan menguji fungsionalitas sistem NavMesh. Skema umum mirip dengan game dalam genre RTS (strategi real-time). Kami mengendarai tangki biru. Klik pada titik yang berbeda sehingga tangki bergerak ke arah mereka. Indikator kuning adalah target tangki saat ini.
Navigasi statis
Pertama, Anda perlu mengatakan bahwa Anda harus menandai semua geometri dalam adegan, dipanggang di NavMesh, sebagai
Navigasi Statis . Anda mungkin pernah melihat ini sebelumnya, misalnya, dalam sistem peta pencahayaan Unity. Untuk membuat objek game statis sangat sederhana, cukup centang kotak
Statis untuk semua propertinya (navigasi, pencahayaan, culling, batching, dll.), Atau gunakan daftar drop-down untuk menentukan properti. Kotak centang terletak di sudut kanan atas inspektur objek yang dipilih.
Navigasi Properti StatisIni dapat dilakukan secara individual untuk objek yang berbeda atau, jika Anda memiliki hierarki objek game bawaan, terapkan parameter ke objek induk, setelah itu Unity akan menawarkan untuk menerapkannya ke semua objek anak.
Memanggang Mesh Navigasi
Untuk keseluruhan adegan, opsi navigasi navmesh diterapkan menggunakan jendela
Navigasi . Jendela ini dapat dibuka dengan masuk ke
Jendela |
Navigasi Seperti jendela lainnya, jendela dapat diputus untuk gerakan bebas atau diperbaiki. Di tangkapan layar kami, ditampilkan sebagai tab merapat di sebelah hierarki, tetapi Anda dapat meletakkan jendela ini di tempat yang nyaman.
Membuka jendela, Anda akan melihat tab individual. Akan terlihat seperti ini:
Jendela NavigasiDalam kasus kami, tangkapan layar sebelumnya menunjukkan tab
Bake , tetapi di editor Anda, tab apa pun dapat dipilih secara default.
Mari kita lihat masing-masing tab, mulai dari kiri dan pindah ke kanan. Mari kita mulai dengan tab
Agen , yang terlihat seperti tangkapan layar menunjukkan:
Tab AgenJika Anda mengerjakan proyek lain, Anda mungkin menemukan bahwa beberapa pengaturan berbeda dari yang kami atur untuk proyek contoh yang ditunjukkan pada tangkapan layar. Di bagian atas tab ada daftar di mana Anda dapat menambahkan jenis agen baru dengan mengklik tombol
+ . Anda dapat menghapus agen tambahan dengan memilihnya dan mengklik tombol
- . Jendela dengan jelas menunjukkan apa yang dilakukan berbagai pengaturan saat mengubahnya. Mari kita lihat apa yang dilakukan masing-masing pengaturan:
- Nama: nama jenis agen yang ditampilkan dalam daftar turun-bawah Jenis Agen.
- Radius: Anda dapat menganggapnya sebagai "ruang pribadi" agen. Agen akan mencoba untuk menghindari kontak yang terlalu dekat dengan agen lain berdasarkan nilai ini, karena digunakan dalam penghindaran.
- Tinggi: seperti yang Anda duga, pengaturan ini menetapkan ketinggian agen yang digunakannya untuk penghindaran vertikal (misalnya, ketika melewati benda-benda di bawah).
- Tinggi Langkah: nilai ini menentukan ketinggian apa yang bisa dipanjat agen.
- Max Slope: seperti yang akan kita lihat dari bagian selanjutnya, nilai ini menentukan sudut maksimum di mana agen dapat naik. Dengan menggunakan parameter ini, Anda dapat membuat lereng curam peta tidak dapat diakses oleh agen.
Selanjutnya, kami memiliki tab
Area , yang terlihat seperti yang ditunjukkan pada tangkapan layar ini:
Seperti yang dapat Anda lihat di tangkapan layar, Unity menyediakan beberapa jenis area yang tidak dapat diubah:
Walkable ,
Not Walkable, dan
Jump . Selain memberi nama dan membuat area baru, Anda dapat menetapkan biaya untuk bergerak di area tersebut.
Area melayani dua tujuan: membuat area dapat diakses atau tidak dapat diakses oleh agen, dan menandai area yang kurang diinginkan dalam hal biaya perjalanan. Misalnya, Anda dapat mengembangkan RPG di mana musuh iblis tidak dapat memasuki area yang ditandai sebagai "tanah yang dikuduskan". Anda juga dapat menandai beberapa area peta sebagai "rawa" atau "rawa", yang akan dihindari agen karena tingginya biaya bergerak.
Tab
Panggang ketiga mungkin yang paling penting. Ini memungkinkan Anda untuk membuat NavMesh sendiri untuk adegan itu. Anda harus sudah terbiasa dengan beberapa opsi. Tab
Bake terlihat seperti ini:
Bake tabOpsi ukuran agen pada tab ini menentukan bagaimana agen akan berinteraksi dengan lingkungan, sedangkan opsi pada tab
Agen mengontrol interaksi dengan agen lain dan objek bergerak. Tetapi mereka mengontrol parameter yang sama, jadi kita akan melewatkannya.
Jatuhkan Tinggi dan
Jarak Lompat mengontrol seberapa jauh agen dapat "melompat" untuk mencapai bagian NavMesh yang tidak terkait langsung dengan bagian di mana agen saat ini berada. Kami akan mempertimbangkan ini secara lebih rinci di bawah ini, jadi jika Anda tidak yakin, maka Anda masih tidak dapat mempelajari parameter ini.
Selain itu, ada opsi lanjutan yang biasanya disembunyikan secara default. Untuk memperluas opsi ini, cukup klik pada segitiga tarik-turun di sebelah tajuk
Tingkat Lanjut .
Ukuran Manual Voxel dapat dianggap sebagai pengaturan "kualitas". Semakin kecil ukurannya, semakin banyak detail yang akan disimpan dalam jaring.
Area Wilayah Min digunakan untuk melewati platform pemanggangan atau permukaan di bawah ambang batas yang dipilih.
Tinggi Mesh memberi kita data vertikal yang lebih rinci saat memanggang mesh. Misalnya, opsi ini memungkinkan Anda untuk mempertahankan lokasi agen yang benar saat menaiki tangga.
Tombol
Hapus menghapus semua data NavMesh dari adegan tersebut, dan tombol
Bake menciptakan mesh untuk adegan tersebut. Proses memanggang cukup cepat. Selama Anda memiliki jendela yang dipilih, Anda dapat mengamati generasi NavMesh dengan tombol
Bake di jendela adegan. Mari klik tombol
Bake untuk melihat hasilnya. Dalam contoh adegan kami, kami berakhir dengan sesuatu yang mirip dengan tangkapan layar ini:
Area biru menunjukkan NavMesh. Di bawah ini kami akan kembali ke sini. Sementara itu, mari kita beralih ke tab terakhir -
Obyek , yang terlihat seperti ini:
Tiga tombol yang diperlihatkan dalam tangkapan layar sebelumnya -
All ,
Mesh Renderers, dan
Terrains - digunakan sebagai filter adegan. Mereka berguna saat bekerja dalam adegan kompleks dengan banyak objek dalam hierarki. Memilih opsi memfilter jenis yang sesuai dari hierarki, membuatnya mudah untuk memilihnya. Anda dapat menggunakan tombol untuk menjelajahi adegan Anda dalam mencari objek yang ingin Anda tandai sebagai navigasi statis.
Menggunakan Agen Nav Mesh
Sekarang kami telah menyiapkan adegan dengan NavMesh, kami membutuhkan cara bagi agen untuk menggunakan informasi ini. Untungnya bagi kami, Unity memiliki komponen
Nav Mesh Agent yang dapat Anda seret ke karakter. Dalam adegan contoh kami, ada objek permainan yang disebut
Tank , yang komponennya sudah terpasang. Lihatlah hierarki dan Anda akan melihat sesuatu seperti ini:
Ada beberapa parameter di sini, dan kami tidak akan mempertimbangkan semuanya, karena cukup jelas, dan uraiannya dapat ditemukan di dokumentasi resmi Unity. Tetapi kami akan menyebutkan hal-hal utama:
- Jenis Agen : Ingat tab Agen di jendela Navigasi ? Jenis agen yang dapat ditugaskan dapat dipilih di sini.
- Auto Traverse Off Mesh Link : Opsi ini memungkinkan agen untuk secara otomatis menggunakan fitur Off Mesh Links , yang akan kita bahas di bawah ini.
- Area Mask : di sini Anda dapat memilih area yang dikonfigurasikan di tab Area pada jendela Navigasi .
Itu saja. Komponen ini melakukan 90% kerja keras untuk kita: membuka jalan, menghindari rintangan, dan sebagainya. Satu-satunya hal yang Anda butuhkan adalah mentransfer titik target ke agen. Mari kita lihat masalah ini.
Pengaturan Titik Target
Setelah mengatur agen AI, kita perlu cara untuk memberitahunya ke mana harus pergi. Dalam proyek contoh kami, ada skrip bernama
Target.cs yang melakukan tugas ini dengan tepat.
Ini adalah kelas sederhana yang melakukan tiga hal:
- “Tembak” pancaran dari kamera ke posisi mouse di dunia
- Memperbarui posisi marker
- Memperbarui properti tujuan untuk semua agen NavMesh.
Kode ini cukup sederhana. Seluruh kelas adalah sebagai berikut:
using UnityEngine; using UnityEngine.AI; public class Target : MonoBehaviour { private NavMeshAgent[] navAgents; public Transform targetMarker; private void Start () { navAgents = FindObjectsOfType(typeof(NavMeshAgent)) as NavMeshAgent[]; } private void UpdateTargets ( Vector3 targetPosition ) { foreach(NavMeshAgent agent in navAgents) { agent.destination = targetPosition; } } private void Update () { if(GetInput()) { Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition); RaycastHit hitInfo; if (Physics.Raycast(ray.origin, ray.direction, out hitInfo)) { Vector3 targetPosition = hitInfo.point; UpdateTargets(targetPosition); targetMarker.position = targetPosition; } } } private bool GetInput() { if (Input.GetMouseButtonDown(0)) { return true; } return false; } private void OnDrawGizmos() { Debug.DrawLine(targetMarker.position, targetMarker.position + Vector3.up * 5, Color.red); } }
Tindakan berikut terjadi di sini: di metode
Mulai , kami menginisialisasi array
navAgents menggunakan metode
FindObjectsOfType () .
Metode
UpdateTarget () melewati array
navAgents kami dan menetapkan titik target untuk mereka dalam
Vector3 yang diberikan. Ini adalah kunci kode. Anda dapat menggunakan mekanisme apa pun untuk mendapatkan titik target, dan agar agen pindah ke sana, cukup setel bidang
NavMeshAgent.destination ; agen akan melakukan sisanya.
Dalam contoh kami, klik digunakan untuk bergerak, jadi ketika pemain mengklik mouse, kami melepaskan sinar dari kamera ke dunia ke arah kursor mouse, dan jika berpotongan dengan sesuatu, maka kami menetapkan titik tumbukan ke agen
targetPosisi yang baru. Kami juga menyesuaikan penanda target sesuai dengan mudah memvisualisasikan tujuan dalam permainan.
Untuk menguji operasi, Anda perlu memanggang NavMesh sesuai dengan deskripsi dari bagian sebelumnya, lalu mulai mode Putar dan pilih area mana saja di peta. Jika Anda mengklik berkali-kali, Anda dapat melihat bahwa agen tidak dapat mencapai beberapa area - bagian atas kubus merah, platform atas dan platform di bagian bawah layar.
Kubus merah terlalu tinggi. Kemiringan yang mengarah ke platform tertinggi terlalu tajam untuk pengaturan
Max Slope kami, dan agen tidak dapat memanjatnya. Tangkapan layar berikut menunjukkan bagaimana pengaturan
Max Slope memengaruhi NavMesh:
NavMesh dengan kemiringan maks = 45Jika Anda mengubah nilai
Max Slope ke sesuatu seperti
51 , dan kemudian klik tombol
Bake lagi untuk memanggang NavMesh lagi, hasilnya adalah sebagai berikut:
NavMesh dengan kemiringan maksimum = 51Seperti yang Anda lihat, kami dapat menyesuaikan desain level, membuat seluruh area tidak dapat diakses dengan mengubah satu parameter. Ini bisa berguna, misalnya, ketika Anda memiliki platform atau langkan yang membutuhkan tali, tangga atau lift untuk dipanjat. Atau mungkin keterampilan khusus, misalnya, kemampuan memanjat?
Aplikasi Off Mesh Links
Anda mungkin memperhatikan bahwa ada dua jeda di adegan kami. Agen kami dapat masuk ke yang pertama, tetapi yang di bagian bawah layar terlalu jauh. Perhitungan ini tidak sepenuhnya arbitrer.
Off Mesh Links pada dasarnya membuat jembatan melintasi ruang antara segmen NavMesh yang tidak terkait. Tautan ini dapat dilihat di editor:
Lingkaran biru dengan garis penghubung adalah koneksi.Unity dapat menghasilkan tautan ini dalam dua cara. Yang pertama sudah kami pertimbangkan. Ingat nilai
Jump Distance di tab
Bake pada jendela
Navigasi ? Unity secara otomatis menggunakan nilai itu untuk menghasilkan tautan ini saat memanggang NavMesh. Coba ubah nilainya di adegan pengujian kami menjadi 5 dan buat lagi. Lihat - platform sekarang terhubung? Ini karena jerat sekarang dalam ambang yang ditentukan baru.
Ubah nilainya menjadi 2 lagi dan panggang. Sekarang mari kita lihat cara kedua. Buat bola yang akan digunakan untuk menghubungkan kedua platform. Tempatkan kira-kira seperti yang ditunjukkan pada tangkapan layar:
Anda sudah dapat melihat apa yang terjadi, tetapi mari kita menganalisis proses yang memungkinkan mereka terhubung. Dalam kasus kami, saya menyebut bola di
awal yang benar, dan bola di
ujung kiri. Anda akan segera mengerti mengapa. Selanjutnya, saya menambahkan komponen
Off Mesh Link ke platform di sebelah kanan (relatif terhadap tangkapan layar sebelumnya). Anda akan melihat bahwa komponen memiliki bidang
awal dan
akhir . Seperti yang Anda tebak, kami akan menyeret bola yang dibuat sebelumnya ke slot yang sesuai - bola awal di bidang
awal dan bola akhir di bidang
akhir . Inspektur akan terlihat seperti ini:
Nilai
Override Biaya diperhitungkan saat diberi nilai positif. Ini menerapkan faktor biaya ketika menggunakan hubungan ini sebagai lawan dari rute yang lebih hemat biaya ke target.
Bi Directional jika benar memungkinkan agen bergerak ke dua arah. Untuk membuat tautan dengan lalu lintas satu arah, Anda dapat menonaktifkan nilai ini. Nilai
Activated digunakan sesuai dengan namanya. Jika salah, agen mengabaikan hubungan ini. Anda dapat menghidupkan dan mematikannya untuk membuat skenario permainan di mana, misalnya, pemain harus menekan sakelar untuk mengaktifkan koneksi.
Untuk mengaktifkan hubungan ini, memanggang ulang tidak diperlukan. Lihatlah NavMesh Anda dan Anda akan melihat bahwa tampilannya persis seperti pada tangkapan layar:
Seperti yang Anda lihat, celah yang lebih kecil masih terhubung secara otomatis, dan sekarang kami memiliki koneksi baru yang dihasilkan oleh komponen
Off Mesh Link antara dua bola. Luncurkan mode Putar dan klik pada platform jauh. Seperti yang diharapkan, agen sekarang dapat menavigasi ke platform terputus:
Di level gim Anda, Anda mungkin perlu mengubah parameter ini untuk mencapai hasil yang diinginkan, tetapi kombinasi fitur-fitur ini memberi Anda alat yang nyaman dan siap pakai. Anda dapat dengan cepat membuat game sederhana menggunakan fungsionalitas NavMesh.
Tutorial ini adalah bagian dari Pemrograman AI Game Unity 2017 - Edisi Ketiga oleh Ray Barrera, Aung Sithu Kyaw dan Thet Naing Swe.