Banyak sumber pergerakan dalam sistem entitas

9

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 MoveBykelas, 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 MoveBytelah 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

Entityyang memiliki a PositionComponentdan aMoveByComponent

MoveBySystemyang mencari entitas dengan kedua komponen ini, dan menambahkan nilai MoveByComponentke PositionComponent. Ketika timetercapai, 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, MoveByComponentsama seperti di atas

MoveByCollectionComponentyang berisi larik MoveByComponents

MoveByCollectionSystemyang mencari entitas dengan a PositionComponentdan a MoveByCollectionComponent, beriterasi melalui huruf MoveByComponents 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.

  1. Apakah ini cara yang tepat untuk melihat ini?

  2. Haruskah entitas hanya memiliki satu komponen dari tipe tertentu setiap saat?

Lengket
sumber
1
Kedengarannya seperti MoveByfungsionalitas 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.
MichaelHouse
Agak, tetapi perbedaannya adalah bahwa kecepatan ini hanya berlaku dari satu waktu ke waktu lain, dan banyak dari mereka dapat disatukan bersamaan. Saya pikir saya hanya perlu sedikit jaminan, saya sudah ketat (anal, hampir) OO untuk permainan saya di masa lalu - yang bertahun-tahun kemudian pada proyek yang sama, telah melumpuhkan kecepatan produksi kami - dan ini adalah wilayah yang tidak dikenal;) . Jawaban bagus di pos yang lain, membantu menjernihkan beberapa hal
Sticky
Saya melakukannya seperti ini: Saya memiliki PlayerInputComponent dan AIInputComponent (atau sistem) yang akan memberi tahu MobileBehaviorComponent bahwa pada klik keyboard atau pada AI berpikir bahwa ponsel harus pindah ke suatu tempat, MobileBehaviorComponent akan menyimpan bahwa ia harus pindah ke suatu tempat (memiliki FSM di dalamnya untuk tindakan mobile) dan beberapa sistem akan memindahkannya. Granularity Anda terlalu banyak, dengan komponen tingkat yang lebih tinggi, seperti Transform, Model, Light, Mob semuanya bekerja dengan baik. Juga saya tidak pernah perlu menghapus komponen - saya menganggapnya lebih seperti sesuatu yang menggambarkan objek game sehingga tidak bisa hilang begitu saja.
Kikaimaru
Contoh MoveBy khusus ini hanyalah sebuah contoh. Pertanyaannya lebih tentang bagaimana Anda menggabungkan hal-hal seperti itu. Jika saya perlu secara spesifik mengatakan 'bergerak x = 5 dan y = 6 dalam 5 detik' 'pindah x = 10 y = 2 dalam 10 detik', pada saat yang sama, apakah ini yang akan saya lakukan?
Sticky
Apa yang Anda maksud dengan "digabungkan bersama"? Suka menambahkan kecepatan? Jadi, jika Anda majemuk move x by 10 in 2 secondsdan move x by -10 in 2 secondsentitas akan berdiri diam?
Tom Dalling

Jawaban:

6

Untuk skenario Anda, kami biasanya menambahkan tiga komponen ke objek game:

  1. TransformComponent (posisi, orientasi, skala)
  2. VelocityComponent (kecepatan, arah)
  3. Komponen Pengontrol

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:

BehaviorTree* tree(new SequentialNode());
tree->addChild(new MoveToNode(x,y,z));
tree->addChild(new WaitNode(30));
tree->addChild(new MoveToNode(a,b,c));
tree->addChild(new WaitNode(30));
gameObject->addComponent(new AIController(tree));

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.

Naros
sumber
1

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.

Hatoru Hansou
sumber
Itu pada dasarnya desain OO yang sudah kita miliki sekarang. Entity, dengan turunan (Character, Monster) dll., Saya telah memimpin tim kami yang telah mengerjakan game ini secara penuh selama hampir 2 tahun, dan dengan semua orang mengubah hal-hal sesuka hati, itu menjadi mengerikan, mengerikan basis kode - dan mulai memakan waktu lama untuk mendapatkan fitur baru dikirim. Gagasan Sistem Entitas tampaknya persis seperti yang saya cari, jadi sementara jawaban Anda tidak cukup relevan, Anda harus membaca sendiri tautan di bagian atas pertanyaan, lihat apakah mereka dapat membantu Anda :)
Sticky
@Sticky Saya harus mengakui bahwa Node System plus Entity yang terbuat dari komponen adalah cara yang cerdik untuk mewakili sistem yang dibutuhkan berbeda dari pendekatan pengontrol yang saya sarankan yang seperti versi yang kurang berkembang. Anda benar-benar tidak membutuhkan jawaban saya.
Hatoru Hansou
Jangan khawatir. Cara OO memang memiliki kelebihan, tetapi segalanya menjadi jelek, cepat
Sticky