Saya sedang menulis mesin permainan yang terdiri dari beberapa modul. Dua di antaranya adalah mesin grafis dan mesin fisika .
Saya ingin tahu apakah ini solusi yang baik untuk berbagi data di antara mereka?
Dua cara (berbagi atau tidak) terlihat seperti itu:
Tanpa berbagi data
GraphicsModel{
//some common for graphics and physics data like position
//some only graphic data
//like textures and detailed model's verticles that physics doesn't need
};
PhysicsModel{
//some common for graphics and physics data like position
//some only physics data
//usually my physics data contains A LOT more informations than graphics data
}
engine3D->createModel3D(...);
physicsEngine->createModel3D(...);
//connect graphics and physics data
//e.g. update graphics model's position when physics model's position will change
Saya melihat dua masalah utama:
- Banyak data yang berlebihan (seperti dua posisi untuk data fisika dan grafik)
- Masalah dengan memperbarui data (saya harus memperbarui data grafik secara manual ketika data fisika berubah)
Dengan berbagi data
Model{
//some common for graphics and physics data like position
};
GraphicModel : public Model{
//some only graphics data
//like textures and detailed model's verticles that physics doesn't need
};
PhysicsModel : public Model{
//some only physics data
//usually my physics data contains A LOT more informations than graphics data
}
model = engine3D->createModel3D(...);
physicsEngine->assingModel3D(&model); //will cast to
//PhysicsModel for it's purposes??
//when physics changes anything (like position) in model
//(which it treats like PhysicsModel), the position for graphics data
//will change as well (because it's the same model)
Masalah di sini:
- physicsEngine tidak dapat membuat objek baru, hanya "mengasumsikan" yang sudah ada dari engine3D (entah bagaimana itu terlihat lebih anti-independen untuk saya)
- Casting data dalam fungsi assingModel3D
- physicsEngine dan graphicsEngine harus berhati-hati - mereka tidak dapat menghapus data saat mereka tidak membutuhkannya (karena yang kedua mungkin membutuhkannya). Tapi ini situasi yang langka. Selain itu, mereka hanya dapat menghapus pointer, bukan objek. Atau kita dapat mengasumsikan bahwa graphicsEngine akan menghapus objek, physicsEngine hanya menunjuk ke mereka.
Jalan mana yang lebih baik?
Mana yang akan menghasilkan lebih banyak masalah di masa depan?
Saya lebih suka solusi kedua, tapi saya bertanya-tanya mengapa sebagian besar mesin grafis dan fisika lebih suka yang pertama (mungkin karena mereka biasanya hanya membuat grafik atau hanya mesin fisika dan orang lain menghubungkannya dalam permainan?).
Apakah mereka memiliki pro & kontra yang tersembunyi lagi?
physics
architecture
graphics
PolGraphic
sumber
sumber
Jawaban:
Saat ini, lebih banyak mesin game mengadopsi desain komponen (misalnya Unity, Unreal). Dalam desain semacam ini, a
GameObject
terdiri dari daftar komponen. Dalam situasi Anda, bisa ada aMeshComponent
dan aPhysicalComponent
, keduanya menempel pada satu objek game.Untuk mempermudah, Anda bisa meletakkan variabel transformasi dunia ke
GameObject
. Selama frasa pembaruan,PhysicalComponent
output dunia berubah ke variabel itu. Selama rendering,MeshComponent
membaca variabel itu.Alasan di balik desain ini adalah untuk memisahkan antara komponen. Baik
MeshComponent
atauPhysicalComponent
tahu satu sama lain. Mereka hanya tergantung pada antarmuka umum. Dan bisa lebih mudah untuk memperluas sistem dengan komposisi, daripada menggunakan hierarki pewarisan tunggal.Namun, dalam skenario yang realistis, Anda mungkin perlu penanganan yang lebih canggih antara sinkronisasi fisika / grafik. Sebagai contoh, simulasi fisika mungkin perlu dijalankan dalam langkah waktu yang tetap (mis. 30Hz), sementara rendering harus variabel. Dan Anda mungkin perlu menginterpolasi hasil dari output mesin fisika. Beberapa mesin fisika (misalnya Bullet) memiliki dukungan langsung terhadap masalah ini.
Unity memberikan referensi yang baik untuk Komponen mereka , yang patut dilihat.
sumber
Mesin biasanya memilih opsi pertama (memiliki fisika-mesh dan render-mesh sendiri) karena mereka membutuhkan data yang sangat berbeda, baik dalam kualitas maupun kuantitas.
Kualitas karena mesin fisika tidak peduli dengan koordinat tekstur, grup normal dan semua barang mewah ini membuat misalnya. Masing-masing dari mereka mengharapkan data dalam tata letak yang sangat spesifik untuk masalah pelurusan, pengemasan, interleaving data dll.
Kuantitas karena jaring fisika biasanya memiliki segitiga jauh lebih sedikit, ini adalah versi sederhana dari mesh render resolusi tinggi.
Dengan memisahkan keduanya, kami memastikan bahwa kami dapat tweek satu, termasuk mengubah tata letak datanya untuk kinerja yang lebih baik, tanpa merusak yang lain. Itu jauh lebih scalable.
sumber
Selain @Millo Yip jawaban yang bagus Saya hanya ingin mengingatkan Anda bahwa Anda akan perlu berbagi data yang sama dengan modul Kontrol dan modul AI dan jika saya tidak salah sebagian besar perpustakaan audio memiliki gagasan tentang posisi pemancar suara jadi Anda harus berbagi data dengan modul itu juga.
sumber
Seperti yang orang lain katakan, itu adalah tempat yang cukup umum bahwa fisika memiliki keadaan data internal yang dikelola secara terpisah dari keadaan data internal mesin rendering. Seringkali untuk melihat bahkan data transformasi (posisi / orientasi / skala) yang disimpan secara terpisah dari fisika dan renderable karena mungkin saja ada objek permainan yang tidak dipaksakan oleh fisika atau dirender tetapi memerlukan posisi dunia untuk mekanik lain.
Bagaimana data diperoleh dari fisika hingga dapat diulang sepenuhnya terserah Anda.
Anda dapat melakukan ini melalui beberapa proses pengiriman antar subsistem menggunakan peristiwa / pesan. Anda bisa melakukan ini dengan mengekspos antarmuka publik dari subsistem render ke subsistem fisika sehingga fisika dapat dengan mudah mengatur posisi yang dapat di render. Opsi lain adalah bahwa subsistem yang dapat di-render menanyakan entitas untuk transformasi selama pembaruannya dan melakukan pembaruan posisi komponen yang dapat diurai kemudian diikuti dengan menggambar.
Tentu saja, tergantung pada gim Anda, beberapa cara ini akan menjadi lebih ramah terhadap cache dan memiliki kinerja yang lebih baik daripada yang lain. Saya tidak akan terjebak terlalu banyak pada cara tertentu pada saat ini dan memilih pola komunikasi dan mencobanya. Anda dapat dengan mudah mengerjakan ulang bagian ini nanti untuk menguji berbagai cara untuk optimasi.
sumber