Sistem Komponen Entitas - Bagaimana mengimplementasikan Transform objek?


11

Dalam merancang sistem entitas-komponen untuk mesin saya, saya telah menemukan sedikit hambatan dalam cara menyimpan dan mengambil jenis komponen tertentu.

Pertama, izinkan saya mengatur sedikit terminologi yang akan saya gunakan dalam pertanyaan ini:

  • Saya menyebut " Komponen " struktur data yang menyimpan data yang relevan untuk sistem tertentu.
  • Saya menyebut " Sistem " agregasi metode dan struktur data yang memanfaatkan Komponen untuk memperbarui status permainan / antarmuka dengan pengguna.
  • " Entity " pada dasarnya hanya ID yang digunakan untuk mengambil komponen tertentu dan memodifikasi data mereka dalam logika game.

Setiap sistem memiliki larik (ID-dipetakan) dari jenis Komponennya (Misalnya Fisika-> Komponen Fisika, AI-> Komponen A, komponen- Render-> RenderingKomponen), sehingga dapat beralih secara efisien melalui data.

Namun, tidak semua komponen dimiliki secara khusus oleh suatu sistem. Misalnya, komponen Transform menyimpan posisi, rotasi, dan skala objek. Ini adalah salah satu bagian terpenting dari sebuah entitas (Unity membuatnya wajib, bahkan), karena digunakan oleh banyak sistem, misalnya Fisika, AI, Rendering dll.

Ini cukup banyak masalah yang saya hadapi. Karena Transform digunakan oleh banyak sistem lain, bagaimana cara saya mengambil satu untuk digunakan untuk setiap Komponen? Salah satu solusi yang mungkin saya lihat adalah membuat setiap Komponen menyimpan ID Entitasnya sendiri. Akan mudah untuk mengambil komponen seperti ini, tetapi tidak akan seefisien itu, dan itu juga akan bertentangan dengan konsep Komponen sebagai kumpulan data yang terisolasi dan independen, yang tidak mengetahui komponen lainnya.

Apakah ada cara yang tepat untuk menyelesaikan masalah ini? Haruskah Transform bahkan menjadi komponen?


3
+1 untuk "Pertama, izinkan saya menjernihkan sedikit terminologi yang akan saya gunakan dalam pertanyaan ini:"
Vaillancourt

Saya akan senang melihat pertanyaan jenis ini lebih banyak di situs ini. +1
S. Tarık Çetin

Simpan saja semua komponen sebagai variabel global
Miles Rout

Jawaban:


2

Ini adalah pertanyaan yang cukup luas, jawabannya, sangat tergantung pada arsitektur Anda. Namun, saya akan berusaha memberi Anda jawaban umum.

Fisika dan sistem rendering Anda tentu membutuhkan transformasi, namun, sistem AI tidak akan melakukannya. Oleh karena itu, masuk akal untuk merangkum transformasi ke kelas komponen itu sendiri. Semua sistem yang tertarik tersebut akan menggunakan data yang sama, oleh karena itu, masuk akal bagi entitas untuk memiliki pointer ke objek transformasi, atau id untuk objek transformasi yang disimpan di tempat lain.

Jika Anda memilih solusi yang terakhir, maka setiap sistem yang tertarik pada transformasi akan memerlukan akses ke mana pun objek transformasi disimpan.

Jika Anda memilih yang pertama, maka yang perlu dilakukan setiap sistem adalah mengakses entitas itu sendiri, dan meminta transformasi.

Dalam kasus sebelumnya, masalahnya menjadi bagaimana memberikan akses ke penyimpanan untuk transformasi ke setiap sistem, tanpa melanggar aturan OOP, jika Anda peduli tentang hal-hal seperti itu.

Kasing terakhir tidak memiliki masalah seperti itu, tetapi membutuhkan perubahan desain objek entitas Anda untuk menyimpan pointer ke objek daripada id objek komponen.

Preferensi pribadi saya adalah merancang kelas entitas untuk menyimpan pointer ke objek komponen, karena menyederhanakan banyak masalah desain. Dengan cara ini, setiap sistem yang membutuhkan transformasi dapat memintanya dari entitas, dan mengabaikannya jika tidak. Namun, ini membawa overhead komputasi yang melekat pada pointer, yang menjadi biaya cache gagal.

Lihat Ikhtisar ECS ini untuk informasi lebih lanjut tentang ini.

Pada akhirnya, terserah Anda untuk memutuskan mana yang lebih penting bagi Anda: kemudahan pengembangan, atau kinerja.

Saya akan menunjukkan, akhirnya, bahwa pertanyaan Anda adalah contoh yang sangat baik dari pertanyaan desain yang dipikirkan oleh para pendukung ECS, dan tidak ada solusi peluru perak yang pasti.


Terima kasih atas saran Anda. Saya punya pertanyaan, mengapa: mengapa sistem AI tidak membutuhkan posisi objek?
CRefice

Anda membingungkan posisi (vektor 3 mengapung) dengan Terjemahan (mengubah matriks yang dibangun dari vektor posisi). Matriks Transformasi dibuat dari transformasi translasi, rotasi, dan skala. Ini adalah informasi yang jauh lebih banyak daripada yang dibutuhkan oleh sistem AI, meskipun Anda tentu dapat mengekstraksi vektor posisi darinya. Namun secara pribadi, saya akan memisahkan posisi, orientasi, dan ukuran ke dalam komponen mereka sendiri, dan menggunakannya untuk membuat dan memperbarui Transform.
Ian Young

@IanYoung Memisahkan mereka bisa lebih berbahaya daripada baik, berpotensi jika Anda menemukan Anda membutuhkan posisi dan orientasi bersama lebih sering daripada Anda melakukan posisi atau orientasi secara terpisah. Dalam hal ini, menempatkan atribut data posisi dan orientasi dalam satu komponen dapat meningkatkan kinerja cache.
Naros

1
Preferensi saya adalah menggabungkan ketiganya, posisi, orientasi, dan skala ke dalam satu komponen tunggal dan dalam kasus di mana subsystsem tertentu hanya membutuhkan posisi atau orientasi, saya akan menganjurkan menduplikasi data dan menyinkronkannya pada titik-titik yang jelas dalam loop permainan. .
Naros

@Naros ya ini yang saya maksud: Dua Komponen, Transform, dan (dalam kerangka saya) SpatialData, yang berisi posisi, kecepatan, orientasi, dan kecepatan sudut. Posisi dan orientasi digunakan untuk membuat dan memperbarui Transform.
Ian Young
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.