Godot: Tidak ada yang tahu bagaimana Godot bekerja. (Re-MultiScript, node berbasis Re-Class)

Dibuat pada 16 Okt 2018  ·  63Komentar  ·  Sumber: godotengine/godot

Ini lebih merupakan topik informal tetapi ini adalah masalah drastis jika bukan masalah utama Godot.
Tidak ada yang tahu bagaimana para pengembang mesin Godot, merencanakan pengguna yang menggunakannya.

Beberapa masalah terkait: #19486 #7402 #15996 #8502
Ini adalah 4 teratas, tetapi ada banyak yang serupa yang semuanya bertujuan untuk memecahkan masalah yang sama: Semua orang mencari alur kerja yang dapat digunakan.

Hebatnya pengguna Godot telah berhasil membuat alur kerja yang tidak efisien yang menyalin mesin lain yang sudah dikenal. Untuk mendemonstrasikan ini saya akan menggunakan kelas tiruan dari apa MeshInstance , jika dibuat di Godot akan terlihat seperti.


Ada pseudo Unity, alias node anak:


Pengguna Godot menggunakan node anak untuk membuat yang setara dengan MultiScript.

MeshInstance (Spatail + skrip)
--- Jala (Jala + skrip)
--- Material (node ​​+script) - Shader (node ​​+script) - Tekstur (node ​​+script)
--- Transform (Position3D +script)

Pada dasarnya mereka akan menggunakan node dan kode yang paling tepat apa yang mereka butuhkan untuk membuat kelas apa yang mereka inginkan menggunakan skrip.

Masalah:
1.) Ini adalah setara digital menambahkan air dingin ke panci mendidih; itu membantu jangka pendek tetapi menyebabkan lebih banyak kebingungan dalam proyek-proyek yang lebih besar.
2.) Sebagian besar pengguna akhirnya menggunakan sinyal seperti peristiwa, menghubungkannya hanya ke node yang mengirimnya dan menggunakan Ekspor untuk menemukan target.
3.) Acara dapat dicegat sebelum mencapai node yang lebih rendah.
4.) Performanya lambat dan pada sekitar 50.000 objek dapat terhenti saat game mencoba memuat adegan.


Pseudo Unreal, alias pengontrol dan perantara:

Pengguna Godot membuat pengontrol dan node pemilik yang memanipulasi semua anak. Merek dagang dari alur kerja ini adalah kelas yang diturunkan dengan ekstensi.

MeshWithTexturedMaterial.intanced() *hanya simpul di pohon
-> memanjang dari -> MaterialTextured -> memanjang dari -> Material -> memanjang dari -> Shader

Sistem ini membutuhkan perencanaan yang berat, atau Anda akan berakhir dengan kode serupa di banyak kelas. Seperti kelas kamera, karakter, dan kendaraan semua berisi salinan "ikuti target" mereka sendiri
Masalah:
1.) Skrip besar yang berantakan yang sulit untuk di-debug.
2.) Duplikat kode di kelas yang berbeda.
3.) Godot tidak memperlakukan node sebagai kelas; memaksa para pengembang ini untuk secara besar-besaran menyampaikan pada kelas-kelas yang dikodekan sendiri.
4.) Memperpanjang tidak masuk akal, seperti _combat system_ memperluas _weapon system_ dan akhirnya memperpanjang pemain.


Pseudo Panda3D, alias Preload (Script):

Yang ini mereplikasi alur kerja cara kerja sebagian besar mesin berbasis kode. Pengembang sering kali memiliki lebih banyak skrip daripada node.

MeshInstance (Node)
Pramuat (Skrip Mesh)
Pramuat (Skrip Materi)
Pramuat (Transformasi Skrip)

Anehnya pengembang inilah yang menolak untuk meninggalkan GDscript, bahkan ketika C# jelas lebih baik untuk pendekatan ini. Itu sebabnya saya menganggap mereka akrab dengan Python.
Masalah:
1.) Kebingungan tentang bagaimana impor harus dipanggil, karena konstanta mungkin variabel dengan onready; siapa tahu.
2.) Jarang menggunakan node Godot, saya bahkan melihat pengembang mengabaikan alat UI sepenuhnya.
3.) Sulit untuk men-debug karena tidak ada indikasi di mana skrip ditautkan.


skrip WTF:

Meninggalkan yang terbaik untuk yang terakhir. Beberapa developer game Godot telah berhasil membuat game yang bagus menggunakan Signals and Groups.

MeshInstance (Node) yang memiliki node kosong di atasnya memungkinkan pemindahan dan desain ulang anak dengan mudah.
--- Mesh (Mesh +Script || Sinyal)
--- Bahan (Sprite +Script || Sinyal)
--- Transform (Position3D +Script || Sinyal)

Ketika pohon harus menghubungkan objek 2 adegan atau lebih dalam, grup akan digunakan sebagai gantinya. Penting tentang alur kerja ini adalah bagaimana ia memiliki pohon yang dangkal.
Masalah:
1.) Sinyal dan Grup memungkinkan seluruh bagian permainan gagal begitu saja, tanpa peringatan.
2.) Skrip kecil yang tidak berguna hanya berkeliaran. Yang mereka lakukan hanyalah mengirim sinyal dan melacak satu nilai.
3.) Memindahkan objek dengan begitu banyak sinyal yang terpasang membuat frustrasi.
4.) Konflik dengan sistem instance. Karena instance mengalir ke bawah saat sinyal terhubung ke atas.

Ya, saya tahu Godot memiliki kelas MeshInstance .
Hal ini menunjukkan bahwa sebagian besar alur kerja yang digunakan oleh pengembang saat ini dapat membuat kelas serumit MeshInstance dengan multi komponen; kecuali setiap alur kerja sangat cacat.

Semua alur kerja ini memiliki masalah inti yang sama. Mereka adalah solusi jangka pendek untuk mengembangkan game.
Tak satu pun dari mereka menskala dengan baik dan debug cacat di semuanya.

Apa yang dibutuhkan pengembang game Godot dari pengembang Engine adalah perlambatan yang jelas dari alur kerja resmi untuk membuat objek dan sistem yang kompleks.
Dengan cara itu mereka menyimpang tetapi selalu tahu bagaimana itu dimaksudkan untuk digunakan.

archived discussion core

Komentar yang paling membantu

Jika pertanyaannya sederhana: "Apakah ada beberapa cara untuk mencapai hasil yang sama di Godot ?", jawabannya adalah ya. Dan mencoba memaksakan satu alur kerja tidak masuk akal, karena setiap sistem dalam game mungkin memiliki persyaratan yang berbeda. Anda tidak mengkodekan dengan cara yang sama sistem yang membutuhkan banyak kinerja dan yang perlu sering diperbarui oleh desainer game. Semua solusi memiliki pengorbanan sehingga tidak ada gunanya membuat alur kerja "resmi".

Semua 63 komentar

Jika pertanyaannya sederhana: "Apakah ada beberapa cara untuk mencapai hasil yang sama di Godot ?", jawabannya adalah ya. Dan mencoba memaksakan satu alur kerja tidak masuk akal, karena setiap sistem dalam game mungkin memiliki persyaratan yang berbeda. Anda tidak mengkodekan dengan cara yang sama sistem yang membutuhkan banyak kinerja dan yang perlu sering diperbarui oleh desainer game. Semua solusi memiliki pengorbanan sehingga tidak ada gunanya membuat alur kerja "resmi".

dapat membuat kelas serumit MeshInstance dengan multi komponen

Dengan komponen apa tepatnya?

EDIT: Dan asal tahu saja, salah satu masalah yang Anda kutip ditutup dengan penulis yang menyatakan "Ide ini benar-benar menyebalkan dan sama sekali tidak masuk akal."

Untuk mendemonstrasikan ini, saya akan menggunakan kelas tiruan dari apa MeshInstance, jika dibuat di Godot akan terlihat seperti.
Ada pseudo Unity, alias node anak:
Pengguna Godot menggunakan node anak untuk membuat yang setara dengan MultiScript.
Pseudo Unreal, alias pengontrol dan perantara:
Pseudo Panda3D, alias Preload (Script):
skrip WTF:
Ya, saya tahu Godot memiliki kelas MeshInstance.
Hal ini menunjukkan bahwa sebagian besar alur kerja yang digunakan oleh pengembang saat ini dapat membuat kelas serumit MeshInstance dengan multi komponen; kecuali setiap alur kerja sangat cacat.

Saya tidak begitu mengerti apa yang Anda coba katakan di sini. Mengapa seseorang membuat kelas MeshInstance jika sudah ada? Dan mengapa Godot memiliki fitur yang mirip dengan mesin lain? Juga, jika Anda mencoba untuk melampirkan beberapa skrip ke satu node, Anda juga tidak menggunakan OOP atau Anda menempatkan dua fungsi terpisah ke dalam satu node, yang mudah diperbaiki dengan menggunakan sistem node Godot.

Jika pertanyaannya sederhana: "Apakah ada beberapa cara untuk mencapai hasil yang sama di Godot ?", jawabannya adalah ya...

Jika saya membuat palu, saya tahu untuk apa palu itu, saya tahu beberapa hal yang tidak boleh digunakan bahkan jika saya tidak tahu semua yang bisa digunakan untuk itu.
Jika Anda memberikan palu kepada seseorang yang tidak tahu apa itu palu, dan Anda tidak pernah menjelaskan cara menggunakannya; Anda tidak dapat bertindak terkejut ketika mereka mulai berayun liar.

Di sinilah Godot berada, para pengembang berayun dalam kegelapan, berharap entah bagaimana ini akan memungkinkan mereka untuk menciptakan sesuatu.

Dengan komponen apa tepatnya?

Hal-hal seperti bahan dan transformasi, apakah ini dianggap sebagai bagian dari contoh asli atau tidak?
Jika kita membuat komponen serupa, bagaimana kita melampirkannya ke node?

Bagaimana dengan tugas lain, seperti "mengikuti target" atau "menembak target" apakah ini harus ditambahkan ke dalam kelas atau dilampirkan entah bagaimana?
Karena Godot tidak pernah membuat fungsi Sertakan atau Impor yang tepat untuk Godot, apakah itu berarti tidak pernah dimaksudkan untuk digunakan seperti itu?

Kita tahu kita tidak bisa memiliki segalanya, jadi pertanyaannya adalah apa yang kita miliki? Bagaimana desainnya agar berfungsi?

@MisteriGM Analogi yang longgar dan tidak terhubung tidak membantu.

Hal-hal seperti material dan transformasi

Transform adalah properti Spasial dan Material adalah properti Mesh. MeshInstance dibangun di atas Spatial sehingga mewarisi semua properti Spatial. Ini adalah hierarki sederhana yang masuk akal bagi saya.

Jika kita membuat komponen serupa, bagaimana kita melampirkannya ke node?

Mengapa Anda membuat sistem Mesh Anda sendiri ketika Godot sudah memilikinya?

Bagaimana dengan tugas lain, seperti "ikuti target" atau "tembak tepat sasaran"

Kode masuk dalam skrip. Anda dapat memasukkannya ke dalam skrip utama node atau memberinya skrip anak jika Anda yakin akan lebih berguna jika melakukannya dengan cara itu.

Mengapa Anda membuat sistem Mesh Anda sendiri ketika Godot sudah memilikinya?

Karena objek permainan sama rumitnya dengan jaring jika diperhatikan lebih dari itu. Ingat bahwa mesin di mana bagian dari game asli, itu hanya bagian yang digunakan kembali.

Jika Godot tidak dapat membuat kelas Mesh di dalam mesin secara efektif, maka itu tidak dapat digunakan untuk membuat game yang rumit. Semua permainan harus kurang kompleks dari mesin.
Ini pada gilirannya berarti tidak ada gunanya bagi tim pengembang profesional. Kecuali tim tersebut hanya menggunakan C++ dengan kode sumber.

Kode masuk dalam skrip.

Tapi dengan cara apa?
Saya sudah tahu saya tidak bisa membuat anak untuk setiap skrip karena saya akan membutuhkan lebih dari satu juta fungsi dan bahkan satu juta node kosong terlalu banyak untuk Godot.
Apa artinya, berapa banyak fungsi yang harus dikelompokkan bersama atau haruskah saya menghabiskan 2-4 bulan merencanakan warisan objek saya di atas kertas?

Yang ingin saya ketahui adalah bagaimana cara Godot menangani game besar dengan sistem yang kompleks seperti efek cuaca, kabut volumetrik, dan medan yang luas?

Berikut ini berkaitan dengan saya, pendapat dan pengalaman saya, _YMMV_

Setiap mesin memiliki kekhasannya, dan Godot tidak berbeda. Jika saya jujur, mengingat sudah berapa lama sejak rilis stabil pertama, saya pasti terkesima dengan seberapa bagus dan seberapa cepat itu berkembang. Itu mungkin menjadi alasan untuk beberapa masalah yang kita miliki. Sistem adegan/simpul adalah bagian favorit saya, kesederhanaan skrip skrip benar-benar membuat saya bersinar. Meskipun memiliki kekurangan bagi saya, saya tidak menyukai sintaks seperti python...

Mengambil Unity 4/5 sebagai contoh (yang saya dirantai selama bertahun-tahun), _components_ sangat membengkak sehingga tidak dapat dibandingkan dengan ECS lain yang pernah saya gunakan. Dan oh, Anda ingin membuat permintaan http? Tentu, tambahkan komponen baru ke objek baru ke struktur adegan Anda karena sangat masuk akal untuk menggabungkan permintaan http dengan objek dalam adegan dan komponennya. Fitur "simpan adegan tanpa perubahan merusak semua UUID" tampaknya diciptakan hanya untuk mempersulit desainer non-teknis kami menggunakan kontrol versi. Saya bahkan tidak ingin memulai "Don't Destroy On Load" dan prefab.

Apa alasan di antara sebagian besar hal itu? Saya akan mengatakan itu mungkin organik, pengembangan berulang, dan beberapa solusi peretasan di sana-sini (juga ditemukan di Godot dan mungkin semua mesin game lainnya). Maksud saya, itu sangat macet sehingga Keyboard Swift saya mulai memprediksi kata-kata "_Unity crashing_" setiap kali saya mengetik "_With_". Itu adalah bagian utama dari alur kerja saya, crash -> reimport semua aset selama satu menit, bekerja selama 30', ulangi.

Saya telah melihat begitu banyak penggunaan monobehavior yang menghujat, tapi siapa yang bisa saya salahkan? Mesin memungkinkan orang untuk menempatkan _GameState_ "_component_" di dalam objek pointlight. Haruskah kita melarangnya? Bagaimana saya berpendapat bahwa data status permainan tidak boleh berada di dalam komponen objek adegan ketika komunikasi http (atau hampir semua pekerjaan asinkron) membutuhkannya?

Itu membawa saya ke poin saya, membandingkan mesin dalam tahap pengembangan yang berbeda itu sulit, dan memang Godot berkembang cepat dan menambahkan/menghapus fitur. Itu berarti alur kerja kita harus berubah dan beradaptasi. Saya memiliki alur kerja 2D yang layak dengan Godot, itu pasti lebih baik daripada yang saya miliki dengan Unity. Ya, praktik terbaik tidak jelas. Ya, jika Anda bertanya kepada tiga pengembang, Anda akan memiliki tiga alur kerja yang berbeda. Tapi saya tidak bisa mengatakan itu adalah masalah baru bagi saya, atau setidaknya itu adalah salah satu yang ada di kedua mesin yang dibandingkan.

Saya belum pernah benar-benar menggunakan Unreal (atau mesin permainan lain yang relevan) untuk lebih dari prototipe dan proyek uji, tidak dapat dibandingkan dengan kedalaman yang wajar.

Tapi dengan cara apa?
Saya sudah tahu saya tidak bisa membuat anak untuk setiap skrip karena saya akan membutuhkan lebih dari satu juta fungsi dan bahkan satu juta node kosong terlalu banyak untuk Godot.
Apa artinya, berapa banyak fungsi yang harus dikelompokkan bersama atau haruskah saya menghabiskan 2-4 bulan merencanakan warisan objek saya di atas kertas?

Letakkan semua fungsi dalam satu skrip mungkin? Godot dapat digunakan berorientasi objek dengan cukup baik, jadi jika Anda pernah menggunakan OOP, Anda dapat menggunakan pewarisan skrip atau adegan, membuat kelas, dan sebagainya.

Yang ingin saya ketahui adalah bagaimana cara Godot menangani game besar dengan sistem yang kompleks seperti efek cuaca, kabut volumetrik, dan medan yang luas?

Efek cuaca? Buat adegan yang berisi simpul partikel, matahari, dan lingkungan dunia dan lampirkan skrip ke root. Script ini dapat mengontrol cuaca. Anda juga dapat membuat simpul kosong dan menggunakannya sebagai mesin status, melampirkan simpul kosong untuk setiap status yang Anda miliki (seperti hujan, sinar matahari, dll). Sekarang cukup masukkan kode untuk setiap negara bagian di node mereka. Mesin negara ini dapat dikontrol oleh skrip root. Ini adalah cara melakukan sesuatu yang sangat mudah dibaca.

Kabut volumetrik? Saya rasa saya telah melihat ini di Demo FPS baru.

Medan yang luas? Saya memiliki proyek dengan jaring medan prosedural sekali dan itu berjalan cukup lancar di laptop saya yang berumur beberapa tahun.

Ini hanya beberapa fungsi daripada 'masalah besar' yang Anda bicarakan di OP.

Efek cuaca? Buat adegan yang berisi simpul partikel...

Yah, kami berencana untuk menjadi sedikit lebih ambisius dari itu :) dengan peta wilayah untuk memberi tahu AI ke mana harus berjalan dan kemudian menggunakan saluran lain untuk zona pengecualian hujan sambil menjaga saluran terakhir untuk kedalaman sehingga salju dapat menumpuk seiring waktu.

Medan yang luas?

Ruang besar. Kami membutuhkan beberapa cara untuk mengatur ulang adegan ke Vector3 (0,0,0) tanpa membeku karena terlalu banyak node yang perlu dihapus. Fisika dan semuanya bergetar dengan pelampung besar.

ia memiliki komponen yang sangat membengkak sehingga tidak dapat dibandingkan dengan ECS lain yang pernah saya gunakan.

Setuju, komponen bisa sangat buruk, oleh karena itu tidak mengherankan jika Godot memiliki strategi yang berbeda dalam pikiran. Namun kami tidak tahu strategi apa yang Godot rencanakan atau apakah memang demikian.

2 bulan belajar Godot hanya memikirkan kami bagaimana membuat game kecil.
Dengan 14 hari tersisa untuk memutuskan menggunakan Godot, saya berharap para pengembang mesin dapat menjelaskan bagaimana seharusnya bekerja pada proyek-proyek besar.

Hal terakhir yang ingin kami lakukan adalah berjuang keras melawan desain mesin saat kami mencoba mengembangkan game.

@MysteryGM Saya benar-benar tidak mengerti mengapa menurut Anda Godot tidak dapat digunakan untuk proyek-proyek besar. Desainnya sangat cocok untuk proyek besar karena Anda dapat membagi semuanya menjadi beberapa adegan terpisah dan menggunakan OOP untuk menggunakan kembali pekerjaan. Jika masalah Anda menggunakan Godot untuk proyek besar adalah Anda tidak tahu cara mencapai tujuan, tanyakan saja di saluran bantuan Godot Discords, Anda akan mendapatkan respons yang sangat cepat.

Fisika dan semuanya bergetar dengan pelampung besar.

Lihat #288

Namun kami tidak tahu strategi apa yang Godot rencanakan atau apakah memang demikian.

Saya mengerti itu agak asing pada awalnya, tetapi bagi saya penggunaan node+script itu cukup mudah. Saya pasti akan merekomendasikan untuk melihat (setidaknya) versi hobi dari kursus ini di sini: https://gumroad.com/gdquest
Ini menggunakan struktur skrip simpul yang sangat mirip dengan milik saya, dan pasti dapat memberi Anda wawasan yang lebih baik tentang bagaimana mereka yang benar-benar terlibat dengan mesin menggunakannya; penulis adalah kontributor utama godot docs.

edit: Sebenarnya, Anda dapat melihat sumbernya di repositori, jika Anda tidak ingin kursus https://github.com/GDquest/make-pro-2d-games-with-godot

Dengan 14 hari tersisa untuk memutuskan menggunakan Godot, saya berharap para pengembang mesin dapat menjelaskan bagaimana seharusnya bekerja pada proyek-proyek besar.

Saya kira saya hanya sedikit bingung tentang apa sebenarnya yang Anda maksud dengan ini. Anda menggunakan analogi palu sebelumnya sebagai contoh, tetapi analogi ini cacat karena palu umumnya merupakan alat utilitarian dasar sekali pakai, dan ada pemahaman intrinsik tentang apa alat itu digunakan karena harganya yang terjangkau.

Selain itu, sementara Anda telah membuat daftar semua masalah dengan semua sistem di atas, saya pikir kenyataan dari setiap proyek perangkat lunak besar adalah bahwa setiap 'pilihan' arsitektur yang Anda buat akan menyebabkan beberapa kerugian di kemudian hari, yang hanya perlu Anda lakukan. bekerja lebih banyak di sepanjang jalan. Jadi, apakah Anda mencari saran peluru perak? Karena sejujurnya, saya bahkan tidak berpikir sebagian besar proyek Unity atau Unreal mengikuti struktur 'yang direkomendasikan' yang tepat dan sering memotong mesin agar sesuai dengan alur kerja apa pun yang paling cocok untuk mereka. Saya bahkan sampai berpendapat bahwa setiap game perlu memiliki ide uniknya sendiri tentang arsitektur node. (Permainan simulasi akan memiliki struktur yang sangat berbeda dari penembak orang ketiga, misalnya.)

Saya kira argumen dapat dibuat untuk dokumentasi lebih lanjut tentang contoh struktur proyek, tetapi saya pikir itu hanya masalah kontribusi lebih banyak untuk dokumentasi.

memisahkan adegan dan menggunakan OOP untuk menggunakan kembali pekerjaan.

Seperti yang saya sebutkan sebelumnya, memindahkan objek setelah sinyal dipasang adalah hal yang menyebalkan. Apalagi ketika mereka berhenti bekerja tanpa pernah memberikan pengecualian atau peringatan.
Kami memutuskan untuk menggunakan alat refactoring pihak ketiga, setelah pengembang lain menyebutkannya; tapi meski begitu itu tidak bisa menyelesaikan masalah unik Godot.
Tidak memindahkan barang menyebabkan masalah ini (gambar dari "papan masalah" kami):
pawndefend
Jadi untuk memperbaikinya kami membuat node anak. Kecuali sekitar 50.000 itu mulai menyebabkan masalah bahkan mereka hanya Node.
pawnfollow

Yang ingin kami ketahui adalah bagaimana kami menangani masalah ini, bagaimana rencana Godot untuk menanganinya; kami menguji setiap alur kerja yang saya sebutkan di atas.

Lihat #288

Terima kasih untuk itu, kami sangat terbiasa dengan koordinat dunia istirahat, kami tidak pernah memeriksa ini.

Saya mengerti itu agak asing pada awalnya, tetapi bagi saya penggunaan node+script itu cukup mudah.

Masalahnya bukan karena itu asing, masalahnya adalah ia menyebabkan masalah yang berbeda. Terutama bahwa menambahkan lebih banyak anak pada akhirnya akan memperlambat permainan atau membekukannya ketika kami mencoba untuk menurunkannya.
Bahkan ketika mereka hanya Node.

Mengapa Anda membutuhkan 50.000 objek dalam game Anda? Tentunya mesin APAPUN ini akan lag.

Mengapa Anda membutuhkan 50.000 objek dalam game Anda?

Karena kami menggunakan node untuk menambahkan skrip tambahan ke objek. Karena alat UI Godot menggunakan wadah dalam wadah dalam wadah... untuk menskalakan berbagai hal secara waktu nyata.
UI terkecil kami adalah lebih dari 800 objek. Sebagian besar wadah ini.

Kami memiliki 50.000 objek karena satu AI musuh adalah +/-8 node dengan tujuan dan +/- 64 node yang hanya ada di sana sehingga kami dapat melampirkan skrip ke objek tersebut.
Karena dengan membagi setiap tugas ke dalam kodenya sendiri, kita dapat melihat di mana letak masalah kita. Karena tidak ada cara lain untuk dengan cepat menemukan bagian tertentu dari permainan.

Dalam hal ini, sepertinya Anda telah masuk ke zona di mana Modul Kustom adalah pilihan yang baik.
http://docs.godotengine.org/en/3.0/development/cpp/custom_modules_in_cpp.html
Anda dapat membuat simpul khusus di sana, dan menghindari banyak sarang.

sunting: Meskipun saya berpendapat bahwa 800 objek untuk satu (terkecil?) ui menunjuk ke arah desain/arsitektur yang buruk.

Saya benar-benar gagal memahami bagaimana Anda dapat memiliki hampir 64 skrip untuk satu objek. Ini kedengarannya lebih merupakan masalah desain proyek Anda daripada masalah Godot (sekali lagi, kemungkinan akan memperlambat mesin apa pun). Konsolidasikan kode Anda menjadi lebih sedikit skrip. Jangan membuat skrip untuk setiap bagian fungsionalitas, tetapi untuk setiap jenis objek (Jika simpul "Musuh" dapat melakukan XYZ, tambahkan bagian itu ke dalam skrip Musuh alih-alih menambahkan simpul anak untuk fungsi X dan Y dan Z) . Jika Anda memerlukan fitur yang lebih canggih untuk melakukan ini, mungkin Anda dapat menggunakan pewarisan khusus dan/atau antarmuka C#.

Dalam hal ini, sepertinya Anda telah masuk ke zona di mana Modul Kustom adalah pilihan yang baik.

Lihat ini adalah salah satu hal yang kami ingin tahu, karena kami semua tahu C++ jika Modul Kustom diperlukan, kami hanya akan mengedit mesin Godot.
Kami tahu bahwa kami dapat dengan aman menggunakan #include di mana Godot preload() dipertanyakan; tidak ada yang bisa memberi tahu kami seberapa stabilnya atau apakah ada kerugiannya.

Saya benar-benar gagal memahami bagaimana Anda dapat memiliki hampir 64 skrip untuk satu objek.

Sederhana, setiap AI dapat melakukan kurang lebih 64 tugas, bukan tugas kecil juga.
Sebuah Script misalnya SquadFlightPatters dan di sini adalah semua formasi penerbangan semua 20 dari mereka, kemudian ada SquadFlightPattersCosmetic dari hanya menyelesaikan animasi, suara dan partikel yang berhubungan dengan pola penerbangan.

Aturan kami saat ini adalah membagi umpan balik pengguna dari mekanik.

Jika simpul "Musuh" dapat melakukan XYZ maka tambahkan bagian itu ke dalam skrip Musuh alih-alih menambahkan simpul anak untuk fungsionalitas X dan Y dan Z

Jika Anda melihat gambar dan Pseudo Unreal, alias pengontrol dan perantara.

karena kita semua tahu C++ jika Modul Kustom diperlukan, kita hanya akan mengedit mesin Godot.

Saya menemukan membuat modul jauh lebih sederhana daripada mengubah mesin itu sendiri, karena dibangun di atasnya, bukan di dalamnya.

Masih tidak dapat membayangkan penskalaan ini ke angka yang begitu tinggi, terutama UI dengan ratusan atau ribuan node per widget.

Menanggapi Masalah yang dirujuk di OP:

  • 19486 :

    • tambahkan manajemen ketergantungan yang tepat dengan pemasangan aset di seluruh sistem. Pindahkan add-on dari proyek itu sendiri dengan cara mengembalikannya untuk dimodifikasi
    • membuatnya lebih mudah untuk memperluas node khusus, memungkinkan pewarisan skrip lintas bahasa
    • izinkan skrip direferensikan oleh nama kelas dan namespace untuk menghindari jalur super panjang jika ada aset.

    Kelas skrip memecahkan masalah terakhir. Ruang nama dapat dibuat dengan membuat kelas skrip tingkat atas dengan konstanta yang berfungsi sebagai alias untuk skrip lain. Perubahan yang saya buat pada adegan editor di 3.1 juga membuatnya JAUH lebih mudah untuk memperluas skrip kustom sekarang. Adapun pewarisan lintas bahasa, itu tidak akan pernah diimplementasikan secara formal, tetapi jika MultiScript pernah diperkenalkan kembali, maka itu bisa memalsukannya dengan cukup baik.

  • 7402 : Sekali lagi, kelas skrip adalah solusi untuk masalah ini ("solusi lebih sederhana" yang telah dipikirkan reduz, jika Anda melihat beberapa komentar terakhir dari Masalah ini).

  • 15996 : Saya menyadari bahwa apa yang saya inginkan adalah sistem sifat (sebelum saya mengerti apa itu sifat) dan akibatnya menyadari betapa buruknya proposal awal saya karena itu benar-benar mendistorsi desain adegan dan simpul yang ditargetkan dan mengubah keseluruhan sesuatu ke dalam sistem pewarisan berbasis komposisi - sesuatu yang lebih seperti apa yang sebenarnya dilakukan Unity, yang menjijikkan (di Unity, Anda dapat menggunakan getComponent dari KOMPONEN mana pun dan itu mengambil komponen saudara pada GameObject yang memiliki. Komponen tersebut, dalam praktiknya, merupakan ekstensi GameObject, mendorong ketergantungan mereka satu sama lain).

  • 8502 : MultiScript hanyalah alat untuk memungkinkan bahasa skrip yang berbeda saling mewarisi, mirip dengan cara Blueprints UE4 dapat mewarisi langsung dari skrip C++ (yang, di Godot tidak akan mungkin karena perbandingannya memiliki GDScript yang memperpanjang NativeScript. VisualScript bahkan tidak mendukung pewarisan, jadi GDScript adalah perbandingan yang lebih tepat di sini).

    Sekarang, karena MultiScript pada dasarnya mendukung skrip APAPUN yang memperluas tipe mesin dasar (sehingga Anda dapat memiliki beberapa skrip perpanjangan Node dari berbagai bahasa yang semuanya melakukan hal yang berbeda, tetapi tidak terkait satu sama lain), sebenarnya berfungsi hampir seperti sistem sifat lintas bahasa ... semacam. Saya pikir menambahkan kembali MultiScript akan sangat keren

Banyak masalah yang diangkat dalam OP berkisar tentang adanya beberapa cara potensial untuk mengatasi masalah, yang masing-masing mungkin memiliki berbagai inefisiensi. Biasanya, ketika ada cara tertentu untuk melakukan sesuatu yang paling optimal, mesin menyediakan implementasinya sendiri di mesin C++ utama (tidak perlu skrip atau plugin) dan itulah penggunaan yang disarankan.

Jika kelas seperti itu ada dan orang tidak menggunakannya, maka itu pertanda bahwa 1) mereka tidak memeriksa dokumentasi dengan benar untuk melihat apakah kebutuhan mereka sudah dipenuhi oleh mesin / bagaimana mesin menyarankan itu digunakan atau 2) mesin / organisasi tidak melakukan pekerjaan yang cukup baik untuk membuat dokumentasi sangat terlihat atau dapat diakses oleh pengguna (karena mereka tidak menemukan sumber daya yang ada).

Satu-satunya hal yang harus dilakukan untuk memperbaiki masalah 1 adalah orang-orang itu menyuarakan masalah mereka dan orang lain mengarahkan mereka ke dokumen atau situs Tanya Jawab untuk membantu mereka menemukan solusi mereka. Saya telah membuat Masalah (#23043) yang menyarankan agar orang-orang menelusuri dan menggunakan situs Tanya Jawab langsung dari editor yang akan banyak membantu masalah 2. Alasan dijelaskan di tautan.

(Sunting: jika ada banyak cara untuk memecahkan masalah, dan salah satu cara itu jauh lebih baik daripada yang lain, dan Godot belum menerapkan solusi aslinya sendiri untuk itu, maka itu akan menjadi sesuatu untuk disarankan sebagai fitur baru untuk mesin Ini adalah cara kami menambahkan hal-hal SimplexNoise karena orang-orang menulis algoritme SimplexNoise mereka sendiri dalam GDScript / kode shader, dll.).


Berdasarkan "papan masalah" yang Anda gambarkan, masalah yang Anda alami adalah bahwa pewarisan berganda tidak didukung (atau ide yang bagus), jadi Anda menggunakan node komponen yang memberikan fungsionalitas kepada induknya (yang terdengar masuk akal bagi saya). Jika Anda mengalami masalah dengan lagging game Anda karena itu hanya membuat terlalu banyak node, maka menurut saya sepertinya akan ada masalah dengan pendekatan umum Anda (yang tampaknya Anda kenali dan cari bantuan untuk dalam mengidentifikasi di sini).


Adapun contoh alur kerja Anda di OP ...

  • Pendekatan kesatuan, node anak:

    Masuk akal untuk menggunakan node anak, dengan asumsi bahwa seseorang menulis logika pasangan. Ini idealnya di mana sistem sifat akan berguna (sehingga seseorang dapat menulis logika pasangan sekali dan hanya mereplikasinya di mana saja sesuai kebutuhan). Saya sering menulis komponen dengan cara di mana mereka secara otomatis menetapkan diri mereka sebagai "target" untuk orang tua mereka ketika mereka diasuh/tidak diasuh dan menyambungkan/memutuskan sinyal yang relevan secara otomatis. Anda dapat menggunakan notifikasi NOTIFICATION_(UN)PARENTED di _notification(what) untuk ini.

  • Pendekatan UE4 dengan pengontrol:

    Godot 3.1 memungkinkan Anda untuk menetapkan kelas skrip untuk skrip, jadi tidak perlu memuatnya terlebih dahulu. Dalam hal ini, Godot TIDAK memungkinkan Anda untuk menetapkan nama jenis ke node, tetapi khusus untuk skrip, jadi Anda harus berhati-hati. Adegan tidak mendapatkan perlakuan yang sama, dan mungkin tidak akan mendapatkan perlakuan yang sama karena akan melibatkan penambahan banyak hal ke inti mesin (yang bisa membuat para pengembang inti sangat sensitif).

    Saya juga tidak yakin bagaimana Anda mendapatkan begitu banyak kode duplikat? Jika beberapa kelas memerlukan logika yang sama, maka Anda menggabungkan logika itu ke dalam satu Node dan kemudian mereproduksi Node itu di bawah kelas yang membutuhkannya, dengan cara yang sama seperti yang Anda lakukan dengan Unreal (komponen, Aktor anak), Unity (MonoBehaviours atau Child GameObjects) , atau hampir semua mesin lain yang mengalihkan dependensi ke objek yang dimiliki untuk mengurangi penggunaan kembali kode.

  • Pendekatan Panda3D dengan pramuat:

    Saya dapat memahami bahwa ada banyak masalah dengan pendekatan ini karena NodeRefs belum menjadi masalah, dan ada masalah dengan mengekspor skrip Sumber Daya saat ini yang saya harap dapat diperbaiki untuk 3.2 (walaupun Anda mungkin dapat memperbaikinya sendiri cukup mudah, itu cukup kecil).

  • Pendekatan skrip WTF:

    Saya tidak begitu mengerti semua masalah yang Anda alami di sini, mungkin karena kita tidak memiliki banyak konteks.

    Konflik dengan sistem instance. Karena instance mengalir ke bawah saat sinyal terhubung ke atas.

    Kapan Anda ingin memiliki perilaku pemicu sinyal orang tua pada keturunannya? Mengapa tidak meminta orang tua langsung mendapatkan dan memanggil keturunan dan metodenya? Tidak ada bahaya orang tua melihat anaknya. Ini seperti mengatakan objek C++ seharusnya tidak dapat mengakses struct atau variabel anggota kelasnya(?).

    Skrip kecil yang tidak berguna hanya berkeliaran. Yang mereka lakukan hanyalah mengirim sinyal dan melacak satu nilai.

    Ini sudah menjadi tanda bahwa desain proyek tidak bagus. Ini masalah memiliki setiap interaksi tunggal dalam permainan dilacak oleh objek pribadinya sendiri. Ini tidak benar-benar ideal, dari sudut pandang apa pun.

    Memindahkan objek dengan begitu banyak sinyal yang terpasang setidaknya membuat frustrasi.

    Dengan cara apa? Saya biasanya menemukan bahwa saya melakukan hardcoding koneksi dalam file adegan atau secara algoritmik menghubungkan dan memutuskan sinyal untuk node jika mereka dimaksudkan untuk dipindahkan. Itu sudah cukup memenuhi tujuan saya, tetapi jika Anda memiliki masalah khusus, membagikannya dapat membantu orang lain untuk membantu Anda.

    Sinyal dan Grup memungkinkan seluruh bagian permainan gagal begitu saja, tanpa peringatan.

    Demikianlah masalah dengan boolean apa pun melalui desain keberadaan. Alternatifnya adalah mengulang melalui SEMUA objek, memeriksa apakah mereka cocok dengan kriteria, dan kemudian melakukan logika jika mereka cocok dan, jika mereka cocok, tetapi tidak benar, maka buat kesalahan. Dalam kasus sinyal dan grup, perilaku dipicu pada semua yang ada di dalam set secara otomatis, jadi jika ada yang keluar dari set, tidak ada cara untuk mendeteksi bahwa masalah telah terjadi selama waktu eksekusi. Satu-satunya cara untuk menemukan masalah semacam ini adalah selama proses pengaturan di mana grup/sinyal sedang diatur di tempat pertama.


Bagaimanapun, itu semua pengalaman saya dengan barang-barang itu. Ini akan lebih membantu kami untuk mengetahui lebih banyak tentang proyek Anda dan apa yang sebenarnya dilakukan sehingga kami dapat memberikan saran untuk kasus penggunaan khusus Anda.

Either way, masalah yang Anda angkat di sini tampaknya bukan masalah "baru" dengan desain atau implementasi Godot Engine itu sendiri. Godot memberi orang API dan bagaimana orang menggunakan API itu terserah mereka. Jika Anda memiliki gagasan tentang bagaimana fitur tertentu harus dibuat lebih terintegrasi / tersedia di Godot (misalnya, menghidupkan kembali MultiScript), maka itu akan menjadi proposal yang bagus.

Namun, pertanyaannya di sini tampaknya lebih merupakan "apa cara terbaik untuk merancang sistem seperti X" yang ... sebenarnya bukan masalah GitHub. Tampaknya lebih tepat di situs T&J untuk semacam pertanyaan "praktik terbaik". Itu, atau itu adalah saran bahwa kami harus menyediakan jalan untuk membuat informasi khusus kasus penggunaan semacam ini lebih jelas / tersedia untuk umum, yang persis seperti yang dimaksud dengan Masalah T&J saya.

Kelas skrip memecahkan masalah terakhir.

Pertama, terima kasih atas balasannya yang panjang, itu banyak dan jelas membutuhkan waktu untuk menulis.
Saya senang mendengar tentang kelas skrip, kami tidak menggunakan 3.1; hanya untuk menjalankan demo FPS.

tetapi jika MultiScript pernah diperkenalkan kembali, maka itu bisa memalsukannya dengan cukup baik.
Sangat bisa dimengerti jika Godot tidak pernah mengimplementasikan MultiScript. Sebenarnya saya baru saja menunjukkan bahwa banyak pengguna di GitHub mencari solusi alur kerja yang serupa saat kami mencoba.

Kapan Anda ingin memiliki perilaku pemicu sinyal orang tua pada keturunannya? Mengapa tidak meminta orang tua langsung mendapatkan dan memanggil keturunan dan metodenya?

Saya merasa harus menjelaskan ini. Saat itu kami memiliki skrip yang sangat besar, masing-masing memiliki sekitar +/- 30 fungsi. Untuk alasan itu kami ingin menghindari penambahan fungsi sinyal tambahan ke skrip yang sudah besar.
Hasilnya adalah kami membuat skrip longgar untuk membongkar pekerjaan dari skrip besar.

Ini sudah menjadi tanda bahwa desain proyek tidak bagus.

Itu memang akar masalahnya. Terutama karena kami mencoba banyak desain yang direkomendasikan oleh komunitas Godot dan beberapa dari tutorial.
1.) Pada awalnya kami memiliki warisan gila, dengan cepat ditinggalkan ketika menjadi jelas bahwa Menyimpan Adegan Cabang atau memindahkan objek ke adegan lain terputus sinyal.
2.) Kami mengikuti ini dengan skrip besar. Kecuali nama abstrak dari skrip ini untuk mencoba dan menjelaskan apa yang dilakukan masing-masing, membuatnya sulit untuk menemukan masalah.
Kami tahu apa nama fungsi yang menyebabkan masalah di mana, tetapi tidak persis di mana mereka berada.
3.) Kemudian dengan membaca manual kami menemukan pendekatan simpul anak. Itu mungkin terlalu menggoda karena memungkinkan node langsung dan kita bisa melihat strukturnya di editor; juga menyaringnya untuk menemukan skrip yang tepat yang kita inginkan.

Berakhir dengan saya di sini, dan saya pikir jawaban terakhir membahas banyak hal yang saya ingin tahu; Saya harus memeriksa ulang besok karena ini jam 2 pagi di sini.

"apa cara terbaik untuk mendesain sistem seperti X" yang... sebenarnya bukan masalah GitHub.

Saya ingin menunjukkan bahwa kami kehabisan sebagian besar pilihan kami yang lain. Masing-masing dari kami bertanya-tanya di forum Q&A, kami berteman di komunitas dan mengumpulkan contoh dari mereka. Memindai dokumen mencari penjelasan.
Semua alur kerja yang saya jelaskan adalah hal-hal yang kami coba jelaskan kepada kami oleh pengguna Godot, yang menggunakan alur kerja ini. Masing-masing akan bekerja di mesin yang disebutkan, mereka hanya tidak bekerja dengan baik di Godot.

Hanya alur kerja terakhir yang berhasil, kecuali programmer utama kami membenturkan kepalanya ke meja dan menirukan mencekik seseorang.

Maaf membaca Anda mengalami masalah dalam menemukan solusi untuk masalah Anda. Will sudah memberi Anda jawaban yang panjang jadi saya akan mencoba untuk tidak mengacaukan percakapan terlalu banyak tetapi pada titik ini, sepertinya Anda membutuhkan lebih banyak konsultan untuk membantu Anda memecahkan tantangan spesifik yang muncul dari kebutuhan Anda.

Terutama karena kami mencoba banyak desain yang direkomendasikan oleh komunitas Godot dan beberapa dari tutorial

Sebagian besar dari kita di masyarakat bekerja dalam proyek-proyek skala yang relatif kecil. Saya menggunakan banyak node untuk membantu mendapatkan poin dan struktur dari sistem yang diberikan dalam tutorial. Ini akan berskala baik untuk kebanyakan orang. Tapi apa yang berhasil untuk game berukuran kecil atau sedang tidak berlaku untuk game yang lebih besar.

Mengikuti apa yang dikatakan @willnationsdev sebelumnya, mungkin ada baiknya mempertimbangkan kode back-end untuk membantu skala permainan, baik dari segi kinerja maupun hanya untuk memiliki lebih sedikit kode untuk dikelola di editor itu sendiri. Saya tidak dapat membantu banyak selain itu karena, seperti banyak orang di sini, saya tidak memiliki pengalaman dengan proyek yang lebih besar. Semoga beruntung!

Hai, kami hanya punya satu pertanyaan lagi.

Jika kita memiliki dua objek yang tidak terkait, seperti bangunan dan air, tetapi kita ingin skrip objek ini berinteraksi, bagaimana kita melakukannya tanpa node atau pramuat?
Airnya bertekstur sehingga tidak bisa berbenturan dengan bangunan juga.

@MysteryGM Apakah Anda mengatakan Anda tidak ingin node mewakili bangunan dan air, atau Anda hanya tidak ingin skrip dilampirkan padanya? Tidak ada yang salah dengan memiliki data untuk diproses yang tidak ada dalam beberapa cara di dalam pohon adegan selain dari satu data yang berisi simpul.

Jika Anda ingin mengambil pendekatan ECS, alih-alih melampirkan skrip ke setiap instance dari suatu tipe dan membuatnya diproses secara individual, Anda dapat memiliki satu simpul "sistem" yang akan beralih dan melakukan pemrosesan pada simpul sesuai dengan tipe/ kelompok Anda ditugaskan mereka. Jika Anda ingin menghindari melampirkan skrip ke node untuk informasi detail masing-masing, Anda juga dapat menyimpan info itu di sistem tergantung pada seberapa temporal. Ini membuat node Anda lebih ringan, dan bisa lebih efisien untuk Anda saat beroperasi pada ribuan entitas dengan tipe yang sama.

Dengan memiliki 50.000 dari apa pun , Anda telah lama melampaui titik di mana metafora berbasis objek SceneTree-and-node Godot berguna.

Itu tidak jauh berbeda dari mesin lain, dengan Unity Anda akan mencapai batas yang sama dengan objek permainan mereka, GC, atau dengan UE4 Anda akan menemukan masalah penskalaan cetak biru sejauh itu - tetapi di atas semua itu, memiliki jumlah apa pun berarti default editor visual tidak lagi berguna, dan alat yang disediakan mulai rusak atau setidaknya berkinerja buruk.

Di semua mesin, solusinya sebagian besar sama: buat solusi Anda sendiri. Apa itu lebih tergantung pada gim Anda, arsitektur, dan detailnya daripada mesinnya.

Kelas manajer, bus komunikasi pub-sub, perantara pesan, manajer instans serupa dengan apa yang dilakukan untuk partikel, kumpulan objek, shader khusus untuk memindahkan pekerjaan ke GPU, menghitung shader, memindahkan pemrosesan ke utas atau proses/server lain - ada berton-ton blok bangunan untuk solusi yang memungkinkan, dan mana yang perlu Anda gabungkan bergantung pada rangkaian masalah spesifik Anda.

Unity membuat beberapa hal ini lebih mudah dengan infrastruktur ECS baru mereka. Tidak yakin tentang UE4. Pada akhirnya, pada tingkat mahir ini, Anda harus melakukan sebagian besar pekerjaan berat sendiri (atau mempekerjakan seseorang yang berpengalaman untuk melakukannya untuk Anda).

UE4 dan Unity hanya lebih mudah sejauh mereka lebih tua, lebih mapan, dan dengan demikian ada lebih banyak orang yang mengalami masalah penskalaan seperti itu, yang berarti lebih banyak pengetahuan (dan bakat yang dapat disewa) tersedia untuk menyelesaikannya.

Tapi sungguh, pada akhirnya, tidak ada mesin yang akan membawa Anda sejauh itu . Setiap game ambisius akan mengalami keterbatasan di mesin apa pun. Saya tahu banyak contoh untuk game menengah hingga besar di UE atau Unity yang juga perlu menyelesaikan masalah serupa. Selesaikan atau kurangi cakupan Anda.

Apa yang dibutuhkan pengembang game Godot dari pengembang Engine adalah perlambatan yang jelas dari alur kerja resmi untuk membuat objek dan sistem yang kompleks.

Itu sangat tergantung pada permainan Anda. Tidak ada jawaban langsung untuk ini di mesin besar mana pun.
Haruskah Anda menggunakan pendekatan berbasis gameobjects-scene di Unity? Atau ECS hibrida? ECS baru yang lengkap? Pipa render mana yang Anda gunakan?
Apakah Anda akan menggunakan Blueprint atau C++ dalam proyek UE4 Anda?

Semua engine menawarkan banyak pilihan, banyak worklows, dan banyak kebebasan, karena tidak ada solusi satu ukuran yang cocok untuk semua.

Jadi, jika Anda memerlukan saran konkret tentang cara mendekati permainan spesifik Anda di Godot, bagaimana menyusunnya, arsitektur apa yang digunakan, Anda perlu memberikan lebih banyak konteks dan informasi.

Beri tahu kami apa yang ingin Anda capai, dan mungkin seseorang dapat memberikan saran. Jika tidak, satu-satunya cara adalah menyewa Godot dev berpengalaman sebagai konsultan.

Saya hanya bisa setuju dengan Groud:

Semua solusi memiliki pengorbanan sehingga tidak ada gunanya membuat alur kerja "resmi".

@mhilbrunner Hanya bermain advokat iblis di sini tetapi desain mesin yang lebih baik (seperti ECS yang tepat di sebagian besar kasus di mana kinerja penting) membuat banyak dari batas itu secara signifikan lebih tinggi daripada hampir semua game yang benar-benar pernah alami (inilah cara Rust Amethyst baru mesin permainan sedang membangun untuk fokus misalnya).

Tapi ya, saya telah melakukan hal ECS di Godot (2) dan itu bekerja jauh lebih baik daripada gaya pembuatan instance scenetree dalam hal efisiensi dan distribusi fungsionalitas. Itu bisa dilakukan, hanya sedikit menyakitkan karena Godot tidak memiliki beberapa primitif yang berguna untuk itu.

@OvermindDL1

Saya hanya bisa berbicara untuk diri saya sendiri, bukan pengembang Godot lainnya, dan saya hanya memiliki pengalaman dengan UE, Unity dan Godot, jadi saya tidak tahu tentang Rust Amethyst.

Itu bisa dilakukan, hanya sedikit menyakitkan karena Godot tidak memiliki beberapa primitif yang berguna untuk itu.

Berdiskusi tentang di mana masuk akal untuk menambahkan primitif seperti itu / bagaimana Godot dapat mengakomodasi kasus penggunaan seperti itu dengan lebih baik, saya pikir akan sangat berharga. Mungkin tidak dalam masalah ini :)

Tetapi kita harus mengumpulkan umpan balik ini dengan cara tertentu.

Dan saya setuju bahwa ada batasan yang berbeda tergantung pada mesinnya, tetapi sekali lagi, saya telah melihat orang-orang mengalami hambatan serupa di Unity dan UE4 juga. Mungkin nanti, mungkin itu lebih tinggi - tetapi pada akhirnya, Anda harus bisa memecahkan masalah yang Anda hadapi di mesin apa pun. :)

@MysteryGM Apakah Anda mengatakan Anda tidak ingin node mewakili bangunan dan air, atau Anda hanya tidak ingin skrip dilampirkan padanya?

Saya sudah memiliki skrip yang dilampirkan ke objek air yang memberi makan shader air. Jadi saya tidak bisa lagi melampirkan skrip ke simpul air.
Saya memiliki skrip yang dilampirkan ke gedung yang mengontrol produksi sumber dayanya dan menghubungkan hal-hal seperti pintu ke sana. Jadi ia juga memiliki skrip yang tidak ingin saya tambahkan lebih banyak kode.

Dengan kedua objek sudah memiliki kode, apa yang harus saya lakukan sekarang? Saya tidak dapat menambahkan lebih banyak node, dan masih belum jelas apakah preload adalah solusi yang memungkinkan.

Pertanyaan saya jika saya mengucapkannya sebagai desain OOP adalah: Bagaimana dua skrip mengakses antarmuka satu sama lain?

Masalahnya adalah GDscript sepertinya tidak memiliki cara untuk mengakses skrip lain secara langsung.
Jika saya ingin Api membakar Kayu, saya juga harus memiliki Kayu->memperpanjang->Api atau Api->memperluas->Kayu.

@MisteriGM : Satu tip: sinyal. Api dapat membakar sinyal (target) di mana targetnya adalah Kayu Anda.

Bagaimana dua skrip mengakses antarmuka satu sama lain?

$NodeWithScript.do_function() ?

_/saya masih berperan sebagai advokat setan, jangan menganggap ini sebagai ukuran apa pun dari apa yang 'harus' dilakukan di Godot, paling banter bikeshed_

Saya hanya bisa berbicara untuk diri saya sendiri, bukan pengembang Godot lainnya, dan saya hanya memiliki pengalaman dengan UE, Unity dan Godot, jadi saya tidak tahu tentang Rust Amethyst.

UE menggunakan model Aktor SceneTree. Unity menggunakan model EC (walaupun baru-baru ini mereka telah membangun ECS dan menghentikan model EC lama, itu belum cukup lengkap tetapi terlihat menjanjikan). Dan Godot menggunakan model Component SceneTree. ECS adalah bagian dari pola aliran data (khususnya ini adalah generalisasi darinya).

Ringkasan singkat tentang ECS:

  • 'Entitas' hanyalah ID integer, meskipun sebagian besar mesin mengemas indeks generasi dan entitas ke dalam satu int32 (generasi 8 bit dan indeks 24 bit) atau int64 (masing-masing 32 bit, int64 secara signifikan lebih umum karena ECS sebenarnya memungkinkan Anda untuk menskalakan ke jumlah entitas yang signifikan).

  • A 'Komponen' adalah struktur POD dalam terminologi C/C++, sama sekali tidak boleh berisi fungsionalitas. Secara umum itu harus memcpy'able secara sepele.

  • 'Tabel' Komponen adalah penyimpanan untuk komponen, pada dasarnya itu hanya dapat berupa array yang dapat diubah ukurannya, tetapi secara umum beberapa jenis cenderung digunakan:

    • Resizeable Array: Sering digunakan ketika komponen sangat umum, seperti Position.
    • Array Jarang: Sering digunakan ketika komponen cenderung digunakan dalam kelompok entitas pada suatu waktu.
    • Pemetaan: Mungkin peta Hash atau peta Pohon atau lebih tergantung pada karakteristik kinerja yang Anda harapkan, tetapi umumnya digunakan untuk komponen yang kurang umum.
    • Bitset: Digunakan murni sebagai definisi jika suatu komponen ada pada suatu entitas sama sekali tetapi tidak menyimpan apa pun, umumnya dikenal sebagai Komponen Bendera.
    • Octree atau SceneGraph lainnya (renderer Godot bisa muat di sini): Pemetaan scenetree yang berpura-pura menjadi komponen.
    • Dll...: Banyak jenis lain tergantung pada akses dan karakteristik kinerja yang diharapkan untuk suatu komponen.
  • Sebuah ' S ystem' pada dasarnya adalah fungsi yang mengambil sekumpulan komponen yang digabungkan, meskipun sebagian besar perpustakaan memilikinya sebagai kelas atau modul non-virtual atau lebih, ia beroperasi di atas kumpulan komponen yang digabungkan untuk 'melakukan' sesuatu, yang dapat melibatkan perubahan nilai dalam komponen, menambah atau menghapus komponen, dll... Beberapa contoh:

    • Sistem yang mengambil semua entitas dengan komponen Posisi dan Transformasi dan dengan cara yang efisien dan ramah-tembolok mengubah semua matriks posisi dengan transformasi yang diperlukan pada tick/waktu yang diberikan. Ketika tidak ada lagi transformasi yang harus dilakukan (entitas menjadi statis) maka komponen Transformasi dihapus dari entitas dan kemudian tidak lagi diproses.
    • Sistem input mendengarkan kejadian dari input (mouse/keyboard/gamepad/dll...) dan mengubahnya menjadi komponen yang ditambahkan ke entitas yang relevan atau untuk melakukan tindakan lain.
    • Sistem Tungku (Metafora Minecraft) mengambil entitas yang memiliki Inventaris, Bahan Bakar, Pemetaan Resep, BlockPos, Memasak, dan komponen lainnya, mengulangi entitas tersebut dan memperbarui status yang relevan seperlunya, hingga tidak ada lagi yang dimasak dan ketika bahan bakar habis maka ia dihapus komponen Bendera Masak sehingga tidak lagi diproses sampai inventaris diubah lagi untuk mengatur komponen bendera apa pun.

Secara internal, Anda dapat menganggap ECS sebagai database tempat Anda dapat berlangganan untuk mengatur pemetaan data, meskipun jika dibuat dengan baik, mereka akan dioptimalkan dengan sangat baik. Dengan pengetahuan tentang sistem mana yang harus dijalankan sebelum sistem lain dan sistem mana yang beroperasi secara non-overlapping (bergantung pada membaca atau membaca/menulis), maka Anda juga dapat dengan mudah melakukan multi-thread panggilan. (Saya terus menggunakan Amethyst dan bagian perpustakaan khusus ECS yang disebut specs sebagai contoh karena saya memiliki andil dalam pembuatannya dari mem-porting perpustakaan C++ ECS lama saya) Buku spesifikasi banyak merinci tentang 'Mengapa' ECS, ' Bagaimana', efisiensi, kegunaan, dll... Amethyst masuk ke detail lebih jauh terutama dengan bagaimana ECS harus digunakan dengan sistem permainan umum, rendering, dll...

Jika Anda ingin melihat pustaka C++ ECS yang ditulis dengan baik, maka lihat https://github.com/skypjack/entt karena dari semua pustaka C++ ECS yang pernah saya lihat tidak saya buat, sepertinya itu yang terbaik yang dibuat secara keseluruhan (meskipun spesifikasi masih mengunggulinya dalam pengujian sederhana saya, meskipun tidak banyak, yang mengesankan mengingat spesifikasi mengungguli semua yang pernah saya bandingkan dengan margin yang signifikan).

'Penggunaan' ECS secara umum adalah Anda memiliki 'Entitas' (hanya bilangan bulat, tidak ada data), dan Anda memiliki kumpulan Tabel yang memetakan komponen ke entitas, dan sistem untuk benar-benar melakukan pekerjaan. Dalam kode semu GDScript, saya membayangkannya sebagai API sederhana, meskipun dengan sedikit konvensi aneh untuk 'mengintegrasikan' ke dalam scenetree Godot karena scenetree tidak dirancang dengan mempertimbangkannya.

# All of this would generally be wrapped up in one or more function calls for easy
# building.

# Create a new entity
var e = createEntity()

# Map it to some Components, starting with a godot scenetree component
# I'm using long names to be descriptive, but eh...
var eNode = scenetreeComponentTable.set(e, SomeNodeType())
# Generally things like the transformation matrix and so forth would be their own
# components, but since the godot scenetree already bakes all that in then just
# deal with it all via the node type, you definitely lose a little efficiency doing
# it this way though since nodes involve multiple virtual calls to access and
# the usual ECS patterns entirely get rid of virtual calls with potentially only
# the occasional indirect calls inside a table (maps, etc...)

# 8x4 inventory slots
inventoryComponentTable.set(e, 8, 4)
# 1 fuel slot, accepts items that have the "burn" tag
fuelStorageComponentTable.set(e, 1, "burn")
# Give this entity the furnace component that uses the "basicFurnaceRecipes" recipes
furnaceComponentTable(e, "basicFurnaceRecipes")
# Add other components

# All of the above component mappings could also be in, say, a JSON file, and
# loaded something as such:
componentTables.map(e, "res://entity_types/basicFurnace.json")
# Or maybe via a preloaded JSON object or so

# Once at startup:

# And you could make a system something like, I'll use a GDScript class for this:
val furnaceCookSystemHandler = systems.register(FurnaceCookSystem.new())
furnaceCookSystemHandler.staticTickRate(0.05) # 20 times a second exactly

# Where the `FurnaceCookSystem` could be something like:
class FurnaceCookSystem:
  def _entity_matchers():
    furnaceBurnMatcher =
      componentTables.matcher().
      write(inventoryComponentTable).
      write(fuelStorageComponentTable).
      writeEither(inventoryChangedComponentTable, furnaceCookingComponentTable)
      read(furnaceComponentTable)
    return [furnaceBurnMatcher]

  # Assume we have matching semantics here to destructure a list, I'm lazy...
  def _entities_process([furnaceBurnEntities], delta):
    # This function takes a list of entity sets in the same order as the matchers
    # returned above.
    while entity in furnaceBurnEntities:
      val furnace = furnaceComponentTable[entity] # or .get(entity) or whatever API
      val cooking = furnaceCookingComponentTable[entity]
      if cooking == null or cooking.cookTimeRemaining <= 0:
        if cooking != null:
          if inventoryComponentTable.put(item) == False: # No space, try later
            continue
        # Get next item that has a "burnable" tag, if any
        val item = inventoryComponentTable[entity].getAndRemoveFirstOf("burnable")
        if item == null:
          furnaceCookingComponentTable.remove(entity)
        else:
          cooking = furnaceCookingComponentTable.set(entity, item, furnace.cookTime * getCookTimeModifierOfItem(item))
      else:
        cooking.cookTimeRemaining -= delta

 # ... whatever other functions are useful to the system

# Then of course just with the right components on any entity it will just work
# 'as' a furnace.  You can have a whole variety of 'generic' systems that can be
# mixed and match with impunity.  If you want a random rock that can be a furnace
# then just add the proper components, or if you want an Ent that can both be
# chopped down like a tree for wood but will also attack the player then just add
# the proper components, etc.... etc....

@MisteriGM : Satu tip: sinyal. Api dapat membakar sinyal (target) di mana targetnya adalah Kayu Anda.

Maaf maksud saya skrip bukan instance. Saya ingin skrip berinteraksi tanpa memerlukan simpul di pohon Godot.

Maaf maksud saya skrip bukan instance. Saya ingin skrip berinteraksi tanpa memerlukan simpul di pohon Godot.

Mungkin saya salah memahami masalah Anda, tetapi saya cukup yakin Anda sudah dapat melakukannya dengan membuat kelas di GDScript. Anda masih memerlukan pemuatan otomatis atau setidaknya satu skrip pada simpul untuk berfungsi sebagai titik masuk.

Juga, sudahkah Anda mencoba C#? Jika Anda mencoba membuat sistem kompleks yang memiliki skrip yang berinteraksi dan mengontrol node melalui sesuatu selain melampirkan skrip ke node, Anda mungkin akan memiliki waktu yang jauh lebih baik dengan C# daripada dengan GDScript untuk sistem seperti itu.

@MysteryGM Mendapatkan skrip untuk berinteraksi satu sama lain tanpa menggunakan simpul di tempat kejadian berarti Anda harus mendapatkan versi sumber skrip yang dimuat, minimal. Satu-satunya cara untuk melakukan ini di 3.0 adalah dengan preload / load skrip dengan jalur file. 3.1 menambahkan fitur "kelas skrip" untuk GDScript dan NativeScript di mana nama yang diberikan ke skrip terdaftar secara global. GDScript kemudian secara manual mengonversi pendaftaran global tersebut di mesin ke variabel global dalam bahasa tersebut.

Kemudian, jika Anda memiliki sumber daya Script , Anda dapat memanggil metode statis pada skrip atau memanggil .new() untuk mendapatkan ScriptInstance dan kemudian memanggil fungsi anggota / mengakses variabel anggota. Jika Script menurunkan Object, Reference, Resource, atau tipe non-Node lainnya, maka cukup membuat instance dari Script / ScriptInstance saja yang Anda perlukan konten statis/non-statis. Jika itu adalah Node, maka hal yang sama berlaku kecuali untuk hal-hal yang memerlukan akses SceneTree (seperti get_node ) dalam hal ini Anda harus menggunakan add_child untuk menambahkannya ke SceneTree terlebih dahulu.

Semua hal di atas berlaku untuk bahasa skrip apa pun yang digunakan dengan Godot (walaupun, preload adalah operasi khusus untuk bahasa tertentu yang saya yakini...).

skrip dengan jalur file. 3.1 menambahkan fitur "kelas skrip" untuk GDScript

Kapan 3.1 akan dirilis secara resmi?

@MysteryGM Ketika persentase penyelesaian tonggak cukup tinggi / ketika pengembang inti telah menilai kemajuannya cukup jauh sehingga mereka menganggap build itu "stabil".

Tonggak pencapaian: https://github.com/godotengine/godot/milestone/7

Sebagai perbandingan, 2.1 dan 3.0 saat ini berada pada penyelesaian 99%. Tidak yakin apakah itu status mereka ketika mereka melakukan siaran langsung.

Pada dasarnya, jawabannya adalah "ketika sudah siap".

Terima kasih atas tanggapannya dan kami mohon maaf telah menyita waktu Anda.
Sepertinya Godot tidak sesuai dengan kebutuhan kita saat itu. Mungkin di masa depan kita akan mendapatkan kesempatan untuk menggunakan mesin lagi.

Jika saya ingin Api membakar Kayu, saya juga harus memiliki Kayu->memperpanjang->Api atau Api->memperluas->Kayu.

@MisteriGM
Lihat di sini .
Solusinya (tidak peduli mesin atau bahasa) mungkin memiliki skrip "sistem" yang mengontrol interaksi antara api dan hutan. Presentasi itu berfokus pada komponen, tetapi seseorang juga dapat membuat sistem bekerja dengan objek.

Dalam C# saya dapat mengatakan bahwa Wood mengimplementasikan IBurnable yang digunakan Fire .

Hai, terima kasih atas perhatiannya yang berkelanjutan dan kami sangat berterima kasih atas dukungan @willnationsdev . Kami percaya bahwa skrip sebagai solusi sumber daya ekspor memiliki banyak potensi. Seperti yang disebutkan dalam #22660.

Karena kita masih punya waktu 10 hari untuk memutuskan mesin apa yang akan kita gunakan, kita mencoba lagi dengan Godot.
Kami telah melihat masalah alur kerja dan saya yakin programmer kami mengatakan yang terbaik:

"Pengembang Godot menyimpan setiap Masalah di Github di posnya sendiri, selalu buka satu masalah untuk satu bug , tetapi jangan biarkan alur kerja yang sama untuk mesin mereka."
Fakta bahwa kita harus membuat skrip DAN kita dipaksa untuk menambahkannya ke hierarki.

skrip "sistem" yang mengontrol interaksi antara api dan hutan. Presentasi itu berfokus pada komponen

Ya itu yang kami inginkan, bagaimana kami melakukannya di GDscript?

Dalam C# saya dapat mengatakan bahwa Wood mengimplementasikan IBurnable yang digunakan Fire.

Godot memiliki pengetikan Bebek untuk melakukan hal yang sama seperti Antarmuka. Yang kami inginkan adalah agar Pembakaran menjadi kelas yang terpisah sehingga kami dapat menggunakannya kembali, tanpa memaksa kami untuk menambahkan simpul ke hierarki.

Yang kami inginkan adalah Api, Pembakaran, Kayu. Kami tidak menginginkan Api (Kayu+Pembakaran).
Keuntungan dari alur kerja ini adalah kita dapat men-debug Burning sendiri, tanpa perlu memperbaiki Setiap objek yang bisa terbakar.

Di C# kita hanya akan mendeklarasikan Burning sebagai kelasnya sendiri. Pembakaran kelas publik dan masalah kami terpecahkan.
Di C++ kami akan Menyertakan Pembakaran dan masalah terpecahkan.

Ya itu yang kami inginkan, bagaimana kami melakukannya di GDscript?

@MisteriGM

Tanpa menyelami pengoptimalan kinerja, yang saya sarankan hanyalah memindahkan penyelesaian interaksi ke skrip sistem yang terpisah (bukan dalam api, bukan pada kayu). Sistem dalam kasus yang paling sederhana dapat menampung array dari semua objek di dunia dan menangani interaksinya. Dalam hal ini, objek tidak harus peduli tentang tipe, hanya sistem yang peduli.

Untuk membuat segalanya lebih cepat, seseorang mungkin hanya melakukan pemeriksaan untuk objek yang benar-benar bertabrakan (misalnya, dengan mengirimkan signal dari objek ke sistem saat tabrakan terjadi).

Beberapa contoh spesifik GDScript untuk referensi silang skrip (untuk versi 3.0):

Di sini Enemy bertindak sebagai tipe/antarmuka, seseorang dapat memeriksanya dengan operator is :

# Cache the enemy class.
const Enemy = preload("enemy.gd")

# Use 'is' to check inheritance.
if (entity is Enemy):
    entity.apply_damage()

Di sini runnerGame menunjuk ke adegan _autoload_ (alias singleton) dengan jalur /root/runner:

onready var runnerGame = get_node("/root/runner")
onready var runnerScript = preload("res://runner/runner.gd")

func _ready():
    runnerGame.setMode(runnerScript.SPAWN_TITLE)

Di sini kita menghubungkan tombol signal "ditekan" ke handler (yang bisa berada di objek dan skrip yang berbeda, kita menggunakan self untuk merujuk ke yang sama):

func _button_pressed(which):
    print("Button was pressed: ", which.get_name())

func _ready():
    for b in get_node("buttons").get_children():
        b.connect("pressed", self, "_button_pressed",[b])

Lihat juga dokumen di sini, ada beberapa fitur lain yang tersedia: http://docs.godotengine.org/en/3.0/getting_started/scripting/gdscript/gdscript_basics.html#inheritance

Lihat juga dokumennya di sini, ada beberapa fitur lain yang tersedia:

Terima kasih atas masukan Anda dalam topik. Masalah dengan pewarisan adalah bahwa itu hanya berfungsi jika kita mengetahui semua hubungan kelas ketika kita mengimplementasikannya.

Berikut ini contohnya:

Langkah A
MeshInstance+ HomingScript = HomingMissile .
Tapi sekarang jika saya menginginkan Ranjau Darat Homing, saya punya masalah.
(MeshInstance+ ProximityScript) = Ranjau Darat .
(MeshInstance+ ProximityScript) + HomingScript = ERROR lebih dari satu skrip
(MeshInstance+ ProximityScript) + (childNode + HomingScript ) = GAGAL karena hanya node tak terlihat yang bergerak.
(MeshInstance+ ProximityScript) + (childNode + ExtendedHomingScript ) = SUCCESS karena sekarang kita memperluas kelas Homing sehingga dapat memiliki node dari node anak. Kami mendapatkan HomingLandmine .

Kecuali sekarang dapat dikatakan bahwa Rudal Homing dan Ranjau Darat harus diperluas dari Kelas Homing.

LangkahB.
Rudal Homing[dari Homing]
HomingLandmine[from Homing] [+ ProximityScript] Script sekarang disalin dan ditempelkan ke ranjau darat.

Kemudian dalam produksi hal yang sama terjadi dengan skrip lain yang kami miliki.
LangkahC.
Ranjau Darat[dari Proximity]
ProximityAlarm[dari Proximity] [+ AlarmScript]
// Ranjau Darat Homing[dari Kedekatan] [+ Skrip Homming] // Sekarang ranjau darat kita juga bisa muat di sini.

Jadi kita harus terus melalui StepA untuk menemukan pewarisan yang tepat untuk StepB. Itu terus mengulangi pola ini melampaui StepF dll.

Kami menemukan cara untuk memperpanjang StepA, Kami hanya menghindari menambahkan skrip ke node teratas, dan selalu menjadikannya Spasial atau beberapa node utama.
(Spatial + MeshInstance+ ProximityScript) + HomingScript = HomingLandmine
Kecuali ini masalah yang sama tetapi dengan ParentSpatial yang lebih mahal; alih-alih childNode.

Saya minta maaf untuk berapa lama ini.

@MisteriGM

"Pengembang Godot menyimpan setiap Masalah di Github di posnya sendiri, selalu buka satu masalah untuk satu bug , tetapi jangan biarkan alur kerja yang sama untuk mesin mereka."
Fakta bahwa kita harus membuat skrip DAN kita dipaksa untuk menambahkannya ke hierarki.
...
Yang kami inginkan adalah Api, Pembakaran, Kayu. Kami tidak menginginkan Api (Kayu+Pembakaran).
Keuntungan dari alur kerja ini adalah kita dapat men-debug Burning sendiri, tanpa perlu memperbaiki Setiap objek yang bisa terbakar.
...
Di C# kita hanya akan mendeklarasikan Burning sebagai kelasnya sendiri. Pembakaran kelas publik dan masalah kami terpecahkan.
Di C++ kami akan Menyertakan Pembakaran dan masalah terpecahkan.

Yang harus Anda pahami adalah bahwa fungsi Godot tidak berbeda dalam kasus ini. Sementara solusi masuk adalah membuat sub-Node dengan skripnya sendiri (untuk "Pembakaran" dalam kasus ini), Anda bisa mendefinisikan Pembakaran sebagai kelasnya sendiri dan memasukkan/menggunakannya melalui fungsi statis (atau contohkan dan kemudian menggunakan properti/metode)

  • C++

    • kelas Membakar {};

    • termasuk "burning.h";

    • Membakar::mengaplikasikan(kayu, api);

    • Membakar *b = Membakar::get_singleton(); b->terapkan (kayu, api);

  • C# (diedit untuk perubahan gaya)

    • Pembakaran kelas publik {}

    • menggunakan Game.Burning;

    • Burning.apply(kayu, api);

    • Pembakaran b = Pembakaran.Instance; b.berlaku(kayu, api);

  • Skrip GD (3.1)

    • memperluas Sumber Daya # burning.gd

    • const Pembakaran = preload("res://burning.gd")



      • di 3.0, dapat menggunakan skrip umum untuk memuat konstanta untuk semua rangsangan yang biasa Anda gunakan.


        memperluas Referensi


        const Pembakaran = preload("res://burning.gd")


        const Pembasahan = preload("res://wetting.gd")


        memperluas Referensi


        const Stimuli = preload("res://stimuli.gd")


        # gunakan Stimuli.Burning atau Stimuli.Wetting


      • di 3.1, hanya bisa menggunakan kelas skrip. Pembakaran dan Pembasahan tidak memerlukan "penyertaan" karena bersifat global.


        Selain itu, jika menolak penggunaan global, dapat membuat "Stimuli" menjadi kelas skrip dengan deklarasi konstanta yang sama, sehingga selalu tersedia sebagai pseudo-namespace.



    • Burning.apply (kayu, api)

    • var b = Membakar.baru()

      b.berlaku (kayu, api)

Untuk pendekatan Unity/ScriptableObject, seseorang dapat menggunakan skrip Sumber Daya Godot untuk tujuan yang sama.

  • pengaturan dapat dikonfigurasi di Inspektur.
  • "build" fitur dapat disimpan ke file sehingga pengaturan tertentu dapat ditukar dengan mudah sesuai kebutuhan, bahkan saat runtime.
  • Editor secara otomatis membuat instance Resource pada Node menggunakan deklarasi adegan, jadi tidak diperlukan pembaruan manual. Array sumber daya tersebut dapat bekerja dengan cukup baik, meskipun, dengan sistem petunjuk tipe array rusak di 3.1 (hingga mudah-mudahan 3.2), Anda harus menulis EditorInspectorPlugin untuk menghasilkan konten Inspector dengan benar (yang sebenarnya sedang saya kerjakan di dalam FileSystemItemList repositori godot-next saya (peringatan, ini adalah WIP awal), untuk digunakan di repositori Godot-Builder saya untuk array file/direktori.

skrip "sistem" yang mengontrol interaksi antara api dan hutan. Presentasi itu berfokus pada komponen

Ya itu yang kami inginkan, bagaimana kami melakukannya di GDscript?

Cara termudah untuk melakukannya adalah dengan semacam node/adegan autoload. Alasannya adalah bahwa bahkan jika Anda hanya menggunakan satu node dengan banyak sumber daya untuk semua sistem yang berbeda (untuk meminimalkan jumlah node yang Anda gunakan), Anda mungkin masih ingin memiliki akses ke Node yang ada di pohon sehingga bahwa Anda mendapatkan akses ke waktu delta, data input, operasi hasil (terutama dikombinasikan dengan penggunaan sinyal), animasi/tween/timer node, daftarnya terus berlanjut. Selanjutnya, sebagai autoload, GDScript lagi akan menghasilkan variabel global untuk node sehingga "sistem" dapat diakses dengan nama di mana saja di basis kode Anda (pengganti lain yang cocok untuk menggunakan kelas skrip dalam kasus ini).

Saya sebenarnya memiliki refactoring besar dari plugin WIP lama, godot-skills , yang ingin saya lakukan yang saya yakini mencakup ini dan banyak lagi. Silakan baca utas reddit (maaf, panjang) tentang topik tersebut. Ini melibatkan pemeriksaan kelayakan penggunaan multithreading terkoordinasi dalam arsitektur server (mirip dengan arsitektur yang mendasari Godot) untuk menerapkan sistem interaktivitas generik dan dapat digunakan kembali yang serupa.

btw, jika Anda ingin mengobrol secara real time tentang topik tersebut, silakan pm saya di Reddit/Discord/Twitter di mana saya menggunakan nama pengguna yang sama.

@MisteriGM

MeshInstance+ HomingScript = _HomingMissile_.
Tapi sekarang jika saya menginginkan Ranjau Darat Homing, saya punya masalah.
(MeshInstance+ ProximityScript) = _Landmine_.
(MeshInstance+ ProximityScript) + HomingScript = ERROR lebih dari satu skrip
(MeshInstance+ ProximityScript) + (childNode + HomingScript ) = GAGAL karena hanya node tak terlihat yang bergerak.
(MeshInstance+ ProximityScript) + (childNode + ExtendedHomingScript ) = SUCCESS karena sekarang kita memperluas kelas Homing sehingga dapat memiliki node dari node anak. Kami mendapatkan _HomingLandmine_.

Kecuali sekarang dapat dikatakan bahwa Rudal Homing dan Ranjau Darat harus diperluas dari Kelas Homing.

Saya percaya saya kehilangan sesuatu di sini. Afaik, cara yang tepat untuk membuat simpul "perilaku komponen" adalah yang tidak mengubah dirinya sendiri, melainkan langsung memodifikasi simpul "target" di mana target default adalah induknya. Ini menghindari masalah yang Anda hadapi sepenuhnya, jika saya tidak salah.

extends Node
var src_target
export(NodePath) onready var dst_target = get_node(dst_target) if dst_target else null
func _notification(p_what):
    match p_what:
        NOTIFICATION_PARENTED:
           src_target = get_parent()
        NOTIFICATION_UNPARENTED:
           src_target = null
func _physics_process():
    # if necessary, can manually assign src_target elsewhere to be NOT a parent
    if src_target and src_target is KinematicBody2D:
        src_target.move_and_slide(...) # do logic to get parameters that move towards dst_target

Sesuatu seperti ini berarti Anda tidak perlu mengubah apa pun hanya dengan membuat simpul dengan skrip menjadi anak dari hal yang Anda inginkan untuk memiliki fitur "homing". Anda hanya perlu menetapkan nilai properti yang diekspor (baik di tempat kejadian atau saat runtime) untuk memberi tahu apa yang harus di rumah TO. Properti yang diekspor lainnya dapat digunakan untuk memodifikasi jenis gerakan dan hal itu juga dapat dialihdayakan ke Sumber Daya jika Anda ingin memiliki "build" yang berbeda. Sekali lagi, Godot memungkinkan Anda untuk menjadi sangat fleksibel dengan desain kerangka permainan Anda.

Beberapa koreksi:

 - C#
-   - public class Burning {};
+   - public class Burning {}
    - using Game.Burning;
    - Burning.apply(wood, fire); // is it :: here? I forget...
-   - Burning b = Burning::GetSingleton(); b.apply(wood, fire);
+   - Burning b = Burning.GetSingleton(); b.apply(wood, fire);

Titik koma setelah kurung kurawal kelas tidak diperlukan. Anda menggunakan titik untuk anggota statis alih-alih :: .
Sebagai catatan tambahan, konvensi untuk mengakses singleton adalah menggunakan properti (umumnya bernama Instance ) alih-alih metode.

@neikeq Terima kasih. Saya terlalu keluar dari latihan dengan C#, lol.

Adapun pendekatan "Skrip Global", saya sangat menentang ini. Itu akan mendorong para pengembang untuk membuat kode permainan mereka dengan cara yang buruk. Pertanyaan umum dari pengembang game C++ dan Java sebelumnya, ketika mereka mencoba Unity/Unreal/Godot/etc, adalah "di mana loop game utama tempat saya dapat menulis kode saya?". Menambahkan sistem seperti itu akan memungkinkan para pengembang melakukan ini, sehingga mereka mungkin akhirnya menulis kode dalam skrip global yang mereferensikan objek yang ingin mereka modifikasi alih-alih hanya menggunakan skrip pada objek.

Mungkin sebaliknya kita bisa meningkatkan kinerja barebone Node node sehingga tidak menimbulkan overhead untuk objek "komponen" yang murni menyimpan skrip. Atau mungkin bahkan simpul sederhana "skrip-skrip saja" yang terpisah.

@aaronfranke

Adapun pendekatan "Skrip Global", saya sangat menentang ini. Itu akan mendorong para pengembang untuk membuat kode permainan mereka dengan cara yang buruk. Pertanyaan umum dari pengembang game C++ dan Java sebelumnya, ketika mereka mencoba Unity/Unreal/Godot/etc, adalah "di mana loop game utama tempat saya dapat menulis kode saya?".

Seperti yang saya sebutkan, jika seseorang menolak untuk melakukan ini (cukup demikian dalam proyek besar), maka tidak ada masalah dengan hanya membuat kelas skrip global "namespace" yang mempertahankan konstanta skrip lain untuk melakukan perjalanan lebih jauh ke hierarki API. Kami hanya berbicara skrip di sini, bukan referensi simpul yang sebenarnya.

Menambahkan sistem seperti itu akan memungkinkan para pengembang melakukan ini, sehingga mereka mungkin akhirnya menulis kode dalam skrip global yang mereferensikan objek yang ingin mereka modifikasi alih-alih hanya menggunakan skrip pada objek.

Sistem ini sudah dapat diterapkan oleh siapa saja di Godot melalui autoloads (tidak ada "tambahan" fitur yang disarankan). Lebih jauh lagi, masalah yang mereka hadapi di tempat pertama adalah bahwa mereka tidak ingin menambahkan sistem itu sendiri sebagai sub-node di dunia (walaupun saya memberikan saran untuk itu juga di komentar tindak lanjut) karena mereka telah untuk memiliki simpul di sana DAN skrip pada simpul itu, dan berpotensi memfaktorkan ulang hubungan antara semua simpul dan skrip ketika mereka kemudian menyadari bahwa segala sesuatunya harus bergerak.

Mungkin sebagai gantinya kami dapat meningkatkan kinerja node barebones Node sehingga tidak menimbulkan overhead untuk "komponen" objek yang murni menampung skrip.

Dengan cara apa? Satu-satunya cara untuk melakukan ini secara transparan adalah dengan menerapkan sistem MultiScript dan ada banyak masalah yang menyertai paradigma itu. Satu-satunya alternatif lain yang dapat saya temukan ketika mencoba memecahkan masalah itu adalah sistem sifat GDScript yang saya sarankan di #23101 yang membatasi masalah MultiScript ke satu bahasa, tetapi dilengkapi dengan host sendiri untuk masalah yang lebih parah.

Atau mungkin bahkan simpul sederhana "skrip-skrip saja" yang terpisah.

Setelah kami memperbaiki sistem petunjuk tipe array di 3.2, kami akan dapat melakukannya hanya dengan...

extends Node
export(Array, Script) behaviors = []

Seseorang bahkan dapat mengimplementasikan fitur tersebut sekarang menggunakan Kamus (untuk mengakses skrip berdasarkan nama) dan EditorInspectorPlugin dari 3.1 untuk menentukan UI khusus ketika node tersebut dibuka di Inspektur (buat UI larik skrip yang diekspor, tetapi miliki itu menambahkan skrip dengan kunci yang cocok dengan nama file di bawah kap).

memperluas Sumber Daya # burning.gd

Ah, saya pikir saya menemukan masalah kita. Tak satu pun dari upaya pramuat kami diperpanjang dari sumber daya. Saya rasa tidak ada di antara kita yang tahu bahwa kita bisa membuat sumber daya khusus.

Saya juga ingin menunjukkan bahwa tidak ada orang yang berbagi permainan mereka dengan kami atau yang menjelaskan alur kerja mereka berasal dari sumber daya.
Hampir semua orang memperluas Node.js. Tidak tahu seberapa besar perbedaannya, perlu menjalankan tes.

FileSystemItemList (peringatan, ini adalah WIP awal)

Pasti harus melihat ini.

@MisteriGM

Saya rasa tidak ada di antara kita yang tahu bahwa kita bisa membuat sumber daya khusus.

Ya! Saya baru saja menambahkan bagian ke dokumen yang menguraikan prosesnya. :-D

Anda dapat memperluas jenis mesin APAPUN dengan skrip, termasuk Objek, Referensi, Sumber Daya, dan, tentu saja, Node (atau turunan kelas-kelas ini). Satu-satunya hal yang tidak dapat diperpanjang adalah lajang mesin dan editor (seperti OS, Engine, atau EditorFileSystem).

Terima kasih atas masukan Anda dalam topik. Masalah dengan pewarisan adalah bahwa itu hanya berfungsi jika kita mengetahui semua hubungan kelas ketika kita mengimplementasikannya.

Sama-sama. Saya meletakkan warisan di akhir komentar, karena tidak diperlukan untuk menerapkan sistem kayu bakar.
Tampaknya Anda sudah memikirkan solusi menggunakan paradigma yang biasa Anda gunakan, dan masalah Anda bukanlah bagaimana membuat sistem kayu bakar, tetapi bagaimana menggunakan paradigma favorit.
Saya minta maaf kalau begitu. Saya tidak terbiasa dengan pewarisan GDScript, tetapi saya yakin orang lain sudah menjawab pertanyaan Anda.

Oke, kami memiliki waktu untuk menguji metode baru dan ternyata berhasil dengan sempurna. Kami sudah dapat mengganti ratusan node dengan skrip; sangat meningkatkan kinerja.

Mempertimbangkan bahwa pemuatan awal Sumber Daya memecahkan masalah Termasuk skrip. Juga dapat digunakan sebagai alternatif untuk MultiScript dan ScriptableObject Unity dengan mengekspor variabel sumber daya dalam GDscript.
Dikombinasikan dengan fakta bahwa Dokumen telah diperbarui untuk menjelaskan sumber daya secara lebih rinci.
Belum lagi Godot 3.1 juga akan memiliki kelas skrip yang memungkinkan lebih banyak alur kerja.

Saya pikir tujuan awal dari masalah ini telah diselesaikan, dan masalah ini sekarang dapat ditutup?

Sekali lagi saya ingin mengucapkan terima kasih kepada semua orang untuk berpartisipasi dalam diskusi, dan terutama terima kasih kepada @willnationsdev yang memberikan banyak wawasan tentang mesin Godot.

@MysteryGM Saya pikir pemikiran Anda di awal utas ini dan di akhir utas ini mungkin bagus untuk ditulis di blog atau draft godot-docs. Saya pikir sebagian besar pengguna awal sering membuat kesalahan kinerja ketika mencoba mencapai organisasi skrip yang kompleks, kita perlu penulisan yang baik tentang "sebelum" vs "sesudah" dalam hal pembelajaran. Pelajaran dan pola yang kami pelajari di tutorial awal tidak akan diterjemahkan dengan baik ke game skala besar, yang bagi saya berarti kami membutuhkan lebih banyak blog / saran tentang pelajaran skala besar.

@pgruenbacher , itu adalah ide bagus. Ada dua masalah untuk tim kami dengan ini, satu hanya dua dari kami yang tahu bahasa Inggris ke tingkat yang berguna, dan kedua adalah bahwa itu akan memakan banyak waktu.

Meski begitu ada perubahan bagus bahwa kami akan membuat blog pengembangan, dan kami mencatat semua yang kami temukan. Ada kemungkinan kita akan membuat entri blog "Transisi ke Godot".

Saat ini saya sedang mengerjakan beberapa tutorial PDF "Godot crash course for artist", karena kami ingin merekrut pekerja lepas untuk tim, tetapi Godot belum terlalu dikenal.
Tutorial ini bertujuan untuk memperkenalkan Godot kepada seniman game profesional.
Setelah saya menyelesaikan ini, saya akan membagikannya dengan pengguna Godot lainnya, saya akan menyimpannya dalam PDF untuk memulai, karena lebih mudah untuk memperbaiki kesalahan saat saya masih belajar.

@pgruenbacher @MysteryGM Meskipun tidak dalam nada yang sama dari pengalaman sebelum/sesudah dengan Godot, Masalah ini dan beberapa pertanyaan terkait yang berulang telah mendorong saya untuk mulai mengerjakan artikel praktik terbaik desain adegan/skrip untuk godot-docs. Saya punya cabang di garpu saya, tetapi ini adalah atm WIP yang sangat awal.

Membaca topik seperti ini sangat mengecewakan (dalam artian membuat saya menebak-nebak jika kita memilih mesin yang tepat). Proyek kami lebih dari 15.000 LoC dan diatur dengan sempurna dan berjalan dengan baik. (Saya tidak akan membahas detail poin-poin tertentu karena orang lain di sini jauh lebih pintar dari saya).
Dengan itu, aku senang kamu akan tetap bersama Godot, MysteryGM! Def menantikan untuk membaca blog dev

Meh menurut saya game dengan logika signifikan lebih baik dengan kode
diisolasi dari mesin game, jadi itu tidak masalah
mesin bekerja. Skrip simpul saya terutama digunakan untuk rendering antarmuka
dan logika fisika. Logika permainan adalah perpustakaan bersama yang dikompilasi secara terpisah

Pada hari Rabu, 14 November 2018, Aaron-Fleisher [email protected]
menulis:

Membaca topik seperti ini sangat mengecewakan (dalam artian
membuat saya memeriksa ulang apakah kami memilih mesin yang tepat). Proyek kami baik-baik saja
lebih dari 15.000 LoC dan diatur dengan sempurna dan berjalan dengan baik. (aku tidak akan pergi
menjadi detail poin tertentu karena orang lain di sini jauh lebih pintar
daripada saya sendiri).
Dengan itu, aku senang kamu akan tetap bersama Godot, MysteryGM! Def mencari
maju untuk membaca blog dev


Anda menerima ini karena Anda disebutkan.
Balas email ini secara langsung, lihat di GitHub
https://github.com/godotengine/godot/issues/23052#issuecomment-438871197 ,
atau matikan utasnya
https://github.com/notifications/unsubscribe-auth/ADLZ9pw2-G0kE19meyi7iSkceAldfAMjks5uvLb4gaJpZM4XelSe
.

@Aaron-Fleisher

... membuat saya menebak-nebak jika kami memilih mesin yang tepat

Jika mesin yang Anda gunakan sekarang bekerja untuk Anda, bahkan jika Anda harus melakukan beberapa perbaikan, maka tidak ada alasan untuk khawatir. Anda mungkin mendapatkan beberapa pemain (atau pengembang lain) mempertanyakan kemampuan/kewarasan Anda, tapi itu hanya realitas pengembangan game. Banyak orang yang bersemangat berbicara dengan otoritas yang jelas (seringkali jauh di atas tingkat keterampilan mereka yang sebenarnya).

Anda adalah orang yang mengetahui masalah Anda, dan Anda adalah orang yang harus melakukan pekerjaan itu. Hindari menjadi lumpuh oleh apa yang akan memberi Anda produktivitas 10% -20% lagi. Simpan untuk permainan berikutnya. Atau tidak, karena Anda telah menginvestasikan banyak uang untuk mempelajari alat yang sudah Anda ketahui. Pilihanmu :)

Saya tidak tahu, saya merasa bahwa para pengembang Godot tidak tahu apa yang mereka lakukan.

Saat pertama kali menggunakan Godot 3.0.6 stable, saya dihadapkan dengan "Project Manager" yang jelek dan tidak berfungsi. Ketika saya bahkan dapat mengetahui cara kerjanya (dan itu sama sekali tidak intuitif), aplikasi mogok setiap kali saya mencoba mengunduh program contoh dari Perpustakaan Aset. Terkadang, aplikasi berhenti merespons. Terkadang, aplikasi memunculkan kesalahan misterius "kondisi ! terhubung benar". Terkadang, unduhan terhenti. Dan setiap kali, file 100MB membutuhkan waktu sekitar 10 menit untuk mengunduh sebagian besar, sedangkan saya dapat mengunduh 10GB di tempat lain dalam jumlah waktu yang sama. "Coba lagi" memulai seluruh unduhan dari awal.

Saya merasa bahwa "stabil" di sini berarti "akan selalu kacau setiap saat".

Bicara tentang kesan pertama yang mengecewakan.

@dejayc Itu aneh. Saya sendiri tidak pernah memiliki masalah dengan Manajer Proyek (dengan 3.0.6 stabil atau bahkan cabang master) pada Windows 10 atau perangkat Linux Mint saya. Saya akan merekomendasikan Anda membuat Masalah baru tentang masalah Anda di sini (karena ini sebenarnya bukan Masalah yang tepat untuk topik semacam itu), dan semoga seseorang dapat menawarkan bantuan yang lebih baik.

@dejayc
Jika kita semua menyumbang ke Patreon, proyek Godot akan dapat mempekerjakan orang kegunaan penuh waktu .

Meskipun saya setuju dengan poin-poin kecil Anda, mesin harus dipilih berdasarkan posting pemasaran di media sosial betapa pentingnya kelemahan mereka untuk proyek tertentu. Dan sayangnya semuanya memiliki _banyak_ kekurangan, yang lebih dalam dari level permukaan UI...

Yang mengatakan, saya membuka masalah saran tentang Manajer Proyek, diberikan waktu luang, saya akan mengerjakan beberapa perbaikan di area tersebut.

Saya telah bekerja dengan Unity dan Godot dan menemukan alur kerja umum dan struktur jauh lebih baik dan intuitif di Godot (khususnya model adegan daripada adegan/cetakan dari Unity, model "skrip tunggal" alih-alih banyak komponen, kecepatan saat mengunduh/menyalakan mesin dan mengekspor dan kemampuan untuk sepenuhnya bekerja offline).

Ada banyak kemungkinan alur kerja dan model di keduanya dan tidak pernah mudah untuk mengetahui mana yang lebih baik untuk Anda.

Apakah halaman ini membantu?
0 / 5 - 0 peringkat