Saya cukup baru dengan gagasan sistem entitas, setelah membaca banyak hal (yang paling bermanfaat, blog yang hebat ini dan jawaban ini ).
Meskipun saya mengalami sedikit kesulitan memahami bagaimana sesuatu yang sederhana seperti mampu memanipulasi posisi suatu objek oleh sejumlah sumber yang tidak ditentukan.
Artinya, saya memiliki entitas saya, yang memiliki komponen posisi. Saya kemudian memiliki beberapa peristiwa dalam permainan yang memberitahu entitas ini untuk bergerak jarak tertentu, dalam waktu tertentu.
Peristiwa ini dapat terjadi kapan saja, dan akan memiliki nilai yang berbeda untuk posisi dan waktu. Hasilnya adalah mereka dipersatukan.
Dalam solusi OO tradisional, saya akan memiliki semacam MoveBy
kelas, yang berisi jarak / waktu, dan array yang ada di dalam kelas objek permainan saya. Setiap frame, saya akan mengulangi semua MoveBy
, dan menerapkannya pada posisi. Jika a MoveBy
telah mencapai waktu selesai, hapus dari array.
Dengan sistem entitas, saya sedikit bingung bagaimana saya harus meniru perilaku semacam ini.
Jika ada satu saja pada satu waktu, alih-alih dapat menggabungkan mereka, itu akan sangat mudah (saya percaya) dan terlihat seperti ini:
PositionComponent
mengandung x, y
MoveByComponent
mengandung x, y, time
Entity
yang memiliki a PositionComponent
dan aMoveByComponent
MoveBySystem
yang mencari entitas dengan kedua komponen ini, dan menambahkan nilai MoveByComponent
ke PositionComponent
. Ketika time
tercapai, itu menghapus komponen dari entitas itu.
Saya agak bingung bagaimana saya akan melakukan hal yang sama dengan banyak yang pindah.
Pikiran awal saya adalah bahwa saya akan memiliki:
PositionComponent
, MoveByComponent
sama seperti di atas
MoveByCollectionComponent
yang berisi larik MoveByComponent
s
MoveByCollectionSystem
yang mencari entitas dengan a PositionComponent
dan a MoveByCollectionComponent
, beriterasi melalui huruf MoveByComponent
s di dalamnya, menerapkan / menghapus seperlunya.
Saya kira ini adalah masalah yang lebih umum, memiliki banyak komponen yang sama, dan menginginkan sistem yang sesuai untuk bertindak masing-masing. Entitas saya mengandung komponen mereka di dalam tipe komponen hash -> komponen, jadi hanya memiliki 1 komponen tipe tertentu per entitas.
Apakah ini cara yang tepat untuk melihat ini?
Haruskah entitas hanya memiliki satu komponen dari tipe tertentu setiap saat?
MoveBy
fungsionalitas adalah jenis hanya kecepatan? Sepertinya Anda berada di jalur yang benar. Untuk pertanyaan kedua Anda, ada banyak implementasi sistem entitas / komponen yang berbeda. Yang dijelaskan dalam jawaban saya yang Anda tautkan hanya akan memiliki satu komponen dari jenis yang diberikan.move x by 10 in 2 seconds
danmove x by -10 in 2 seconds
entitas akan berdiri diam?Jawaban:
Untuk skenario Anda, kami biasanya menambahkan tiga komponen ke objek game:
Ketika objek game membutuhkan beberapa jenis fungsi AI seperti bergerak di sepanjang jalur seperti yang Anda jelaskan, kami menetapkan AIController ke daftar komponennya. AIControllers benar-benar tidak lebih dari pembungkus yang menginjak Pohon Perilaku. Pohon perilaku adalah tempat kami merancang fungsionalitas aktual yang kami inginkan agar objek permainan berkinerja seperti:
Subsistem AI mengelola AIControllers dan sehingga subsistem mencentang controller yang pada gilirannya langkah Pohon Perilaku. MoveToNode () melihat posisi / orientasi saat ini, menghitung vektor arah dan kecepatan ke tempat Anda ingin pindah berdasarkan argumen konstruktornya dan menetapkan nilai pada komponen kecepatan. Sistem gerakan bertanggung jawab untuk membaca komponen gerakan dengan nilai-nilai dan menerapkan fisika sehingga memperbarui posisi / orientasi yang sesuai.
Kode di atas hanya memindahkan objek game dari lokasi spawn ke x, y, z di ruang dunia, lalu menunggu minimal 30 detik, lalu memindahkan objek game ke lokasi a, b, c dan kemudian menunggu 30 detik lagi. Setelah menunggu selesai, urutan perilaku telah selesai, sehingga berulang dari awal.
Ini memungkinkan Anda untuk dengan mudah menentukan fungsionalitas AI apa pun yang Anda perlukan semua yang terdapat dalam subsistem AI dengan dampak minimal pada subsistem Entitas Anda. Hal ini juga memungkinkan Anda untuk menjaga daftar komponen sistem entitas Anda tanpa terlalu banyak rincian.
sumber
Sebuah opsi adalah menambahkan pengontrol ke desain Anda. Entitas memiliki data untuk mewakili posisi (dalam kasus mesin saya, mereka memiliki data yang mengingat posisi sebelumnya juga, jadi saya dapat mengetahui vektor kecepatan dan jika mereka dipindahkan atau dipindahkan), tetapi mereka tidak tahu apa-apa tentang fisika atau AI. Pengontrol memindahkan entitas dan Anda dapat memiliki banyak pengontrol yang memengaruhi entitas yang sama atau satu pengontrol yang memengaruhi berbagai entitas.
Misalnya: buat kelas Pengontrol dasar dengan metode run (), atau jika Anda tidak suka nama panggilannya think (), perbarui () atau centang (). Kemudian Anda mewarisinya dan membuat MoveController, NPCController, PlayerInputController (untuk entitas pemain), PhysicController; kemudian Anda menerapkan metode run (). Saya akan meletakkan MoveByComponent Anda di MoveController dan bukan di Entity.
Pengontrol ini dapat dipakai oleh setiap Entitas jika mereka memegang data spesifik Entitas. Mereka dapat dihancurkan atau diatur ulang untuk digunakan kembali. Anda juga dapat menggunakan Kontroler untuk memindahkan grup entitas, dalam game RTE misalnya, jika Anda perlu memindahkan berbagai unit sebagai grup, memiliki controller dengan setiap unit dapat merusak kinerja game, maka Anda dapat dengan mudah menetapkan semua unit ke GroupController atau LegionController dan biarkan memindahkan unit sebagai bagian dari grup terorganisir. Saat bertarung, jika gim memungkinkan perilaku unit individu, dan mungkin sebagian besar gim melakukannya, Anda harus beralih ke UnitController tetapi lebih baik melakukannya hanya saat dibutuhkan daripada sejak awal.
Dalam permainan saya yang sedang berkembang, saya memiliki MoveController yang memindahkan entitas mengikuti jalur, satu MoveController ada untuk setiap NPC dan karakter pemain. Kadang-kadang satu dibuat untuk kotak atau batu yang pemain bisa dorong. PhysicController, hanya satu contoh, yang akan memeriksa posisi semua entitas yang ditugaskan padanya, jika beberapa entitas bertabrakan dengan entitas lain yang ditugaskan, posisi yang dihasilkan dari keduanya dihitung (sebenarnya lebih dari itu tetapi Anda mendapatkan ide). NPCController adalah AI, satu instance per NPC. Ia memeriksa situasi NPC dan memutuskan ke mana harus bergerak, lalu mendorong path ke MoveController, yang benar-benar menggerakkan NPC. Pengendali memiliki prioritas, jadi saya dapat menentukan terlebih dahulu pesanan mereka, PhysicController adalah yang terakhir dijalankan.
Saya menganjurkan untuk pengontrol tetapi bukan satu-satunya pilihan "benar". Misalnya saya ingat antarmuka Entity di mesin Cafu yang memiliki metode think () di Entity itu sendiri, pengguna kelas harus mewarisi dari Entity dan mengimplementasikan think (), saya ingat kelas turunan yang disebut CompanyBot (yang datang dengan contoh game) yang melakukan beberapa pemeriksaan tabrakan dalam metode itu, seperti yang disebut "think" kita dapat mengasumsikan kode AI diharapkan juga ada di sana. Sementara mesin NeoAxis (terakhir kali saya melihatnya) memiliki AI dan fisika yang terpisah dari entitas.
Ada pola Pengendali yang saya dengarkan. Mungkin Anda harus mencarinya, dan itu mungkin bukan yang saya bicarakan di sini, tetapi kedengarannya juga solusi yang bagus.
sumber