Desain berbasis komponen / Entitas + Pohon Perilaku => bagaimana cara mengintegrasikan?

9

Untuk proyek saya saat ini, saya menerapkan sistem berbasis komponen / entitas , pada dasarnya mengikuti sebagian besar praktik terbaik yang ada di area yang agak tidak ditentukan ini .

Jadi saya mendapat Entitas (sedikit diperluas) , yang pada dasarnya adalah intID, Nama yang dapat dibaca manusia, std::mapkomponen dan long"indikator tipe" yang digunakan untuk menunjukkan komponen apa yang ada (Saya memiliki kekuatan dua enumuntuk semua komponen jenis dan setiap kali komponen ditambahkan ke Entitas, saya secara otomatis mengubah panjang melalui operasi bitwise, bandingkan jawaban ini ).

Lalu ada Komponen , juga agak sederhana: intID, enumsebagai tipe komponen, induk Entity pointer dan std::mapsemua properti yang dimiliki oleh komponen ini.

Terakhir, beberapa Sistem / Manajer yang menangani pemrosesan logika aktual. Mereka pertama-tama memeriksa apakah Entitas yang saat ini diproses memiliki long"jenis indikator" yang cocok = semua komponen yang diperlukan untuk sistem itu ada. Kemudian mengakses beberapa properti jika diperlukan dan langsung memanggil beberapa fungsi dalam komponen masing-masing atau mengirim beberapa pesan (melalui operator pesan).

Intinya: Sampai di sini, sistem berbasis komponen / entitas berbasis peristiwa yang agak standar digabungkan dengan pendekatan berbasis data (bandingkan, komponen tidak memiliki variabel data hard-coded, melainkan peta generik, seperti (beberapa) komponen / arketipe komponen nantinya akan dibaca dari file dengan opsi untuk menambahkan data tambahan, yang bukan bagian dari kode komponen yang sebenarnya.

Sekarang saya ingin juga memperkenalkan Behavior Trees (berdasarkan AiGameDev BTSK ) ke dalam proyek itu, tetapi saya tidak yakin apakah dan bagaimana mereka harus dikaitkan dengan komponen yang sudah ada atau bagaimana mengintegrasikan desain tersebut secara umum.

Beberapa ide / poin / pertanyaan terkait muncul di benak Anda:

  1. BT saya akan dibaca dari file (lagi). Saat ini saya kesulitan melihat bagaimana cara terbaik untuk membuat koneksi antara BT Actionpohon di dan pengkodean yang sebenarnya dalam aplikasi saya. Haruskah saya membangun semacam peta antara nama tindakan yang digunakan dalam file BT dan penunjuk fungsi ke implementasi logika yang sebenarnya? Apa pendekatan yang biasa untuk menyelesaikannya?

  2. Saya berasumsi bahwa saya harus membuat BT untuk semua Entitytipe saya yang berbeda (jadi untuk setiap kombinasi komponen game-logic / AI-relevan seperti yang ditunjukkan oleh beberapa kali "indikator tipe" saya yang panjang). Akibatnya tidak masuk akal untuk meletakkan BT Actionimplementasi dalam komponen karena kemungkinan besar banyak komponen akan terlibat per tindakan, bukan?

  3. Jadi haruskah BT Actionlogika duduk di / beberapa sistem yang terpisah (ke metode siapa peta dari ide # 1 menunjuk)? Sistem kemudian akan memeriksa per long"indikator jenis" saya apakah EntityBT yang saat ini diperiksa dan yang disuruh melakukan tindakan tertentu (= metode dalam sistem) sebenarnya diizinkan untuk melakukannya (= memiliki komponen yang diperlukan). Tapi kemudian, jika tidak (karena misalnya pencipta BT memang mengabaikan situasi tertentu, di mana komponen yang diperlukan mungkin tidak melekat pada Entity saat runtime lagi), tidak ada yang akan terjadi.

Pertanyaan:

  • Adakah konsep yang terbukti untuk integrasi semacam itu?
  • Apa pendapat Anda tentang 3 poin saya di atas?
  • Adakah hal lain yang terlintas dalam pikiran saya, juga mengenai desain berbasis komponen / entitas saya secara umum?
Philip Allgaier
sumber
Poin 1: Pohon perilaku tidak lebih dari DSL visual yang digunakan sebagian besar untuk membuat perilaku karakter. Komponen BehaviorTree tidak boleh melakukan apa pun lebih atau sesuatu yang kurang dari komponen Script lakukan Poin 3: Apa alasan menggunakan peta di atas bidang biasa?
Eric
# 1: Apa artinya "DSL" dalam konteks ini? # 3: Maaf, tapi saya tidak bisa mengikuti Anda tentang ini. Mau jelaskan tolong apa maksudmu?
Philip Allgaier
1
mungkin Domain Specific Language, yaitu. sintaks khusus untuk bekerja dengan masalah yang sangat spesifik.
Patrick Hughes
Patrick benar, meskipun semantik juga merupakan bagian darinya dan "sangat" dapat dihapus dari definisi ini. - Png 3: Permintaan maaf saya, harus berbunyi: "Apa alasan menggunakan peta di atas bidang biasa dalam komponen ?"
Eric
Re 3: Saya ingin kemampuan untuk menentukan secara dinamis properti tambahan di luar kode C ++ (kata kunci: data-driven). Demi kesederhanaan, saya (setidaknya untuk saat ini) meletakkan semua properti dalam kerangka umum ini (menggunakan peta), bahkan yang diperbaiki dalam kode dan karenanya bisa menjadi bidang C ++ nyata. Mungkin harus meninjau kembali nanti, jika itu menjadi masalah kinerja ...
Philip Allgaier

Jawaban:

2

Saat ini saya kesulitan melihat bagaimana cara terbaik untuk membuat koneksi antara Aksi BT di pohon itu dan pengkodean aktual dalam aplikasi saya. Haruskah saya membangun semacam peta antara nama tindakan yang digunakan dalam file BT dan penunjuk fungsi ke implementasi logika yang sebenarnya? Apa pendekatan yang biasa untuk menyelesaikannya?

Lupakan pointer fungsi dan pikirkan objek. Setiap node di pohon perilaku (BT sejak saat ini) idealnya sesuai dengan satu objek dalam kode Anda. Objek-objek itu akan memiliki antarmuka standar untuk memungkinkan Anda mengaturnya sebagai pohon dan untuk melintasi mereka. Seperangkat pointer fungsi tidak masalah untuk perilaku tersebut tetapi tidak menangkap struktur pohon Anda sama sekali.

Akibatnya tidak masuk akal untuk menempatkan implementasi Aksi BT dalam komponen karena kemungkinan besar banyak komponen akan terlibat per tindakan, bukan?

Saya berharap entitas memiliki komponen BehaviorTree tunggal yang menyimpan data yang relevan untuk BT entitas itu. Eksekusi BT dilakukan oleh Komponen BT atau Subsistem BT tergantung pada bagaimana Anda menangani komponen dalam sistem Anda. Seperti halnya apa pun yang menggunakan komponen, mereka harus merujuk ke komponen lain untuk menyelesaikan pekerjaan, tetapi komponen lain itu tidak perlu tahu apa-apa tentang BT.

Berbagai tindakan yang tersedia akan, pada tingkat paling sederhana, dikodekan ke berbagai objek simpul BT. Mereka harus dapat membuat entitas yang relevan bertindak dengan memanipulasi komponen yang diperlukan, misalnya. mengakses komponen gerakan untuk bergerak.

Kylotan
sumber
Paragraf # 1: Ya, BT itu sendiri akan menjadi objek (seperti yang saya katakan seperti versi dari AiGameDev). Saya hanya berpikir tentang functors untuk tindakan sendiri, tetapi ayat Anda 2 mengubah itu. Untuk beberapa alasan, pendekatan yang sangat sederhana ini tidak pernah terpikir oleh saya (Entity memiliki instance anggota BT sendiri). Mungkin karena hal komponen yang sama sekali baru, saya tidak berpikir lurus dan sederhana lagi, jadi saya sedang mencari cara untuk mencampur komponen dengan barang-barang BT, tetapi itu tidak diperlukan memang.
Philip Allgaier
Hal utama yang hilang pada saya sebelumnya, adalah bagaimana menghubungkan tindakan dengan entitas. Sekarang sudah jelas: Tindakan tahu entitas mana melalui pohonnya yang pada gilirannya mengetahui entitas miliknya.
Philip Allgaier
@ Philip Allgaier Saya ingin tahu, bagaimana akhirnya Anda membuat BT node? Apakah Anda membuatnya sebagai 1 node perilaku = 1 entitas (yang akan menjadi banyak entitas per 1 objek game), atau membuat node sebagai kelas normal (tidak terkait ECS), atau menggunakan pendekatan lain? Terima kasih!
cppBeginner