Struktur unit game RTS

18

Saya ingin cara untuk membuat banyak unit berbeda tanpa harus memprogram hal-hal seperti tindakan moveTo dan Attack lebih dari sekali

Cara saya melihatnya, ada 2 cara saya bisa melakukan ini.

  1. Kelas Unit generik tunggal dengan flag yang menentukan apa yang bisa / tidak bisa dilakukan (kemudian buat instance dalam array statis dan ambil ketika diperlukan)
  2. Abstrak unit class dengan metode abstrak untuk aksi spesifik Unit seperti (Attack, Harvest, Patrol), yang kemudian semua perlu diimplementasikan dalam subclass , bahkan jika unit tidak dapat benar-benar memanen apa pun.

cara pertama melakukan ini tampaknya yang paling sederhana, tetapi saya akan berakhir memiliki banyak kode yang tidak digunakan untuk sebagian besar unit.

cara kedua juga bisa berhasil. Tetapi jika saya memutuskan untuk memiliki dua unit berbeda yang dapat memanen sumber daya, saya akan memiliki kode yang sama persis di dua kelas yang berbeda, yang sepertinya bukan cara yang tepat untuk melakukannya.

Apakah ini bahkan pendekatan yang tepat untuk masalah ini?
Dalam permainan seperti AoE, setiap unit memiliki, apa yang saya anggap adalah, semacam Daftar Tindakan / Pesanan, saya benar-benar ingin tahu bagaimana mencapai sesuatu yang mirip dengan itu, di mana saya bisa mengkodekan setiap Aksi / Pesanan satu kali, dan kemudian berikan ke semua unit yang perlu diucapkan Action.

Jika saya tidak jelas (sangat masuk akal) atau Anda memerlukan informasi lebih lanjut tentang apa yang sebenarnya saya cari, tanyakan saja kepada saya dalam komentar.

Daniel Holst
sumber

Jawaban:

25

Pendekatan yang umum adalah memiliki pendekatan berbasis komponen di mana "Unit" kelas dasar hanya mengimplementasikan aspek yang paling mendasar yang dimiliki semua unit, sementara setiap unit kemudian memiliki daftar beberapa objek-objek yang mengatakan apa yang dapat dilakukan dan bagaimana cara melakukannya.

Sebagai contoh, sebuah tangki mungkin memiliki komponen Mobile, Destructible, Attacker, sebuah bergerak turret hanya Destructible, Attackerdan harvester Mobile, Destructible, Harvester. Kelas-kelas ini kemudian akan mencakup semua kode yang diperlukan untuk menerapkan perilaku ini. Interaksi antara komponen ( Attackerhanya dapat merusak apa yang ada Destructible) dapat diimplementasikan dengan meminta komponen memeriksa apakah unit lain memiliki komponen yang diperlukan dan kemudian berinteraksi dengan komponen itu secara langsung.

Keuntungan lebih dari warisan kelas klasik adalah bahwa Anda dapat dengan mudah menggabungkan kemampuan. Misalnya, ketika Anda ingin memiliki pemanen yang juga dapat menyerang, mengangkut infanteri dan terbang, Anda hanya perlu menambahkan komponen yang diperlukan. Anda juga dapat dengan mudah menambah dan menghapus fitur baru dalam bentuk komponen baru tanpa harus mengasapi kelas Unit dasar.

Unity mendukung Anda dalam arsitektur seperti itu, karena seluruh mesin sudah berbasis komponen. Jadi komponen game-logis seperti ini dapat ditambahkan dalam bentuk skrip.

Philipp
sumber
Jadi dalam kesatuan, apakah saya kemudian akan menonaktifkan dan mengaktifkan komponen sesuai kebutuhan ?.
Daniel Holst
@DanielHolst Tidak, Anda akan menambah dan menghapusnya sesuai kebutuhan. Anda dapat melakukannya di editor Persatuan atau dengan skrip menggunakan gameObject.AddComponentdan gameObject.RemoveComponent.
Philipp
ah oke, tapi katakan untuk tindakan / perintah "moveTo". bagaimana unit akan tahu kapan pesanan dilakukan ?, dan bagaimana saya akan mengantri pesanan?
Daniel Holst
2
@DanielHolst, saya pikir Anda salah mengerti sesuatu. The Movingberarti komponen "unit ini umumnya mampu gerakan". Komponen terpasang secara permanen padanya, terlepas dari apakah unit bergerak atau tidak. Itu tidak berarti bergerak sekarang . Meskipun Anda juga bisa melakukannya dengan cara menambahkan MoveOrderkomponen ke dalamnya dan meminta komponen itu menghapus sendiri dari unit ketika pesanan dipenuhi atau dibatalkan.
Philipp
1
@DanielHolst Sekarang Anda hanyut ke arah unit AI, yang merupakan kaleng cacing lainnya. Suatu pendekatan yang mungkin adalah memiliki perpustakaan komponen AIScript yang mengasumsikan bahwa komponen tertentu ada atau mengubah perilaku mereka tergantung pada komponen apa yang dimiliki unit. Tapi itu benar-benar topik yang terlalu rumit untuk ditangani dalam komentar.
Philipp
4

Banyak gim menggunakan sistem berbasis komponen untuk entitas yang merupakan tempat sekelompok perilaku dan kemampuan dapat ditambahkan ke tipe unit yang lebih umum daripada dikodekan sebagai bagian dari kelas entitas (atau yang setara).

Ross Taylor-Turner
sumber
apakah ini akan sangat sulit untuk diterapkan?
Daniel Holst
Pola seperti ini digunakan untuk membuat implementasi lebih mudah secara keseluruhan. Jika Anda tidak dapat memutuskan pendekatan apa yang harus diambil, adalah ide yang baik untuk memulai sesederhana mungkin dan menumbuhkan pilihan Anda saat Anda memiliki lebih banyak fungsi. Setelah Anda memiliki lebih banyak rasa untuk masalah, Anda bisa refactor atau menulis ulang untuk pendekatan yang lebih sesuai dengan situasi Anda.
Ross Taylor-Turner
1
@DanielHolst Saya melihat pertanyaan Anda memiliki Unitybendera. Unity sudah memiliki sistem komponen bawaan, dan sangat menyukai komposisi daripada warisan . Salah satu metode langsung adalah membuat MonoBehaviouruntuk masing-masing jenis tindakan Anda, kemudian melampirkan ke setiap jenis unit cetakan tindakan yang dapat dilakukan (menyesuaikan contoh tindakan dengan detail per-jenis seperti nilai & biaya kerusakan). Ini membuat data unit Anda tetap digerakkan, sehingga Anda dapat dengan mudah membuat banyak tipe unit kustom.
DMGregory
@DanielHolst Itu tergantung pada definisi Anda tentang "sangat sulit". Jawaban saya menjelaskan lebih detail tentang bagaimana ini bisa diterapkan.
Philipp