Godot: Node EditorPlugin kustom yang lebih baik

Dibuat pada 7 Agu 2016  ·  121Komentar  ·  Sumber: godotengine/godot

Node yang dibuat oleh fungsi add_custom_type di EditorPlugin memiliki skrip terpilih yang ditetapkan saat menambahkan. Ini membuatnya hampir tidak berguna, karena Anda hanya dapat menggunakan fungsi yang ditentukan dalam skrip itu di node lain.

Ini benar-benar berbeda dari node lain dan membuat add-on node sangat tidak berguna/jauh lebih mengganggu untuk digunakan.

feature proposal plugin usability

Komentar yang paling membantu

Seperti yang saya pahami, harapannya adalah memiliki kemungkinan untuk membuat node khusus yang akan berperilaku seperti node bawaan, yaitu mereka harus memiliki fitur berikut:

  • Ikon khusus, pengidentifikasi khusus
  • Dapat dibuat instan melalui widget Add node (dan saya kira melalui skrip, jadi terkena Global Scope?)
  • Memiliki kode API khusus melalui skrip (mis RedNode2D akan diperluas Node2D , dan memiliki modulasi merah yang ditentukan melalui skrip khusus)
  • Maka simpul khusus ini harus berperilaku seperti simpul bawaan, yaitu pengguna harus dapat membuat instance tanpa skrip sama sekali (API khusus tidak akan langsung diekspos ke pengguna, seperti halnya skrip bawaan yang di-hardcode di C++), dan lampirkan skrip yang akan memperluas node kustom (misalnya extends RedNode2D ).

Itu akan menjadi harapan "alami" ketika mendeklarasikan simpul khusus, dan akan menjadi fitur yang sangat kuat; Saya menyimpulkan dari atas bahwa sejauh ini tidak berfungsi seperti ini, sebagian karena keputusan desain. Jika ada cara untuk memiliki fungsi seperti yang saya jelaskan di atas, saya yakin itu akan memiliki banyak aplikasi. Assetlib akan penuh dengan node khusus yang melakukan banyak pekerjaan di luar kotak dan dapat digunakan seolah-olah sudah ada di dalamnya.

Pembukaan kembali sampai ada konsensus tentang apa yang bisa/harus dilakukan atau tidak.

Semua 121 komentar

Saya tidak mengerti apa yang Anda maksud

@reduz ketika Anda menambahkan ke adegan sebuah simpul yang tipenya dibuat oleh sebuah plugin, itu sudah memiliki skrip plugin yang terpasang. Jadi tidak mungkin menambahkan skrip lain dengan perilaku khusus.

Tentu saja tidak, ini adalah desain inti dan tidak akan berubah.

Pada 7 Agustus 2016 18:11, "George Marques" [email protected] menulis:

@reduz https://github.com/reduz ketika Anda menambahkan ke adegan sebuah simpul yang a
ketik yang dibuat oleh plugin, skrip plugin sudah terpasang. Jadi
tidak mungkin menambahkan skrip lain dengan perilaku khusus.


Anda menerima ini karena Anda disebutkan.

Balas email ini secara langsung, lihat di GitHub
https://github.com/godotengine/godot/issues/6067#issuecomment -238108767,
atau matikan utasnya
https://github.com/notifications/unsubscribe-auth/AF-Z29F5q8PaoBv4OrzAUayzrfNjfHyZks5qdkoUgaJpZM4JejbZ
.

Ini menyedihkan. Tetapi Anda selalu dapat menambahkan skrip ke induk atau ke anak.

Menutup sebagai wontfix.

Saya mungkin salah memahami sesuatu, tetapi jika jenis khusus Anda adalah skrip,
bagaimana itu tidak dimasukkan dalam simpul yang dibuat? Itu tidak masuk akal untuk
itu menjadi berbeda

Pada 7 Agustus 2016 21:52, "George Marques" [email protected] menulis:

Ini menyedihkan. Tetapi Anda selalu dapat menambahkan skrip ke induk atau ke anak.

Menutup sebagai wontfix.


Anda menerima ini karena Anda disebutkan.
Balas email ini secara langsung, lihat di GitHub
https://github.com/godotengine/godot/issues/6067#issuecomment -238120392,
atau matikan utasnya
https://github.com/notifications/unsubscribe-auth/AF-Z27Zo4Ixvo4APSC4Fxf5ZqCJRsAxXks5qdn3igaJpZM4JejbZ
.

Saya kira itu akan membutuhkan kemampuan memiliki dua (atau lebih) skrip per node, meskipun ini benar-benar tidak masuk akal.

Godot awalnya mendukung ini, tapi itu lebih banyak masalah daripada keuntungan

Pada 7 Agustus 2016 22:36, "George Marques" [email protected] menulis:

Saya kira itu akan membutuhkan kemampuan memiliki dua (atau lebih) skrip per
node, meskipun ini benar-benar tidak masuk akal.


Anda menerima ini karena Anda disebutkan.
Balas email ini secara langsung, lihat di GitHub
https://github.com/godotengine/godot/issues/6067#issuecomment -238123729,
atau matikan utasnya
https://github.com/notifications/unsubscribe-auth/AF-Z27jidVZl-hHWW3G_ESr8Cqj3eX7Eks5qdogRgaJpZM4JejbZ
.

Masalahnya adalah bahwa node kustom hampir tidak berguna karena mereka tidak benar-benar "node kustom", mereka hanya node dasar dengan skrip yang telah ditetapkan sebelumnya dan ikon yang berbeda.
Apa yang saya harapkan dari "node khusus" adalah saya dapat memperluas simpul untuk menggunakan apa pun yang ditentukan dalam skrip. Contoh skenario:
Saya memiliki simpul khusus bernama Test yang merupakan anak dari Sprite dan menambahkan fungsi test() yang mengembalikan true . Kemudian, saya ingin membuat simpul Uji baru, menetapkan skrip untuk itu dan menggunakan fungsi test() .
Ini tidak mungkin.

Saya kira kembali ke tempat kejadian untuk mewarisi + skrip untuk memperpanjang kombo.

Nah, menjadi node yang telah ditetapkan dengan skrip yang telah ditentukan sebelumnya dan ikon yang berbeda adalah IMO
cukup kustom, tetapi jika Anda benar-benar ingin memasukkan kode kustom Anda sendiri
di sana, Anda selalu dapat mewarisi yang datang dengan node. Kita bisa
buat ini sedikit lebih mudah dari UI jika benar-benar diinginkan.

Pada Senin, 8 Agustus 2016 pukul 10:40, Dominik [email protected]
menulis:

Masalahnya adalah node kustom hampir tidak berguna karena sebenarnya tidak
"node khusus", itu hanya simpul dasar dengan skrip yang telah ditentukan sebelumnya dan berbeda
ikon. Saya kira kembali ke tempat kejadian untuk mewarisi + skrip untuk memperpanjang kombo.


Anda menerima ini karena Anda disebutkan.
Balas email ini secara langsung, lihat di GitHub
https://github.com/godotengine/godot/issues/6067#issuecomment -238240130,
atau matikan utasnya
https://github.com/notifications/unsubscribe-auth/AF-Z27eHoXwgr6buF6CCAHfxwx1dKkCiks5qdzHhgaJpZM4JejbZ
.

Saya akan senang jika itu bisa diotomatisasi/dipermudah melalui UI.

Seperti yang saya pahami, harapannya adalah memiliki kemungkinan untuk membuat node khusus yang akan berperilaku seperti node bawaan, yaitu mereka harus memiliki fitur berikut:

  • Ikon khusus, pengidentifikasi khusus
  • Dapat dibuat instan melalui widget Add node (dan saya kira melalui skrip, jadi terkena Global Scope?)
  • Memiliki kode API khusus melalui skrip (mis RedNode2D akan diperluas Node2D , dan memiliki modulasi merah yang ditentukan melalui skrip khusus)
  • Maka simpul khusus ini harus berperilaku seperti simpul bawaan, yaitu pengguna harus dapat membuat instance tanpa skrip sama sekali (API khusus tidak akan langsung diekspos ke pengguna, seperti halnya skrip bawaan yang di-hardcode di C++), dan lampirkan skrip yang akan memperluas node kustom (misalnya extends RedNode2D ).

Itu akan menjadi harapan "alami" ketika mendeklarasikan simpul khusus, dan akan menjadi fitur yang sangat kuat; Saya menyimpulkan dari atas bahwa sejauh ini tidak berfungsi seperti ini, sebagian karena keputusan desain. Jika ada cara untuk memiliki fungsi seperti yang saya jelaskan di atas, saya yakin itu akan memiliki banyak aplikasi. Assetlib akan penuh dengan node khusus yang melakukan banyak pekerjaan di luar kotak dan dapat digunakan seolah-olah sudah ada di dalamnya.

Pembukaan kembali sampai ada konsensus tentang apa yang bisa/harus dilakukan atau tidak.

+1
Ini adalah salah satu hambatan besar pertama bagi saya ketika saya mencoba untuk mem-port proyek yang sudah ada dari "OtherEngine(tm)" ke Godot. Tipe kustom, seperti @akien-mga yang dijelaskan di atas, seharusnya berperilaku seperti tipe bawaan lainnya setelah pendaftaran.

Tolong jelaskan dengan cara yang menurut Anda tidak

Pada 8 Agustus 2016 11:50, "Ralf Hölzemer" [email protected] menulis:

+1
Ini adalah salah satu penghalang jalan utama pertama bagi saya ketika saya mencoba untuk port dan
proyek yang ada dari "OtherEngine(tm)" ke Godot. Jenis khusus, seperti
@akien-mga https://github.com/akien-mga dijelaskan di atas, sebaiknya
berperilaku seperti tipe bawaan lainnya setelah pendaftaran.


Anda menerima ini karena Anda disebutkan.
Balas email ini secara langsung, lihat di GitHub
https://github.com/godotengine/godot/issues/6067#issuecomment -238261603,
atau matikan utasnya
https://github.com/notifications/unsubscribe-auth/AF-Z25PJzv9w7iXO350tRF3FcEuYQYUKks5qd0IrgaJpZM4JejbZ
.

Seperti yang telah dikatakan sebelumnya, kelemahan terbesar saat ini adalah bahwa tipe kustom tidak lebih dari cara cepat untuk membuat instance tipe dasar dari skrip tersebut dan menetapkan skrip yang sesuai untuk instance tersebut. Ini membuat memperluas simpul itu di editor dengan skrip lain menjadi tidak mungkin - seperti yang dapat Anda lakukan dengan tipe bawaan.

Tetapi juga tidak mungkin untuk membangun pohon warisan dengan simpul khusus dalam dialog "Buat Node/Sumber Daya baru" karena mereka hanya muncul di pohon ini ketika Anda mendaftarkannya dengan tipe bawaan sebagai induk melalui add_custom_type.

Sebagai contoh, mari kita asumsikan saya ingin mewarisi semua tipe kustom saya di proyek saya dari satu tipe dasar.

base.gd

extends Node
export (Color) var color

type_a.gd

extends base.gd

type_b.gd

extends base.gd

Seperti sekarang, saya harus mendaftarkan tipe-tipe seperti ini. Dalam hal ini, argumen kedua dari add_custom_type harus "Node", jika tidak, argumen tersebut tidak akan muncul di dialog.

func _enter_tree():
    add_custom_type("Base", "Node", preload("base.gd"), preload("base.png"))
    add_custom_type("TypeA", "Node", preload("type_a.gd"), preload("type_a.png"))
    add_custom_type("TypeB", "Node", preload("type_b.gd"), preload("type_b.png"))

... dan inilah hasilnya.

add_node_flat

Meskipun menyenangkan dapat mendaftarkan tipe kustom seperti ini, dialog tidak mencerminkan sifat pewarisan tipe tersebut seperti tipe bawaan lainnya. Untuk tipe bawaan apa pun, saya dapat melihat pohon itu dan melihat sekilas apa yang saya hadapi. Saya dapat, misalnya, memastikan bahwa Sprite adalah Node2D dan karenanya mewarisi semua fungsi yang disediakan oleh Node2D. Hal yang sama tidak berlaku untuk tipe kustom.

Sekarang, jika tipe kustom dapat sepenuhnya didaftarkan ke dalam lingkup global, seperti @akien-mga yang disebutkan di atas, segalanya akan lebih mudah dipahami dan digunakan.

Pertama, Anda dapat mewarisi dari tipe khusus yang dirujuk oleh nama tipe alih-alih jalur/nama file.

base.gd

extends Node
export (Color) var color

type_a.gd

extends Base

type_b.gd

extends Base

... kemudian, pendaftaran tipe kustom dapat disederhanakan seperti ini. Perhatikan parameter kedua yang hilang dari add_custom_type.

func _enter_tree():
    add_custom_type("Base", preload("base.gd"), preload("base.png"))
    add_custom_type("TypeA", preload("type_a.gd"), preload("type_a.png"))
    add_custom_type("TypeB", preload("type_b.gd"), preload("type_b.png"))

... dan Anda akan mendapatkan ikhtisar yang jauh lebih baik dalam dialog "Buat Node/Sumber Daya baru":

add_node_tree

... dan tentu saja kemampuan untuk memperluas jenis tersebut di editor dengan skrip khusus:

custom_type_no_script

... yang juga akan direferensikan dengan nama tipe alih-alih nama/jalur skrip

extends Base

Berikut contoh plugin dari atas untuk bermain-main.
addons.zip

Oh begitu.. kedua paha ini pasti bisa diperbaiki, bersama dengan
menambahkan dukungan pewarisan ke dialog pembuatan skrip

Pada 8 Agustus 2016 13:54, "Ralf Hölzemer" [email protected] menulis:

Seperti yang sudah dikatakan sebelumnya, _kelemahan terbesar_ saat ini adalah
tipe khusus tidak lebih dari cara cepat untuk membuat contoh tipe dasar
skrip itu dan tetapkan skrip yang sesuai untuk instance itu. Ini
membuat memperluas simpul itu di editor dengan skrip lain menjadi tidak mungkin -
seperti yang dapat Anda lakukan dengan tipe bawaan.

Tetapi juga tidak mungkin untuk membangun pohon warisan dengan simpul khusus di
dialog "Buat Node/Sumber Daya baru" karena hanya muncul di ini
pohon ketika Anda mendaftarkannya dengan tipe bawaan sebagai induk melalui
tambahkan_custom_type.

Sebagai contoh, mari kita asumsikan saya ingin mewarisi semua tipe kustom saya di my
proyek dari satu tipe dasar.

_base.gd http://base.gd_

memperpanjang Node
ekspor (Warna) var warna

_type_a.gd http://type_a.gd_

memperluas basis.gd

_type_b.gd http://type_b.gd_

memperluas basis.gd

Seperti sekarang, saya harus mendaftarkan tipe-tipe seperti ini. Di dalam
kasus, argumen kedua add_custom_type harus "Node", jika tidak
mereka tidak akan muncul dalam dialog.

fungsi _enter_tree():
add_custom_type("Base", "Node", preload("base.gd"), preload("base.png"))
add_custom_type("TypeA", "Node", preload("type_a.gd"), preload("type_a.png"))
add_custom_type("TypeB", "Node", preload("type_b.gd"), preload("type_b.png"))

... dan inilah hasilnya.

[gambar: add_node_flat]
https://cloud.githubusercontent.com/assets/8785013/17486294/9bcc029c-5d90-11e6-81e6-6fce6b0e7cf0.png

Meskipun menyenangkan bisa mendaftarkan tipe kustom seperti ini,
dialog tidak mencerminkan sifat pewarisan tipe-tipe seperti
tipe bawaan lainnya. Untuk tipe bawaan apa pun, saya dapat melihat pohon itu dan
melihat sekilas apa yang saya hadapi. Saya dapat, misalnya, memastikan bahwa
Sprite _adalah a_ Node2D dan karenanya mewarisi semua fungsi yang _disediakan
oleh_ Node2D. Hal yang sama tidak berlaku untuk tipe kustom.

Sekarang, jika tipe khusus dapat sepenuhnya terdaftar ke dalam lingkup global, seperti
@akien-mga https://github.com/akien-mga disebutkan di atas, semuanya akan
menjadi lebih sederhana untuk dipahami dan digunakan.

Pertama, Anda dapat mewarisi dari tipe khusus yang dirujuk oleh _type name_
alih-alih jalur/nama file.

_base.gd http://base.gd_

memperpanjang Node
ekspor (Warna) var warna

_type_a.gd http://type_a.gd_

memperluas Basis

_type_b.gd http://type_b.gd_

memperluas Basis

... kemudian, pendaftaran tipe kustom dapat disederhanakan seperti
ini. Perhatikan parameter kedua yang hilang dari add_custom_type.

fungsi _enter_tree():
add_custom_type("Base", preload("base.gd"), preload("base.png"))
add_custom_type("TypeA", preload("type_a.gd"), preload("type_a.png"))
add_custom_type("TypeB", preload("type_b.gd"), preload("type_b.png"))

... dan Anda akan mendapatkan ikhtisar yang jauh lebih baik di "Buat baru
Dialog Node/Sumber Daya":

[gambar: add_node_tree]
https://cloud.githubusercontent.com/assets/8785013/17487264/619f4da0-5d94-11e6-880f-a00791e30125.png

... dan tentu saja kemampuan untuk memperluas jenis tersebut di editor dengan a
skrip khusus:

[gambar: custom_type_no_script]
https://cloud.githubusercontent.com/assets/8785013/17487807/b54aced2-5d96-11e6-90e5-ee838b6a1335.png

... yang juga akan dirujuk oleh _type name_ alih-alih skrip
nama/jalan

memperluas Basis

Berikut contoh plugin dari atas untuk bermain-main.
addons.zip https://github.com/godotengine/godot/files/407291/addons.zip


Anda menerima ini karena Anda disebutkan.
Balas email ini secara langsung, lihat di GitHub
https://github.com/godotengine/godot/issues/6067#issuecomment -238299152,
atau matikan utasnya
https://github.com/notifications/unsubscribe-auth/AF-Z20FQioFVkVcvhhbvDQ7jQKv5De7Hks5qd19QgaJpZM4JejbZ
.

Apa yang tidak akan pernah terjadi adalah skrip menghilang dari node yang dibuat, atau
disembunyikan, Perlu dibuat jelas bahwa simpul itu ditulis, tapi
menambahkan skrip ke dalamnya masih memungkinkan untuk mengganti skrip untuk yang
mewarisi darinya

Pada 8 Agustus 2016 14:02, "Juan Linietsky" [email protected] menulis:

Oh begitu.. kedua paha ini pasti bisa diperbaiki, bersama dengan
menambahkan dukungan pewarisan ke dialog pembuatan skrip

Pada 8 Agustus 2016 13:54, "Ralf Hölzemer" [email protected] menulis:

Seperti yang sudah dikatakan sebelumnya, _kelemahan terbesar_ saat ini adalah
tipe khusus tidak lebih dari cara cepat untuk membuat contoh tipe dasar
skrip itu dan tetapkan skrip yang sesuai untuk instance itu. Ini
membuat memperluas simpul itu di editor dengan skrip lain menjadi tidak mungkin -
seperti yang dapat Anda lakukan dengan tipe bawaan.

Tetapi juga tidak mungkin untuk membangun pohon warisan dengan simpul khusus di
dialog "Buat Node/Sumber Daya baru" karena hanya muncul di ini
pohon ketika Anda mendaftarkannya dengan tipe bawaan sebagai induk melalui
tambahkan_custom_type.

Sebagai contoh, mari kita asumsikan saya ingin mewarisi semua tipe kustom saya di my
proyek dari satu tipe dasar.

_base.gd http://base.gd_

memperpanjang Node
ekspor (Warna) var warna

_type_a.gd http://type_a.gd_

memperluas basis.gd

_type_b.gd http://type_b.gd_

memperluas basis.gd

Seperti sekarang, saya harus mendaftarkan tipe-tipe seperti ini. Di dalam
kasus, argumen kedua add_custom_type harus "Node", jika tidak
mereka tidak akan muncul dalam dialog.

fungsi _enter_tree():
add_custom_type("Base", "Node", preload("base.gd"), preload("base.png"))
add_custom_type("TypeA", "Node", preload("type_a.gd"), preload("type_a.png"))
add_custom_type("TypeB", "Node", preload("type_b.gd"), preload("type_b.png"))

... dan inilah hasilnya.

[gambar: add_node_flat]
https://cloud.githubusercontent.com/assets/8785013/17486294/9bcc029c-5d90-11e6-81e6-6fce6b0e7cf0.png

Meskipun menyenangkan bisa mendaftarkan tipe kustom seperti ini,
dialog tidak mencerminkan sifat pewarisan tipe-tipe seperti
tipe bawaan lainnya. Untuk tipe bawaan apa pun, saya dapat melihat pohon itu dan
melihat sekilas apa yang saya hadapi. Saya dapat, misalnya, memastikan bahwa
Sprite _adalah a_ Node2D dan karenanya mewarisi semua fungsi yang _disediakan
oleh_ Node2D. Hal yang sama tidak berlaku untuk tipe kustom.

Sekarang, jika tipe khusus dapat sepenuhnya didaftarkan ke dalam lingkup global,
seperti @akien-mga https://github.com/akien-mga yang disebutkan di atas, hal-hal
akan lebih mudah dipahami dan digunakan.

Pertama, Anda dapat mewarisi dari tipe khusus yang dirujuk oleh _type name_
alih-alih jalur/nama file.

_base.gd http://base.gd_

memperpanjang Node
ekspor (Warna) var warna

_type_a.gd http://type_a.gd_

memperluas Basis

_type_b.gd http://type_b.gd_

memperluas Basis

... kemudian, pendaftaran tipe kustom dapat disederhanakan seperti
ini. Perhatikan parameter kedua yang hilang dari add_custom_type.

fungsi _enter_tree():
add_custom_type("Base", preload("base.gd"), preload("base.png"))
add_custom_type("TypeA", preload("type_a.gd"), preload("type_a.png"))
add_custom_type("TypeB", preload("type_b.gd"), preload("type_b.png"))

... dan Anda akan mendapatkan ikhtisar yang jauh lebih baik di "Buat baru
Dialog Node/Sumber Daya":

[gambar: add_node_tree]
https://cloud.githubusercontent.com/assets/8785013/17487264/619f4da0-5d94-11e6-880f-a00791e30125.png

... dan tentu saja kemampuan untuk memperluas jenis tersebut di editor dengan a
skrip khusus:

[gambar: custom_type_no_script]
https://cloud.githubusercontent.com/assets/8785013/17487807/b54aced2-5d96-11e6-90e5-ee838b6a1335.png

... yang juga akan dirujuk oleh _type name_ alih-alih skrip
nama/jalan

memperluas Basis

Berikut contoh plugin dari atas untuk bermain-main.
addons.zip https://github.com/godotengine/godot/files/407291/addons.zip


Anda menerima ini karena Anda disebutkan.
Balas email ini secara langsung, lihat di GitHub
https://github.com/godotengine/godot/issues/6067#issuecomment -238299152,
atau matikan utasnya
https://github.com/notifications/unsubscribe-auth/AF-Z20FQioFVkVcvhhbvDQ7jQKv5De7Hks5qd19QgaJpZM4JejbZ
.

@reduz
Apakah ada alasan teknis untuk memperjelas bahwa simpul tersebut dituliskan dan jika demikian, apakah itu harus berupa slot skrip yang ditempati?

Menurut saya cara yang agak canggung untuk menunjukkan jenis khusus dan saya pikir tidak ada yang akan datang dengan gagasan bahwa dengan mengganti skrip saat ini pada sebuah simpul, Anda mendapatkan skrip yang memperluas skrip yang sudah ada di sana. Itu bukan cara memperluas melalui skrip berfungsi untuk tipe dasar.

Dan apa yang akan terjadi jika pengguna mengosongkan bidang skrip itu? Apakah tipe kustom kembali ke skrip sebelumnya atau sepenuhnya kembali ke tipe dasar? Sekali lagi, saya tidak berpikir ini akan menjadi ide yang baik.

Sebagai gantinya, itu hanya dapat diindikasikan sebagai tipe khusus di pohon simpul atau editor properti melalui warna yang berbeda, beberapa ikon atau sesuatu yang lain, tanpa mengorbankan slot skrip yang kosong.

Apa yang tidak akan pernah terjadi adalah skrip menghilang dari node yang diinstance, atau disembunyikan, Perlu dibuat jelas bahwa node tersebut skrip, tetapi menambahkan skrip ke dalamnya masih memungkinkan untuk mengganti skrip untuk yang mewarisi darinya

Intinya di sini adalah bahwa skrip yang mendefinisikan simpul khusus _harus_ disembunyikan, karena itu bukan properti dari simpul _instanced_ tetapi dari jenisnya. Jadi skrip ini harus memberikan properti ke simpul khusus, tetapi harus tidak terlihat oleh pengguna simpul yang diinstance seperti kelas C++ dari simpul bawaan. Itu akan menyediakan API, tetapi tidak dapat dimodifikasi, hanya dapat diperpanjang. Sama seperti ketika Anda membuat instance Sprite, Anda tidak mendapatkan scenes/2d/sprite.cpp dilampirkan sebagai skrip dari simpul yang diinstance, Anda seharusnya tidak mendapatkan my_custom_node.gd dilampirkan sebagai skrip yang dapat dimodifikasi dari simpul kustom instance.

Sekarang, saya tidak tahu apakah secara teknis _mungkin_ sekarang, tetapi itu akan menjadi kasus penggunaan alami AFAIU. Jika Anda memodifikasi skrip jenis kustom, itu akan memodifikasi jenis itu sendiri, dan dengan demikian akan memengaruhi semua instance jenis ini. Tetapi node yang diinstance menggunakan tipe kustom harus memiliki skrip sendiri yang extends CustomNode .

Saya pikir fitur itu memerlukan Object untuk memiliki penunjuk tambahan ke "jenis skrip khusus dasar", karena Anda memerlukan informasi itu ketika Anda ingin menghapus skrip pengguna darinya (yang sebenarnya harus menggantikannya dengan skrip dasar).
Setelah Anda memilikinya, sisanya adalah masalah memasukkannya ke semua kasus, karena dapat menimbulkan banyak efek samping. Pada akhirnya, hanya akan ada satu skrip yang dilampirkan, hanya cara menanganinya yang berbeda.
Saya bukan penggemar berat warisan secara umum, tetapi beginilah cara saya melakukannya.

Sebenarnya, penunjuk itu bahkan tidak diperlukan. Menandai skrip sudah cukup, misalnya jika Anda menambahkan_custom_type() dengan skrip, mesin dapat menetapkan tanda pada kelas sehingga informasi tersedia, seperti "hei, kelas skrip ini adalah ekstensi jenis mesin". Menghapus skrip pengguna kemudian akan menggantinya dengan kelas skrip warisan pertama yang ditandai sebagai "tipe khusus", atau hapus jika tidak ada.

Maaf, saya menentang menyembunyikan skrip jika simpul memiliki skrip. apa itu?
titik simulasi sesuatu yang bukan?

Fakta bahwa ia memiliki skrip tidak berarti slotnya sibuk atau perlu
skrip kedua, karena Anda cukup membuat skrip baru yang mewarisi
yang sudah ada.

Apa yang dapat kami lakukan, jika Anda setuju, adalah menyembunyikan ikon skrip di pohon adegan jika
skrip yang ditugaskan adalah skrip dari tipe khusus, dan buat skrip
buat dialog secara otomatis menawarkan Anda untuk mewarisi saat pembuatan skrip.
Apakah ini cukup?

Pada 10 Agustus 2016 23:01, "Marc" [email protected] menulis:

Sebenarnya, penunjuk itu bahkan tidak diperlukan. Menandai skrip akan
cukup, misalnya jika Anda menambahkan_custom_type() dengan skrip, mesin
dapat mengatur bendera di kelas sehingga informasi tersedia, seperti "hei, ini
kelas skrip adalah ekstensi tipe mesin". Menghapus skrip pengguna akan
kemudian ganti dengan kelas skrip warisan pertama yang ditandai sebagai "custom
ketik", atau hapus jika tidak ada.


Anda menerima ini karena Anda disebutkan.

Balas email ini secara langsung, lihat di GitHub
https://github.com/godotengine/godot/issues/6067#issuecomment -239055986,
atau matikan utasnya
https://github.com/notifications/unsubscribe-auth/AF-Z2xLGOhgMk__ZoRW1neRu1aRb5Qr_ks5qeoJogaJpZM4JejbZ
.

@reduz saya pikir itu akan cukup baik :senyum:

@reduz Saya setuju, dan saya tidak mengatakan kami membutuhkan skrip kedua. Saya hanya ingin tahu apa yang akan terjadi jika Anda menambahkan skrip yang mewarisi skrip pertama (kustom yang ditentukan oleh plugin), tetapi kemudian memutuskan untuk menghapusnya. Kemudian akan mengembalikan simpul ke tipe mesin dasar tanpa skrip apa pun?

Saya kira kita entah bagaimana bisa membuatnya lebih ramah pengguna dalam hal itu

Pada 11 Agustus 2016 06:10, "Marc" [email protected] menulis:

@reduz https://github.com/reduz Saya setuju, dan saya tidak mengatakan kami membutuhkan
naskah kedua. Saya hanya ingin tahu apa yang akan terjadi jika Anda menambahkan skrip
mewarisi yang pertama (kustom yang ditentukan oleh plugin), tetapi kemudian memutuskan untuk
Singkirkan. Itu kemudian akan mengembalikan simpul ke tipe mesin dasar tanpa
naskah lalu?


Anda menerima ini karena Anda disebutkan.
Balas email ini secara langsung, lihat di GitHub
https://github.com/godotengine/godot/issues/6067#issuecomment -239109334,
atau matikan utasnya
https://github.com/notifications/unsubscribe-auth/AF-Z26JUJ0gjaCFwlsIDsINWp3_nqliwks5qeubygaJpZM4JejbZ
.

Saya menggali bagian dari ekstensi dengan Jenis yang ditentukan simpul alih-alih jalur yang dijelaskan pada komentar ini https://github.com/godotengine/godot/issues/6067#issuecomment -238299152 .

Beberapa saran lagi untuk ditambahkan:

  • node.get_type() pada tipe addon harus mengembalikan nama tipe.

Contoh:

add_custom_type("MyCustomNode", "Node2D", preload("my_custom_node.gd"), preload("icon.png"))

node.get_type() should return "MyCustomNode" instead of "Node2D"
  • Sebuah plugin dapat memperluas plugin lain berdasarkan tipenya

Contoh:
Pengguna A membuat plugin untuk pemberitahuan visibilitas yang lebih tepat berdasarkan Node2D
add_custom_type("PreciseNotifier", "Node2D", preload("precise_notifier.gd"), preload("icon.png"))

Kemudian Pengguna B mengembangkan addon Pemicu berdasarkan pemberitahuan yang tepat pada folder addon LAINNYA dengan konfigurasi lain.
add_custom_type("Trigger", "PreciseNotifier", preload("trigger.gd"), preload("icon.png"))
dan pada skrip trigger.gd dia harus memperpanjangnya dengan nama tipe juga
extends PreciseAddon
Tentu saja pengguna harus menambahkan kedua add-on untuk menggunakan pemicu

Sepertinya satu grup ingin mendefinisikan jenis simpul khusus tanpa skrip sebagai salah satu yang masih diturunkan dari jenis simpul khusus yang menjadi dasarnya sementara kelompok lain ingin mendefinisikan skenario yang sama sebagai simpul yang telah kembali ke basisnya di- Jenis mesin. Meskipun saya termasuk dalam grup sebelumnya, saya juga dapat melihat poin grup terakhir sehubungan dengan jenis kustom yang masih "ditulis" dan ingin memperjelasnya di UI.

Kompromi kemudian mungkin memiliki tombol UI tambahan pada baris node di dok pohon adegan di sebelah ikon skripnya dengan ikon semacam skrip++. Mengkliknya akan membuka jendela popup "Buat Skrip" yang khas dengan skrip yang sudah diturunkan dari tipe kustom, misalnya extends Base atau extends "Base" . Skrip yang ditentukan kemudian akan dibuat dan akan segera menggantikan apa pun skrip yang telah ditetapkan sebelumnya. Jadi Anda masih akan dengan jelas menunjukkan bahwa ada skrip yang sudah ada di node, tetapi Anda juga akan memiliki antarmuka yang familier untuk dengan mudah mengganti skrip prasetel itu.

Proposal ini mungkin akan kurang intuitif karena masih memperlakukan node kustom agak berbeda dari rekan-rekan dalam mesin mereka. Pikiran?

Memberikan cara 2 sen saya nanti pada diskusi ini, saya pikir masalahnya terletak pada kenyataan bahwa banyak node yang mewarisi addon berbagi skrip asli yang sama secara default; Saya tidak keberatan dengan visibilitas kode, seperti yang dikatakan Juan di awal utas ini, adalah pilihan desain dan juga sesuatu yang penting untuk membuat perilaku simpul transparan bagi pengembang menggunakan addon. Tetapi biasanya Anda ingin mengubah perilaku node yang berbeda dalam kode, dan saat ini satu-satunya cara untuk melakukannya adalah dengan menghapus referensi skrip asli, membuat skrip baru dan menyalin-menempelkan kode skrip dasar. Anda bahkan tidak dapat save as skrip node addon baru ke file .gd baru, karena ini akan mengubah referensi ke semua node lain menggunakan skrip asli, jadi ada salin-tempel tiga langkah ini keanehan prosedur.

Sekali lagi, tidak BAHWA rumit, hanya saja dalam kasus khusus ini, opsi save as pada editor GDScript tidak berperilaku seperti yang saya harapkan, dan saya pikir akan lebih ramah UI untuk memiliki ' salin dan simpan 'pada editor GDScript untuk memungkinkan penyesuaian cepat add-on (dan dari segi arsitektur, membuat tombol ini terlihat masuk akal karena ini adalah pendekatan yang baik untuk membuat game di Godot tanpa perlu menggunakan skrip yang diwariskan).

@henriquelalves Saya pikir menyesuaikan node kustom dalam kode pada dasarnya adalah warisan? Seperti, extends "addons/thing/thing.gd" ? Skrip yang diwarisi akan tetap melakukan hal yang sama seperti versi addon, mengingat Anda tahu apa yang Anda timpa. Tidak perlu copy/paste.

@Zylann Anda benar, tetapi biasanya saya tidak menyukai pendekatan khusus ini karena visibilitas kode dan kebiasaan penyelesaian otomatis (setidaknya pada 2.1, saya belum mengujinya sekarang). Dan sebagian besar waktu saya tidak ingin mengganti metode, hanya mengubah hal-hal tertentu yang bukan variabel yang diperluas pada skrip addon asli. Itulah yang mengganggu saya pada perilaku save as , saya tidak dapat dengan cepat membuat salinan skrip tanpa mengubah setiap referensi simpul ke skrip tersebut; dan menyelesaikan ini dengan cara yang ramah UI memecahkan masalah asli memiliki banyak node untuk disesuaikan, ditambah memiliki visibilitas kode dan semacamnya (setidaknya dalam alur kerja saya, saya bisa menjadi satu-satunya yang berpikir seperti ini haha).

@henriquelalves baik saya tidak tahan copy/paste tbh xD Dan Anda juga bisa garpu plugin dengan kontrol versionning dan menggunakannya sebagai gantinya di tempat pertama.

@Zylann Forking sebuah plugin menambahkan lebih banyak langkah ke sesuatu yang seharusnya sangat sederhana, hahaha. Saya kira saya akan tetap menggunakan copy-paste manual jika ini bukan prioritas, meskipun saya masih berpikir perilaku save as itu aneh.

@henriquelalves Salin/tempel IS forking^^ tetapi jika dilakukan tanpa kontrol versi, itu akan menggigit Anda di masa mendatang jika plugin diperbarui.

Perilaku saat ini memiliki skrip yang dilampirkan ke simpul khusus hampir tidak memberikan manfaat untuk memiliki simpul khusus itu sebagai addon versus hanya melampirkan skrip ke simpul. Satu-satunya manfaat adalah itu muncul di dialog simpul, yang sebenarnya bukan manfaat sama sekali.

Saya berada di kamp yang mengatakan simpul khusus harus berperilaku seperti tipe bawaan kelas satu. Kalau tidak, mengapa repot-repot membuat/menggunakan addon untuk itu? Agar Anda dapat melihatnya di dialog dan tidak perlu mengklik tombol tambahkan skrip?

@RodeoMcCabe Masalahnya adalah bahwa di bawah tenda, tipe kustom masih skrip berlapis di atas node dalam mesin dalam praktiknya, dan itu tidak dapat diubah karena node tipe kustom tidak dikompilasi ke dalam sumber mesin secara langsung. Apa yang perlu kita lakukan adalah memformulasikan serangkaian langkah/fitur konkret yang memungkinkan node skrip ini mensimulasikan , di mata pengguna, perilaku node dalam mesin. Sebagai contoh...

  1. Menambahkan simpul ke jendela "buat simpul" (selesai)
  2. Mengizinkan pengguna memberikan "deskripsi singkat" tekstual dari simpul untuk jendela "buat simpul" (tampaknya tidak selesai? - setidaknya, itu bukan bagian dari add_custom_type ).
  3. Mengizinkan pengguna menampilkan hierarki simpul dan menentukan tipe kustom abstrak di jendela "buat simpul". Ini kemungkinan akan melibatkan penambahan bool ke fungsi add_custom_type apakah itu tipe abstrak atau bukan. Wizard "Buat simpul" perlu diperbarui untuk memblokir pembuatan jenis kustom abstrak yang sesuai.
  4. Buat simpul SEEM seolah-olah TIDAK memiliki skrip.

    sebuah. Node tidak boleh memiliki ikon "script ada di node ini" di dok Scene. Untuk membuat segalanya lebih transparan, mungkin seharusnya ada ikon "ini adalah simpul tipe khusus". Mengklik itu kemudian dapat membawa pengguna langsung ke skrip yang ditambahkan tipe khusus. Itu merusak "perendaman", tetapi itu akan menjadi pengorbanan yang diperlukan untuk alasan kegunaan (jelas, Anda akan ingin dapat melihat dan melihat cara kerja simpul tipe khusus, jika Anda mau).

    B. Properti skrip yang ditampilkan di Inspektur harus, secara default, menunjukkan dirinya kosong, kecuali jika pengguna memuat skrip ke dalamnya, dalam hal ini skrip harus berasal dari tipe skrip yang digunakan sebagai tipe kustom. Namun, pengguna tidak perlu mengetahui lokasi file skrip jenis kustom (konsep bahwa itu adalah skrip harus disembunyikan dari mereka). Ini berarti bahwa nama string untuk kelas khusus harus dikenali oleh parser GDScript seperti kelas dalam mesin lainnya (tidak yakin seberapa mudah/sulitnya itu) atau harus ada semacam fungsi global untuk mengambil catatan melalui nama kelas, misalnya untuk skrip di add_custom_type("MyClass", "Node", load(res://addons/git-repo/api/my_class.gd), load(res://addons/git-repo/icons/icon_myclass.svg) , pengguna dapat membuat skrip dengan extends MyClass atau extends custom("MyClass") .

    C. Jika pengguna memuat skrip turunan tipe kustom ke node, hanya dengan demikian ikon "node ini memiliki skrip" akan muncul di dok Scene.

  5. Ikon editor apa pun yang digunakan untuk skrip harus ditambahkan ke blok kategori alih-alih ikon seperti kotak putih yang saat ini digunakan untuk skrip (dalam property_editor.cpp ). Ini harus menjadi bagian dari properti Kamus __meta__ untuk objek simpul tipe kustom.

  6. Ketika Anda mengklik "tambahkan skrip" pada jenis khusus, itu harus mengisi terlebih dahulu bidang "Mewarisi" dengan metode apa pun yang digunakan di 4b.
  7. Jika Anda menghapus skrip, skrip jenis khusus harus tetap ada di bawah tenda dan TIDAK dihapus. Node tipe kustom akan secara efektif menggunakan skrip tipe kustom sebagai skrip cadangan jika skrip yang dimuat disetel ke nol. Dengan demikian, Anda masih harus melihat ikon editor tipe dasar dan properti skrip di dok Adegan Editor dan dok Inspektur. Saya sudah dalam proses menggabungkan fitur untuk mengganti "Variabel Skrip" dengan nama skrip yang sebenarnya, meskipun mungkin perlu diperbarui jika semua perubahan ini ditambahkan.
  8. Object::get_script() harus mengembalikan null untuk node dengan skrip tipe khusus dan tanpa skrip yang dimuat.
  9. Object::get_property_list , dan fungsi analog untuk metode dan sinyal harus menyertakan konten skrip tipe kustom meskipun tidak ada skrip yang dimuat.
  10. Kemungkinan akan membutuhkan fungsi Objek C++ kedua seperti Object::get_custom_script() atau sesuatu sehingga mesin dapat melihat apakah ada skrip, bahkan jika sisi skrip tidak mengetahui skrip kedua ini.
  11. Upaya untuk memuat skrip yang diturunkan dari tipe non-kustom ke Obyek akan gagal dengan bersih dan melaporkan kesalahan (mungkin bool referensi &is_valid dalam fungsi terkait) untuk mengonfirmasi apakah Obyek diizinkan untuk melakukannya. Skenario Godot Editor terkait yang harus memberikan umpan balik tentang informasi ini juga perlu diperbarui untuk memperhitungkan hal ini.

Ini hanya menggores permukaan, tapi saya pikir jenis perilaku yang dicari pengguna adalah tentang ekstensif ini (jadi ini cukup intens). Kami ingin membuat keberadaan tipe kustom dapat diakses jika perlu (jadi miliki ikon tipe kustom di dermaga Scene di baris node untuk melihat skripnya), tetapi kami juga ingin menyembunyikan keberadaannya sebanyak mungkin sehingga kami dapat melihatnya mereka sebagai tipe di dalam mesin. Ini akan membutuhkan banyak pekerjaan untuk benar-benar melakukannya dengan benar karena itu akan merusak banyak hal di BANYAK tempat mungkin.

Apakah semua ini terdengar bagus? Saya yakin ada lebih banyak item yang saya lewatkan karena saya hanya merenungkannya sedikit. Jika ini terdengar gila, maka beri tahu saya. ;-)

Sunting: ah, tetapi saran reduz untuk hanya menyembunyikan ikon skrip di dok Scene jika skrip cocok dengan skrip tipe khusus juga bisa berharga. Hanya saja, metode get_script() seharusnya tetap tidak menghasilkan apa-apa. Mungkin ada cara untuk melakukannya tanpa harus membuat properti skrip terpisah pada Objek itu sendiri? Idk, karena sudah ada banyak asumsi dalam basis kode untuk 1 skrip per objek, yang menurut saya ingin kita pertahankan, tetapi sulit dipertahankan dengan konsep skrip custom_type .

Saran yang bagus, dipikirkan dengan baik. Saya pikir jika semua ini diterapkan, itu akan memberikan perilaku yang kami cari, namun saya pikir melanggar aturan 1 skrip per node bisa menjadi berita buruk yang mungkin beresonansi melalui banyak bagian kode yang tidak terduga. Ambil itu dengan sebutir garam karena saya tidak tahu basis kode dengan baik dan C++ saya biasa-biasa saja. Reduz menyatakan di atas bahwa mereka awalnya mencoba memiliki lebih dari satu skrip per node dan "itu lebih merepotkan daripada nilainya", yang kedengarannya masuk akal bagi saya.

Poin 1 hingga 4 sangat bagus, dan menurut saya dapat dicapai tanpa melanggar aturan 1 skrip. Jenis kustom abstrak jelas bukan masalah karena Anda tidak dapat membuat instance mereka dan oleh karena itu pengguna tidak dapat menambahkan skrip ke dalam editor. Namun, mungkin saja mereka mencoba melakukannya melalui kode, jadi pemeriksaan dan kesalahan yang diperlukan harus dilakukan.

Poin 6 juga bagus, dan di sinilah saya pikir kita bisa lolos dari ini. Membuat skrip baru sesuai poin 6 akan mengubah skrip yang saat ini dilampirkan ke simpul khusus menjadi skrip baru (turunan). Skrip (dasar) lama dihapus dari node. Karena skrip terlampir baru berasal dari skrip asli, semua fungsi tetap ada. Saya sering melakukan ini, di mana saya memiliki kelas dasar (abstrak atau tidak) dan melampirkan skrip turunan ke node. Perbedaannya di sini adalah bahwa skrip baru mungkin harus mengatakan extends "res://addons/path/to/base-script.gd" daripada sekadar nama simpul khusus, karena jenis khusus tidak lagi memiliki skrip yang dilampirkan .... Meskipun dipikir-pikir, remove_custom_type() tidak dipanggil, dan skrip yang dilampirkan masih berasal dari yang lama, jadi mungkin ini tidak perlu? Tolong jelaskan untuk saya tentang hal ini.

Poin 7, 8, dan 9 bagus, dan mungkin tidak terlalu sulit sambil menjaga aturan 1 skrip. 10 tidak diperlukan jika kita menjaga aturan 1-script. 11 bagus, karena ini adalah bagaimana node bawaan berperilaku jika Anda mencoba melampirkan skrip ke mereka yang tidak memperluas tipe node.

Bagaimanapun, itu terdengar seperti banyak pekerjaan, dan kami sudah dalam versi beta, jadi saya kira ini akan untuk 3.1 atau bahkan 3.2 (belum melihat peta jalan baru-baru ini).

@RodeoMcCabe Ya, ini pasti bukan untuk 3.0.

melanggar aturan 1 skrip per node bisa menjadi berita buruk yang mungkin beresonansi melalui banyak bagian kode yang tidak terduga

pikiran saya persis. Saya sedang memikirkan antarmuka publik di mana Objek mengetahui skrip cadangan kustomnya, tetapi objek lain tidak menyadarinya, dan hanya menganggap Objek memiliki satu skrip. Triknya adalah mengedit setter dan getter untuk properti skrip. Pengambil harus memeriksa nol. Jika itu nol, itu harus mengembalikan skrip cadangan. Setter juga harus memeriksa ulang apakah ada skrip baru yang memperluas skrip cadangan, jika tidak, ia akan melaporkan kegagalan.

Jenis kustom abstrak jelas bukan masalah karena Anda tidak dapat membuat instance mereka dan oleh karena itu pengguna tidak dapat menambahkan skrip ke dalam editor.

Tidak ada tipe abstrak di sisi skrip (afaik). Apakah Anda mengatakan Anda tahu cara membuat skrip abstrak? Metode can_instance diekspos ke sisi skrip, tetapi yang dilakukannya hanyalah memeriksa apakah skrip itu sendiri valid dan, jika itu adalah alat, apakah ScriptServer telah mengaktifkan skrip saat ini. Itu tidak ada hubungannya dengan abstraksi tipe skrip, saya rasa tidak.

Anda harus dapat memeriksa apakah kelasnya abstrak agar metode CreateDialog::_update_search mengetahui kapan harus membuat teks menjadi abu-abu/tidak dapat dipilih, dll.

FYI, saya membuat masalah tentang bagian abstrak dari masalah (#13401).

Saya pikir secara keseluruhan itu akan bisa dilakukan jika kita hanya menambahkan backup_script private member ke tipe Object , dan kemudian menggunakannya untuk melakukan pemeriksaan properti script .

Apa yang saya lakukan pada node kustom saya adalah mewarisi skrip dasar, yang membuat skrip node kustom kosong secara default...


Pewarisan otomatis akan memengaruhi plugin itu sendiri, dan tidak mungkin membuat lebih dari satu tanpa menduplikasi plugin, bukan?.

Multiscript ditambahkan untuk kedua kalinya tahun ini dan mudah untuk mematikannya lagi (menimbulkan banyak masalah).


Mengizinkan adegan sebagai basis untuk simpul khusus alih-alih skrip dapat membiarkan root bebas dari skrip.

Apa yang saya lakukan pada node kustom saya adalah mewarisi skrip dasar, yang membuat skrip node kustom kosong secara default...

Maaf, apakah Anda mengatakan ini entah bagaimana memengaruhi abstraksi atau saran lain yang saya buat sebelumnya? Saya tidak melihat di mana ini terhubung ...

Pewarisan otomatis akan memengaruhi plugin itu sendiri, dan tidak mungkin membuat lebih dari satu tanpa menduplikasi plugin, bukan?

Apakah Anda mencoba untuk mengatakan bahwa mencoba memasukkan plugin ke dalam folder /addons/ dua kali dan mengaktifkan keduanya di bagian Plugin Pengaturan Proyek akan menyebabkan masalah entah bagaimana (maksud saya, kedengarannya cukup normal jika plugin Anda menambahkan kustom jenis. Tidak dapat memiliki beberapa jenis khusus yang ditentukan dengan nama yang sama).

Tidak yakin apa yang Anda maksud dengan "tidak mungkin membuat lebih dari satu tanpa menduplikasi plugin." Anda dapat membuat beberapa instance dari node tipe kustom dengan baik(?) karena itu hanya akan membuat node dan melampirkan otomatis skrip tipe kustom yang ditentukan. Saran saya akan melibatkan mengubah proses pembuatan skrip CreateDialog menjadi ...

  1. Biarkan skrip bawaan simpul memutuskan apakah simpul dapat dibuat atau tidak (abstrak).
  2. Buat tipe simpul bawaan.
  3. Tetapkan skrip khusus sebagai properti backup_script node (tidak terpapar ke API skrip).
  4. Biarkan kode Object milik node menangani tugas menipu orang lain agar melihat backup_script sebagai properti script resmi pada objek.
  5. Perbarui metadata untuk ikon editor
  6. Perbarui metadata untuk deskripsi singkat(?)

...dari pada...

  1. Buat simpul bawaan.
  2. Lampirkan skrip jenis khusus sebagai properti script .
  3. perbarui data meta untuk ikon editor khusus.

Multiscript ditambahkan untuk kedua kalinya tahun ini dan mudah untuk mematikannya lagi (menimbulkan banyak masalah).

Saya setuju. Saya pikir objek multiscripting akan menjadi ide yang buruk pada saat ini (dan bahkan tidak benar-benar diperlukan). Bukan itu yang saya sarankan. Dalam tampilan publik, Object seharusnya masih memiliki hanya 1 skrip, tetapi saya menyarankan agar skrip cadangan tersedia yang mengambil alih peran sebagai skrip (jadi tetapkan sendiri ke properti script ) setiap kali properti script utama disetel ke null / dibongkar, dll. Ini akan memungkinkan kita untuk mendukung "tipe khusus" secara lebih efektif tanpa mengubah antarmuka basis kode ke kelas Object. Kami kemudian dapat memiliki penyetel/pengambil khusus untuk properti skrip cadangan ini yang memungkinkan kode (seperti kode yang menetapkan skrip jenis khusus di CreateDialog ) menambah atau menghapus keberadaannya. Dengan cara ini, ini merupakan modifikasi keikutsertaan pada cara kerja properti script dan akan menghasilkan perubahan yang diperlukan pada mesin secara komparatif.

Saya pikir opsi baru untuk menu kontekstual pada node akan menyelesaikan masalah ini "Ganti skrip untuk warisan" ini bahkan dapat memiliki submenu dengan semua skrip yang terdeteksi yang mewarisi dari saat ini dan "Skrip baru" di bagian akhir, ketika mengkliknya skrip baru dialog akan menampilkan jalur skrip pada bidang "memperluas".

Bukankah lebih mudah dan lebih transparan untuk hanya menambahkan alat editor "Ganti dan Warisan skrip"? Maksud saya, ini hanya masalah karena ketika kami membuat simpul Addon, kami mengharapkannya tanpa skrip - tetapi simpul addon sebenarnya hanyalah simpul khusus yang Anda tambahkan ke pohon Buat Node, dan pengguna harus mengetahuinya. Dari perspektif UX (saya bukan ahlinya), saya tidak berpikir kita harus mengorbankan transparansi demi kenyamanan.

@MarianoGnu @henriquelalves Tak satu pun dari mereka yang benar-benar sama. Implikasi dari "tipe kustom" adalah bahwa Anda sedang mensimulasikan tipe node dalam mesin. Itu menyiratkan bahwa skrip itu sendiri tidak dapat dihapus. Fungsionalitas yang ditanamkan ke dalam node sudah ada di dalamnya, dengan cara yang sama seperti Anda tidak dapat menghapus Node2D-ness dari Node2D untuk membuatnya bertindak seperti Node2D murni.

Posting upvoted populer Akien di atas mencakup detail serupa:

Intinya di sini adalah bahwa skrip yang mendefinisikan simpul khusus harus disembunyikan, karena itu bukan properti dari simpul yang diinstance tetapi dari jenisnya. Jadi skrip ini harus memberikan properti ke simpul khusus, tetapi harus tidak terlihat oleh pengguna simpul yang diinstance seperti kelas C++ dari simpul bawaan. Itu akan menyediakan API, tetapi tidak dapat dimodifikasi, hanya dapat diperpanjang.

Jika kami membuat alat editor apa pun untuk memfasilitasi hal-hal "ganti skrip untuk yang diwarisi", itu akan keren, tetapi fungsi apa pun seharusnya tidak dapat melihat lapisan hierarki skrip pada atau di bawah skrip tipe khusus karena seharusnya untuk mensimulasikan perilaku "bawaan".

Faktanya, agar konten dapat diakses dari gdscript_parser dan konten skrip lainnya, mungkin yang terbaik adalah memastikan informasi jenis kustom disertakan dalam singleton ClassDB daripada hanya EditorNode::get_editor_data().get_custom_types() sejak modul tidak akan memiliki akses ke informasi itu, tetapi benar-benar harus memiliki akses ke sana.

saya tidak punya masalah pribadi dengan skrip yang diekspos, ini benar-benar masalah terminologi dan filosofi, menurut apa yang Anda sebutkan, apa yang bisa dilakukan adalah menambahkan Kelas baru ke ClassDB dan menambahkan properti skrip ke kelas itu alih-alih simpul dan kelas harus memeriksa apakah skrip metode itu ada dan memanggilnya sebelum memanggil induk kelasnya. Saya percaya itu mungkin, tetapi akan merusak kompatibilitas dengan versi sebelumnya jika tidak dilakukan sebelum RC1

@willnationsdev Begitu , saya hanya tidak sepenuhnya setuju dengan tipe khusus yang diperlakukan sebagai node dalam mesin. Bagi saya 'kekuatan' Editor Addons terletak pada betapa mudahnya membuat "paket" node kustom dan alat editor dan membagikannya melalui github; semua alat dan simpul itu, pada kenyataannya, hanya adegan dan skrip yang dapat Anda salin-tempel, tetapi Godot menyediakan Addon API untuk memfasilitasi ini. Ketika saya pertama kali menggunakannya, saya juga mengharapkan Addons menjadi tanpa skrip, tetapi hanya karena mesin itu sendiri tampak seperti memperlakukannya sebagai node dalam mesin, dan itu adalah masalah UX, bukan arsitektur. Apa yang saya pikir akan memperbaiki ini adalah:

  1. Jenis khusus di pohon Buat Node ditampilkan dengan warna berbeda (dengan jelas menunjukkan bahwa itu adalah jenis khusus).
  2. Saat Anda menambahkannya ke adegan Anda, ikon skrip ada di sana, tetapi sedikit transparan (menunjukkan bahwa mereka memiliki skrip default, tetapi dapat diganti). Mengklik ikon skrip akan menampilkan skrip tipe khusus pada editor.
  3. Tombol "Menambahkan Skrip" pada tipe kustom akan secara otomatis mengisi opsi "Mewarisi" dengan skrip tipe kustom.

Sekali lagi, saya jelas bukan ahli, jadi asumsi awal saya tentang Tipe Kustom != In-Engine Node mungkin salah; juga, solusi Anda adalah yang paling jelas yang saya lihat di utas ini, jadi saya benar-benar mengerti jika pengembangan Godot berjalan seperti itu.

EDIT: Saya membacanya lagi, dan "solusi" saya pada dasarnya adalah 6 langkah solusi pertama Anda, hahaha.

@henriquelalves @MarianoGnu Saya pikir campuran itu pasti diperlukan. Memiliki kelas tipe khusus yang ditambahkan ke ClassDB adalah suatu keharusan. Benar-benar menyukai ketiga saran yang Anda miliki Henrique. Terutama ide 2 (jauh lebih baik daripada saran ikon tipe khusus saya yang terpisah). Dan saya setuju dengan Anda bahwa kita perlu memastikan bahwa "APA jenis kustom" tetap transparan sampai tingkat tertentu. Saya merasa keseimbangan perlu dipertahankan: orang harus dapat memahami apakah sesuatu adalah tipe kustom DAN apa artinya, tetapi kita juga harus melakukan sebanyak yang kita bisa untuk membuat tipe kustom terasa seperti tipe mesin.

@willnationsdev Saya mengambil ini dari assetlib, memindahkan kode simpul khusus ke skrip "basis":
collision_path_2d-1-modified.zip

Masalah langsung yang saya lihat adalah plugin memuat skrip, dan skrip itu unik, jika saya menambahkan simpul khusus lain, itu akan memiliki skrip _yang sama_.

Lalu, apa arti penggantian skrip untuk plugin dalam kasus itu? (mungkin tidak ada, saya tidak yakin).

Jika tidak ada masalah saat mengganti skrip (mode alat mungkin tidak menyenangkan dalam beberapa kasus), menu untuk node khusus dapat menambahkan entri "perpanjang skrip khusus" untuk melakukan proses penggantian itu.

@henriquelalves @eon-s Saya pikir kami memikirkan hal yang sama. Saya setuju dengan ini menjadi masalah UX lebih dari apa pun. Sejauh ini saya memihak pada pendekatan ini karena saya pikir itu menjaga hal-hal sesederhana mungkin, yang selalu merupakan IMO yang baik.

Jika tidak ada masalah saat mengganti skrip (mode alat mungkin tidak menyenangkan dalam beberapa kasus), menu untuk node khusus dapat menambahkan entri "perpanjang skrip khusus" untuk melakukan proses penggantian itu.

Saya pikir karena skrip perluasan harus mewarisi dari skrip plugin, menggantinya tidak akan menjadi masalah. Tapi, sekali lagi, saya tidak begitu akrab dengan basis kode. Bagaimanapun, saya telah memberikan 2 sen saya, saya akan menyerahkannya kepada pengembang nyata dari sini;)

@willnationsdev Maaf, saya bingung tentang hal-hal abstrak. Kelas dasar "abstrak" saya hanya memiliki pernyataan cetak di _init() untuk memberi tahu saya jika saya membuatnya secara tidak sengaja ....

Hanya untuk berpadu di sini, jenis simpul khusus harus benar-benar berperilaku seperti jenis mesin, termasuk mengatur skrip khusus, kemampuan untuk merujuk dan mewarisi dengan nama di GDScript, dan ketidakmampuan untuk menghapus skrip dasar jenis. Ini meniru perilaku node yang diterapkan oleh mesin, mempromosikan konsistensi internal dan kemudahan penggunaan.

Mengenai masalah menunjukkan bahwa itu adalah simpul "khusus", saya mengusulkan bahwa simpul tersebut memiliki entri di dropdown Inspektur di atas "Show In Help" yang menunjukkan file skrip dasar objek. Dari sudut pandang pengguna dan pengembang, Anda harus mengetahui bahwa ini adalah simpul khusus hanya dengan menggunakannya (siapa lagi yang menambahkannya ke proyek?), dan tujuan dari simpul "khusus" (IMO) adalah untuk memungkinkan pendefinisian jenis dalam GDScript yang tidak dapat dibedakan dari jenis mesin built-in.

@Web-eWorks Saya sebenarnya sedang mengerjakan ini (saat ini) dan saya telah menyelesaikannya dengan baik (masih memiliki sedikit cara untuk melakukannya). Saya telah menyiapkan skrip cadangan di kelas Object dan membuat penyimpanan untuk tipe khusus di ClassDB bersama dengan memperbarui metode EditorPlugin untuk menggunakan API baru. Masih harus membuat pembaruan untuk fungsi ClassDB terkait (hal-hal seperti can_instance dan get_parent_class , dll.) dan memperbarui semua hal Editor / CreateDialog.

@willnationsdev perlu dicatat bahwa mendaftar di ClassDB juga berarti orang yang membuat plugin harus mengawali semua kelas mereka untuk mencegah tabrakan ^^"

@Zylann Ya, sayangnya itu perlu.

Pada titik ini saya pikir saya telah menyelesaikan sebagian besar binding dan perubahan inti. Ini hanya masalah memperbarui kelas Editor, CreateDialog, dan EditorHelp / DocData sekarang (dan kompiler GDScript).

Seperti yang saya sebutkan sebelumnya .. Saya masih tidak berpikir solusi yang diusulkan itu baik.
Silakan periksa dengan saya sebelum mencoba sesuatu yang kemungkinan besar akan terjadi
ditolak.

Pada 7 Februari 2018 20:05, "Will Nations" [email protected] menulis:

@Zylann https://github.com/zylann Ya, itu perlu,
Sayangnya.

Pada titik ini saya pikir saya telah menyelesaikan sebagian besar binding dan inti
perubahan. Ini hanya masalah memperbarui Editor, CreateDialog, dan
Kelas EditorHelp / DocData sekarang.


Anda menerima ini karena Anda disebutkan.
Balas email ini secara langsung, lihat di GitHub
https://github.com/godotengine/godot/issues/6067#issuecomment-363893711 ,
atau matikan utasnya
https://github.com/notifications/unsubscribe-auth/AF-Z2xIYRcs0BFDqTyiFwqlhQWTqjEZtks5tSgIVgaJpZM4JejbZ
.

@reduz Yah, saya sudah mencoba mempertimbangkan masalah yang Anda buat sebelumnya.

Saya tidak menerapkan sistem multi-skrip apa pun. Saya juga tidak membuat skrip menyamar sebagai objek ClassInfo di ClassDB. Yang saya lakukan sejauh ini adalah melampirkan skrip (melalui RefPtr) ke hierarki pewarisan di ClassDB. Kelas Object hanya akan menggunakan "backup_script" setiap kali penugasan skrip reguler mencoba melanggar hierarki pewarisan skrip cadangan.

Oh begitu.. apa gunanya kasus ini?

Pada 7 Februari 2018 20:32, "Will Nations" [email protected] menulis:

@reduz https://github.com/reduz Yah, saya sudah mencoba untuk mempertimbangkan
memperhitungkan kekhawatiran yang telah Anda uraikan sebelumnya.

Saya tidak menerapkan sistem multi-skrip apa pun. saya juga tidak
membuat skrip menyamar sebagai objek ClassInfo di ClassDB. Semua yang saya miliki
yang dilakukan sejauh ini adalah melampirkan skrip (melalui RefPtr) ke warisan
hierarki di ClassDB. Kelas Object hanya akan menggunakan a
"backup_script" setiap kali penugasan skrip reguler mencoba untuk melanggar
pada hierarki pewarisan skrip cadangan.


Anda menerima ini karena Anda disebutkan.
Balas email ini secara langsung, lihat di GitHub
https://github.com/godotengine/godot/issues/6067#issuecomment-363900920 ,
atau matikan utasnya
https://github.com/notifications/unsubscribe-auth/AF-Z2yn68Iy6AgAKJHZ4qImH4UBAm5skks5tSghSgaJpZM4JejbZ
.

Kasus penggunaan adalah ketika seseorang ingin memperkenalkan tipe baru Node ke mesin menggunakan EditorPlugin, tetapi mereka tidak ingin tipe skrip dari node tersebut dapat diedit (mereka ingin interaksi dengannya meniru tipe dalam mesin ). Jadi, misalnya, jika saya mencoba get_script() pada node dengan hanya skrip cadangannya, maka itu akan mengembalikan null. Jika saya mencoba set_script(null) , maka skrip akan disetel ke skrip cadangan. Jika saya mencoba set_script(a_script) , maka skrip hanya akan berhasil ditetapkan jika skrip baru berada dalam hierarki pewarisan skrip cadangan.

Untuk UX, saya berencana membuat ikon skrip muncul di editor sebagai ikon transparan jika hanya skrip cadangan yang ada. Dalam hal ini, tombol untuk menambahkan skrip akan tetap menjadi tombol "tambah skrip" daripada tombol "hapus skrip", dan mengkliknya akan mengisi teks dengan nama jenisnya terlebih dahulu (walaupun, saya mungkin perlu membuat itu diisi dengan jalur skrip jika pengguna mengubah jenis skrip dari GDScript / VisualScript, dll.). Setelah skrip yang berbeda ditetapkan, ikon transparan akan menjadi buram lagi. Mengklik ikon skrip dalam kedua kasus akan membawa Anda ke kode sumber skrip aktif (kode sumber skrip cadangan jika tidak ada skrip lain).

Saya harus mengakui bahwa saya tidak benar-benar melihat manfaat dari ini, jadi sekali lagi apa?
kasus penggunaan khusus yang Anda pikirkan?

Pada 7 Februari 2018 20:46, "Will Nations" [email protected] menulis:

Kasus penggunaannya adalah ketika seseorang ingin memperkenalkan Node tipe baru ke
mesin menggunakan EditorPlugin, tetapi mereka tidak menginginkan jenis skrip
simpul itu dapat diedit (mereka ingin interaksi dengannya meniru dan
tipe dalam mesin). Jadi, misalnya, jika saya mencoba get_script() pada sebuah node
dengan hanya skrip cadangannya, maka itu akan mengembalikan nol. Jika saya mencoba untuk
set_script(null), maka skrip akan disetel ke skrip cadangan. Jika saya
coba set_script(a_script), maka itu hanya akan berhasil ditetapkan
skrip jika skrip baru berada dalam hierarki pewarisan cadangan
naskah.

Untuk UX, saya berencana membuat ikon skrip muncul di editor sebagai
ikon transparan jika hanya skrip cadangan yang ada. Dalam hal itu,
tombol untuk menambahkan skrip akan tetap menjadi tombol "tambahkan skrip" daripada a
tombol "hapus skrip", dan mengkliknya akan mengisi teks dengan nama sebelumnya
dari jenisnya (walaupun, saya mungkin perlu membuatnya terlebih dahulu dengan jalur skrip
jika pengguna mengubah jenis skrip dari GDScript / VisualScript,
dll.). Setelah skrip yang berbeda ditetapkan, ikon transparan
akan menjadi buram lagi. Mengklik ikon skrip dalam kedua kasus akan
membawa Anda ke kode sumber skrip aktif (kode sumber skrip cadangan jika
tidak ada skrip lain yang ada).


Anda menerima ini karena Anda disebutkan.
Balas email ini secara langsung, lihat di GitHub
https://github.com/godotengine/godot/issues/6067#issuecomment-363904934 ,
atau matikan utasnya
https://github.com/notifications/unsubscribe-auth/AF-Z26oeOMT4HpjzDsX8eygMSeUhbTgVks5tSgurgaJpZM4JejbZ
.

Kasus penggunaan tingkat tinggi adalah mengizinkan plugin (EditorPlugins, sistem PluginScript/SubModule) untuk menentukan jenis simpul kustom 'bukti-bodoh'. Saat ini, sistem tipe kustom adalah pabrik tipis untuk "skrip pada node", yang memiliki banyak masalah alur kerja dan kegunaan jika Anda mencoba membangun tipe node baru, yang paling tidak adalah ketidakmampuan total untuk dengan mudah, intuitif, dan efektif perluas node khusus dengan kode gameplay (bertentangan dengan node bawaan). Masalah yang lebih mendesak adalah ketidakmampuan untuk membuat node kustom yang mewarisi dari node kustom lainnya.

Beberapa kasus penggunaan khusus adalah untuk membuat node tingkat rendah: mungkin implementasi GridMap voxel berbasis marching-cubes untuk medan yang dapat dihancurkan, ala Minecraft atau sistem medan lainnya menggunakan marching-cubes/kontur ganda; jenis Kontrol khusus (wadah menu melingkar, seperti yang diterapkan di banyak game modern, semua jenis Kontrol tingkat rendah yang cukup tinggi untuk berada di luar spesifikasi mesin); dan di mana pun Anda ingin membuat plugin yang mendaftarkan node baru. Dalam setiap kasus ini, Anda biasanya ingin menambahkan skrip khusus untuk menangani kode gameplay, dan memisahkannya dari kode "implementasi" (ditulis dalam GDScript/GDNative).

Saya pikir apa yang gagal dikomunikasikan di sini adalah bahwa tujuannya adalah untuk membuat simpul khusus berperilaku seperti simpul mesin tanpa harus menulis modul mesin dan mengkompilasinya.

Peningkatan ini tidak serta merta didorong oleh fitur tertentu (walaupun ada banyak), melainkan oleh alasan "cara saat ini terbelakang, rapuh, dan membosankan". Jika diterapkan sepenuhnya, sistem ini akan memungkinkan metode yang sangat kuat untuk memperluas tipe bawaan mesin dari GDScript / GDNative tanpa perlu mengkompilasi ulang mesin. Dari sudut pandang desain, ini secara harfiah merupakan peningkatan langsung dari sistem saat ini.

Jika Anda menginginkan kasus penggunaan tertentu setelah semua itu: seluruh plugin / ekosistem AssetLibrary .
Itulah cakupan manfaat dari perubahan ini.

Oke, jadi di sini adalah contoh eksplisit:

Saya memiliki plugin yang sedang saya kerjakan, godot-skills , yang memperkenalkan berbagai jenis node baru:

Efek: nodifikasi Functor
Targeter: serupa, tetapi hanya menemukan dan mengumpulkan node lain
Keahlian: menggabungkan hierarki Penarget dan Efek untuk menemukan simpul dan menerapkan efek ke semuanya
SkillUser: "memiliki" beberapa Skill

Saya ingin setiap node ini menjadi hal-hal yang dapat dibuat dan ditambahkan pengguna ke adegan secara langsung. Namun, masing-masing dan setiap node ini dirancang untuk berfungsi sebagai tipe dasar. Mereka tidak memiliki banyak fungsi di luar kotak, dan harus memiliki skrip turunan yang ditempatkan ke setiap simpul yang seharusnya mereka terlibat. Untuk kasus penggunaan seperti ini, akan berguna untuk membuat simpul dari mana Anda tidak ingin pengguna dapat menghapus serangkaian fungsionalitas skrip tertentu. Misalnya, saya ingin mencegah pengguna menempatkan skrip yang bukan berasal dari Target ke node Targeter yang mereka tambahkan ke adegan mereka. Ini karena ada fungsionalitas instan yang Skill dapatkan dari memiliki Targeter sebagai anak-anak (mirip dengan node Area2D dan CollisionShape2D).

Alur kerja saat ini mengharuskan pengguna...

  1. Tambahkan simpul tipe khusus
    2a. Hapus skrip yang dilampirkan dan klik tombol tambahkan skrip ATAU
    2b. Setel properti skrip pada simpul
  2. Temukan di jendela dialog tempat EditorPlugin menyimpan skrip jenis khusus yang ingin Anda peroleh.

Sistem ini akan memungkinkan Anda untuk mengganti semua ini hanya dengan:

  1. Tambahkan jenis simpul khusus.
  2. Tambahkan sebagai skrip (yang secara otomatis mulai menurunkan skrip tipe khusus)

Pengguna akan dapat secara dinamis menambahkan tipe kustom mereka sendiri yang berasal dari tipe dalam mesin (untuk kegunaan yang lebih sederhana). Ini juga akan memperkuat keamanan fungsionalitas plugin dengan menegakkan keberadaan fungsionalitas skrip pada node yang bersangkutan. Saat ini, pengguna dapat dengan mudah menghapus skrip dan merusak sesuatu (tidak diinginkan). Selain itu, jika seseorang ingin "menghapus" skrip pada node, maka node tersebut tidak boleh kehilangan fungsionalitas tipe kustomnya (ini yang besar). Itu harus kembali memiliki skrip tipe khusus.

Oke, jadi pembaruan. Saat ini saya memiliki yang berikut ini.

  • ClassDB sekarang dapat menambah dan menghapus tipe kustom secara langsung.
  • EditorPlugin memiliki metode tipe kustom serupa yang menambah dan menghapus bukan hanya tipe kustom, tetapi data terkait editor lainnya seperti ikon. Metode ini terhubung ke sinyal baru yang dipancarkan setiap kali EditorPlugin diaktifkan/tidak aktif.
  • GDScripts sekarang dapat mewarisi dengan benar langsung dari nama-nama tipe kustom yang akan diwarisi dari skrip.
  • Dock adegan akan membuat ikon skrip transparan ketika skrip saat ini cocok dengan skrip tipe kustom node. Mengkliknya akan membuka skrip jenis khusus di editor. Saat dalam keadaan ini, tombol "tambahkan skrip" ditampilkan daripada tombol "hapus skrip". Jika dipilih, tombol ini akan mengisi kolom "Mewarisi" terlebih dahulu dengan nama skrip tipe khusus (jika bukan nol).
  • Setiap upaya untuk menghapus skrip akan menyebabkan skrip jenis khusus ditetapkan ulang sebagai nilai skrip. Dengan demikian, untuk menghapus skrip, Anda harus terlebih dahulu menghapus nilai skrip jenis khusus dengan set_custom_script(RefPtr()); .
  • Dialog buat simpul dengan benar menunjukkan hubungan pewarisan dan simpul abstrak untuk tipe khusus.
  • File project.godot diisi dengan semua jenis kustom sehingga game yang dijalankan dapat mengaturnya di main.cpp sebelum sisa game dimulai.

Sisa tugas yang harus diselesaikan...

  • Izinkan pengguna membuat dokumen API kelas untuk tipe khusus.
  • Perbaiki bug terpisah sama sekali yang mencegah pengguna mengedit bidang Warisan di script_create_dialog.cpp .
  • Temukan cara untuk menambahkan dan menghapus tipe kustom secara dinamis dari peta/array global GDScript *
  • Terapkan dukungan jenis khusus dalam VisualScript

* Saya sebenarnya punya beberapa pertanyaan tentang ini.

Pertama, saya hanya melihat add_global_constant / _add_global di file gdscript_compiler.cpp tanpa cara apa pun untuk menghapus global dari kelas GDScriptLanguage. Apakah itu benar-benar diinisialisasi ulang setiap kali lajang ditambahkan atau dihapus? Bagaimana pengidentifikasi global diedit secara dinamis? Ini agar pengguna dapat melakukan MyNode.static_func() tanpa harus memuat skrip ke dalam variabel terlebih dahulu.

Sementara saya melakukannya, saya merasa GDScript Godot bisa mendapatkan banyak manfaat dari pengenalan namespace, terutama sebagai bagian dari perubahan ini. Kami harus menemukan pembatas yang tepat untuk menandainya, tetapi Anda dapat menghilangkan kekhawatiran tentang tabrakan nama dari jenis mesin dan plugin saat membuat skrip Anda sendiri. Misalnya, dengan asumsi \ adalah pembatas pilihan...

extends Node # an in-engine type.
extends \ # triggers an error if left alone, but would prompt a dropdown of the plugin API names for auto-completion as well as the names of any scripts in the current project that are not part of a plugin.
extends \MyPlugin\ # triggers an error if left alone, but would prompt a dropdown of the scripted types that exist for the plugin
extends \MyNode # extends my_node.gd somewhere in res://
extends \MyPlugin\MyNode # extends my_node.gd somewhere in res://addons/[my_plugin_something?]/

func _ready():
    print(\MyNode.CONSTANT) # would print CONSTANT in the current project's my_node.gd script

Pokoknya semua ini ^ hanyalah ide yang dilontarkan saat ini. Jika penspasian nama diperkenalkan, Anda bahkan dapat membuat skrip secara otomatis dikaitkan dengan nama berdasarkan nama filenya menggunakan sinyal resource_saved di EditorNode . Mereka TIDAK AKAN menjadi tipe khusus (dalam arti bahwa Anda tidak dapat menghapus skrip dari objek), tetapi mereka AKAN dapat diakses dengan nama saja yang akan sangat berguna dan intuitif. Skrip bahkan dapat mengganti penamaan otomatis default ( filename.capitalize().replace(" ", "") ?) dengan memberikan judul dengan spasi nama di bagian atas, misalnya \MyPlugin\mynode . Sekarang tiba-tiba "\MyPlugin\mynode" adalah pengidentifikasi global untuk skrip itu.

Inilah cuplikan kemajuan saya sejauh ini.

@willnationsdev tolong jangan pilih \ , itu sudah digunakan untuk melarikan diri dan multiline. . , : atau :: terlihat lebih baik.

@Zylann Saya berencana menggunakan pembatas sebagai awalan untuk setiap node yang ditambahkan ke proyek juga. Jadi, misalnya, skrip di res://container.gd tidak ingin bertabrakan dengan kelas Container yang sebenarnya. Jika kita menggunakan titik (.), maka akan terlihat seperti ini.

var engine_type = Container.new()
var script_type = .Container.new()
var plugin_script_type = .MyPlugin.Container.new()

Adakah yang keberatan dengan format semacam itu?

Sunting:

Itu mungkin mengalami masalah dalam fungsi kelas turunan meskipun itu memanggil metode induk di dalamnya:

func _virtual_method():
    ._virtual_method() # parent stuff
    # my stuff

Hmm...apakah itu menimbulkan masalah untuk konstanta dan/atau variabel? Jika tidak, maka kita dapat berasumsi bahwa tanda kurung berarti itu adalah fungsi super dan jika tidak, kemungkinan itu adalah pengidentifikasi ruang nama.

Sejujurnya, saya akan menunda namespace untuk saat ini - itu bisa diperkenalkan nanti, dan saya lebih suka mendapatkan sistem saat ini sesegera mungkin. Kami juga membutuhkan sistem yang _benar-benar_ dipikirkan dengan baik untuk pendaftaran nama otomatis, mungkin meluas ke pengerjaan ulang seluruh struktur organisasi addon, yang merupakan jumlah pekerjaan yang wajar dan di luar cakupan masalah ini.

Secara pribadi, saya lebih suka nama skrip 'terdaftar otomatis' dikontrol oleh deklarasi dalam file, yaitu

register <NAME> extends <PARENT>

atau sintaks serupa berdasarkan prolog extend <NAME> saat ini yang sudah ada untuk GDScript.

EDIT: Saya juga ingin bertanya bagaimana menetapkan skrip yang berasal dari induk (katakanlah Spasial) ke anak khusus (katakanlah Sprite3D->CustomType) akan ditangani? Ini sudah berfungsi untuk jenis mesin, dan membatasi skrip yang ditetapkan untuk diturunkan dari jenis khusus itu sendiri tidak akan berhasil dengan baik.

@Web-eWorks Cukup adil. Saya akan berusaha menyempurnakan API saat ini dan kemudian saya akan membuka Masalah baru untuk penspasian nama setelah PR dikirimkan.

Jika saya memahami dengan baik apa arti @Web-eWorks, saya sendiri masih memiliki pertanyaan ini: bagaimana Anda akan mengatasi fakta bahwa Object hanya dapat memiliki satu skrip? Bagaimana mereka akan ... "scriptable"? Karena selain itu, mendaftar ke ClassDB tidak lebih dari pengenal global dalam hal penggunaan untuk programmer dan desainer.

@Zylann Apa yang telah saya lakukan di garpu saya adalah membuat properti custom_script untuk Object . Itu hanya akan menjadi signifikan jika sebuah nilai diberikan padanya, tetapi jika sebuah skrip ditugaskan padanya, maka skrip tersebut berfungsi sebagai skrip cadangan / batasan pada apa yang dapat menjadi properti script utama. Menghapus script akan menetapkannya menjadi custom_script , dan jika Anda menetapkan Script baru ke script , maka itu hanya akan berhasil ditetapkan jika Script instance berasal dari custom_script . Dan semua ini dikelola oleh Object di belakang layar, sejauh menyangkut mesin, Object s masih hanya memiliki 1 skrip yang sebenarnya.

Konten ClassDB hanya memiliki peta sekunder dari tipe khusus yang didaftarkan, memetakan skrip itu sendiri dan beberapa info lain ke nama yang telah Anda tetapkan. Ia kemudian memberikan nama itu dan hierarki pewarisannya dengan metode pewarisan terkait ( get_class_list , is_parent_class , get_parent , dll.). Dan ini dilakukan sebagai tanda keikutsertaan untuk beberapa metode. get_class_list sekarang akan mengambil tanda bool yang hanya menyertakan jenis khusus jika Anda meneruskan true sebagai parameter kedua. Ini adalah bagaimana mencegah kerusakan kompatibilitas dengan sisa mesin.

@willnationsdev jadi, dengan sistem yang membuat skrip berperilaku seperti kelas bawaan, apa yang mencegah pengguna menginginkan semua skrip dan add-on mereka dianggap sebagai warga kelas satu seperti kelas bawaan, dan membuang cara "jadul"?

Ah. Cara kerja skrip saat ini adalah Anda dapat meletakkan skrip yang extends Node pada VBoxContainer , dan masih berfungsi dengan baik. Jika implementasi saat ini merusak perilaku itu untuk tipe kustom, akan ada beberapa masalah - apakah ada cara untuk menjaga perilaku skrip kustom sementara skrip 'normal' diturunkan langsung dari tipe mesin?

@Zylann Sebenarnya itulah mengapa saya ingin memperkenalkan penspasian nama sehingga skrip dan skrip plugin dapat diintegrasikan dengan aman melalui nama tanpa bertabrakan dengan tipe dalam mesin. Tidak akan ada yang menghalangi orang untuk hanya menggunakan cara baru dan mengabaikan cara lama. Dan saya benar-benar berpikir itu akan lebih baik secara keseluruhan. Sangat melelahkan harus menggunakan jalur eksplisit setiap saat.

@Web-eWorks Tidak yakin apakah saya mengikuti di sini, tapi...

Jenis khusus secara khusus berfungsi seperti jenis dalam mesin untuk pewarisan. Jadi, jika Anda memperluas dari tipe khusus, itu akan menjadi seolah-olah Anda memperluas dari cabang hierarki dalam mesin yang sama sekali berbeda. Mantan. jika saya membuat tipe khusus MyNode yang memanjang Node , saya tidak akan dapat menempatkan skrip itu pada VBoxContainer seperti halnya saya tidak dapat meletakkan Node2D "pada" VBoxContainer . Ini sebenarnya akan menjadi perilaku yang dimaksudkan.

Sekarang, dengan konsep namespace, Anda idealnya akan menamai skrip yang BUKAN tipe khusus. Jadi, dalam hal ini, saya bisa membuat skrip yang memperluas Node dan meletakkannya di Node , VBoxContainer AND MyNode . Apakah itu masuk akal?

Jadi yang saya katakan adalah jika Anda membuat tipe kustom MyNode mewarisi katakan MeshInstance , contohkan simpulnya di editor, dan coba tambahkan skrip yang mewarisi Spatial ke simpul yang diketik MyNode , apakah itu akan berfungsi dengan baik? Ini bekerja dengan baik dengan node 'mesin', dan itulah perilaku yang perlu kita tiru.

Itu harus independen namespace, karena ini lebih merupakan masalah untuk memastikan skrip jenis kustom dipanggil terlepas dari titik dalam hierarki pewarisan skrip 'tingkat pengguna'.

@Web-eWorks Ya, itu akan berhasil. Setiap entri "tingkat pertama" di peta ClassDB 's custom_types harus ditautkan kembali ke jenis di peta classes , jika tidak, akan terjadi kesalahan dan jenis khusus tidak tidak dibuat. Ini memastikan bahwa rantai pewarisan dipertahankan saat berpindah dari tipe kustom kembali ke tipe mesin hingga Object .

@willnationsdev Hanya untuk memastikan - jika Anda menambahkan metode _ready di MyNode , dan simpul siap pakai di skrip pengguna Anda yang berasal dari Spasial, itu akan disebut seperti Spatial._ready(), MeshInstance._ready(), MyNode._ready(), script._ready() ? (Atau pesanan apa pun _ready dikirim.)

Saya masih berpegang pada pandangan saya bahwa ini tidak perlu dan membingungkan. Masalah ini perlu diselesaikan dari UI editor, bukan mesin inti.

@reduz Ini bukan sesuatu yang bisa diselesaikan dari Editor UI saja. Tidak jika Anda ingin mengontrol manipulasi skrip pengguna pada objek. Sepertinya saya seperti itu adalah fitur yang banyak orang ingin siapkan.

Apakah Anda menyarankan agar gdscript_compiler harus mereferensikan konten di EditorData untuk menyiapkan pengidentifikasi global baru untuk jenis skrip, daripada melacak semuanya di ClassDB dan mengizinkan ClassDB untuk mengelola semua informasi warisan di mesin?

Tentu ada bagian yang perlu diselesaikan dari sudut pandang editor UI, tetapi ada juga bagian yang perlu diselesaikan di intinya. Menambahkan tipe khusus ke mesin, tipe _aktual_ dari perspektif ClassDB, adalah fitur yang sangat kuat dan pada akhirnya diperlukan. Sejauh membingungkan, saya masih mempertahankan bahwa itu tidak lebih membingungkan daripada sistem saat ini, dan sangat mungkin kurang.

@Web-eWorks saya setuju. Untuk membuat data warisan dilacak di editor sebenarnya akan jauh lebih membingungkan menurut saya. Dan itu akan menghasilkan solusi yang aneh karena informasi jenis itu tidak akan ada lagi setelah Anda menjalankan game tanpa editor (itulah sebabnya saya sebenarnya harus mulai memuat informasi di project.godot untuk memuatnya ke ClassDB saat startup. Tidak ada EditorPlugins untuk menambahkan tipe kustom yang menyebabkan GDScripts gagal kompilasi saat menjalankan adegan).

@Web-eWorks Dan untuk menjawab pertanyaan Anda sebelumnya, ya, itu berfungsi dengan baik.

Dalam skenario pengujian saya, saya memiliki Node.gd yang diperluas GDSkillsEffect > GDSkillsAPI > Node , dan metode _ready yang diterapkan di setiap skrip dipicu dengan cara yang benar urutan: API, Efek, Node.gd.

Saat ini saya mengalami kesalahan loop tak terbatas dari beberapa jenis meskipun setiap kali dua skrip mencoba mewarisi dari skrip tipe khusus berdasarkan nama. Mantan. jika Node.gd memiliki extends GDSkillsEffect dan gdskills_effect.gd memiliki extends GDSkillsAPI , maka mencoba memodifikasi dan menyimpan gdskills_effect.gd atau gdskills_api.gd akan menyebabkan editor "memuat" tanpa batas dan kemudian crash. Itu mungkin bug terbesar saya saat ini.

@willnationsdev Ahh, tidak, saya sedang berbicara tentang Node.gd memperluas Node , _not_ GDSkillsEffect . Jika _that_ berfungsi, maka semuanya baik-baik saja.

Misalnya, berikut adalah representasi dari pohon adegan:

-> User Script:
  extends Node
  func _ready(): pass

@Web-eWorks Ah, saya mengerti maksud Anda. Yah, itu HARUS berfungsi, tetapi saya baru saja mengujinya dan sepertinya logika saya di Object::set_script() memblokirnya karena suatu alasan, jadi itu adalah bug yang harus saya perbaiki. XD Gagal karena telah mendeteksi bahwa Node tidak mendapatkan skrip tipe kustom (yang benar, yay), tetapi seharusnya tidak gagal dalam kasus itu, lol.

@Web-eWorks Seperti yang saya sebutkan, ini BUKAN sesuatu yang perlu diubah di ClassDB.

Saya tidak benar-benar berpikir ini perlu diselesaikan pada intinya, karena setiap bahasa skrip menanganinya secara berbeda. Anda dapat dengan mudah membuat kelas baru di Mono dan itu akan berhasil. Untuk GDScript, ini mungkin kasus sederhana untuk mengekspos file skrip sebagai global yang dimuat sebelumnya dan hanya itu. Solusi satu ukuran untuk semua, seperti yang diusulkan dalam PR, jelas bukan cara yang tepat.

@willnationsdev Saya menghargai upaya Anda, tetapi ini sudah dibahas tanpa akhir dan konsensusnya adalah:

  • Menambahkan tipe khusus berbeda untuk setiap bahasa skrip, jadi meretas sesuatu di ClassDB, yang hanya benar-benar dimaksudkan untuk mendaftarkan hal-hal C++, BUKAN cara yang harus dilakukan.
  • Sebelum melangkah sejauh itu, kami dapat meningkatkan kegunaan UI untuk kasus di mana Anda ingin memperluas skrip dari simpul khusus, jadi itu hanya membuat pewarisan sederhana.
  • Secara umum, menambahkan peretasan ke mesin inti untuk menangani kasus sudut bukanlah cara yang tepat. Core harus tetap bebas dari peretasan.

@willnationsdev Sebagai referensi, perilaku mesin adalah bahwa skrip apa pun yang memperluas _sesuatu_ sama dengan atau sebelumnya dalam hierarki pewarisan dapat ditambahkan ke sebuah simpul. Jadi, skrip yang extends Spatial dapat ditambahkan ke MeshInstance tetapi bukan Control atau Node , karena tidak satu pun dari yang terakhir adalah atau mewarisi dari Spatial . Ini adalah perilaku yang harus ditiru. (Tidak ada tekanan...)

@reduz Tapi apakah membuat kelas baru di Mono menambahkannya ke hierarki warisan mesin? Atau dialog Buat Node editor? Mungkin perlu dibuka isu baru yang secara ringkas menyatakan apa tujuannya, karena saya pikir kita tidak membicarakan hal yang sama di sini.

Maksud dari modifikasi ClassDB adalah untuk memungkinkan pendaftaran jenis Node (atau Sumber Daya) baru tanpa perlu mengkompilasi ulang mesin. Bukan untuk menambahkan global kustom baru di GDScript, meskipun itu adalah masalah tangensial yang sedang dikerjakan @willnationsdev di cabang yang sama.

Maksud dari ini bukan untuk menambahkan peretasan, tetapi untuk membuat _sistem_ yang dirancang dengan baik untuk memperluas jenis mesin.

@Web-eWorks Hirarki pewarisan mesin adalah untuk C++, bukan skrip. Mencoba menggabungkan keduanya secara konseptual salah sejak awal.

Mungkin kesalahpahamannya adalah bahwa dialog buat simpul membuatnya tampak seperti kelas baru telah ditambahkan, jadi mungkin ide yang baik untuk menandai tipe khusus seperti itu dengan jelas berisi skrip.

@Web-eWorks Jika Anda menggunakan Mono, itu akan terlihat transparan seolah-olah kelas baru telah ditambahkan, karena ADALAH kelas baru. Untuk GDScript, karena kelas adalah file secara default, itu tidak dapat dilakukan dengan cara ini sehingga cara untuk melakukannya mungkin dengan menambahkan global baru dengan UI khusus untuk mengaturnya (seperti yang kita miliki untuk autoload tunggal)... tapi ini masih kelas skrip, bukan kelas mesin.

@willnationsdev Maksud saya dalam hal ini adalah saya pikir itu salah untuk membuatnya terlihat seolah-olah Anda menambahkan kelas baru yang sebenarnya ke mesin, karena sebenarnya tidak. Ini terbuka untuk kebingungan. Itu hanya simpul dengan skrip, jadi alih-alih menyembunyikan skrip, saya pikir hal yang benar untuk dilakukan adalah membuatnya lebih terlihat di dialog buat.

@reduz Nah, itu masalahnya. Node+Script adalah Adegan. Mekanisme add_custom_type harus berperilaku seperti Mono, mendaftarkan 'kelas baru', meskipun secara teknis bukan 'kelas' dengan standar apa pun. Jika ada cara untuk melakukannya tanpa perlu menyentuh ClassDB, saya setuju.

Juga, @akien-mga menyarankan bahwa dalam tampilan pohon adegan, kita dapat menyembunyikan skrip dari node kustom, untuk menghindari membingungkan pengguna tentang mereka yang telah membuat skrip itu dan mengeditnya secara tidak sengaja (tetapi masih menunjukkannya di inspektur di bagian bawah) .

Dalam node seperti itu, menambahkan skrip akan membuka dialog buat dalam mode pewarisan, sehingga akan tetap cukup transparan untuk alur kerja pengguna, sementara jelas bahwa itu adalah simpul khusus dan bukan bagian dari mesin.

@willnationsdev Adakah keberatan dengan saya membuka masalah baru yang lebih ringkas yang secara khusus merinci ruang lingkup implementasi?

@Web-eWorks Node + Script bukan adegan, node dalam tata letak pohon adalah adegan. Anda juga dapat menambahkan jenis sumber daya khusus, bukan hanya node.

Dan tidak, itu seharusnya tidak berperilaku seperti mendaftarkan kelas baru. Harus cukup jelas bahwa ini adalah kelas C++ dengan skrip yang ditambahkan sebelumnya.

@Web-eWorks Ya, itu tidak masalah bagi saya. Tolong sebutkan saya agar saya mendapatkan ping jika Anda melakukannya. Tidak yakin apakah kami memerlukan masalah terpisah?

Lihatlah dari sudut pandang lain. Argumen Anda adalah untuk membuatnya terlihat bagi pengguna seolah-olah Anda memperluas jenis mesin dengan jenis mesin baru.

Sudut pandang saya adalah Anda memperluas jenis mesin dengan skrip, bukan dengan jenis mesin baru. Dan bahwa pengguna tidak bodoh dan perlu mengetahui hal ini.

@reduz Yang saya maksud tentang Node+Script adalah bahwa mekanisme itu sudah dicakup melalui instantiating Scenes.

Mungkin saya salah memahami implementasi Mono, tetapi bukankah kelas Mono masih Script?

@reduz Saya sebagian besar setuju dengan Anda, juga ketika Anda mengatakan bahwa menambahkan skrip ke simpul khusus hanya akan mengusulkan untuk mewarisinya. Tetapi bagaimana Anda mengharapkan ini berfungsi dengan jenis khusus GDNative?

@reduz Salah satu tujuan kami adalah mengizinkan skrip tipe khusus, skrip yang telah ditetapkan sebelumnya ini ditempatkan pada kelas C++, agar tidak dapat dilepas. Itu adalah sesuatu yang tidak dapat dilakukan dalam konteks editor karena Anda selalu dapat menghapus skrip saat runtime (kecuali jika Anda ingin mempertahankan fungsionalitas itu dan hanya mengamankan skrip tipe khusus pada waktu desain di editor)

Saya pasti akan terbuka untuk metode alternatif. Either way, implementasi termudah adalah memiliki Objek secara kondisional menetapkan skrip untuk dirinya sendiri (seperti yang telah saya lakukan dalam implementasi saya) dengan memeriksa beberapa kelas pendaftaran pihak ketiga (apakah itu ClassDB, ProjectSettings, EditorData, atau siapa yang tahu apa lagi) . Kemudian menjadi sangat mudah bagi editor itu sendiri untuk memeriksa dengan pihak ketiga itu dan menampilkan berbagai hal secara berbeda (juga seperti yang telah saya lakukan dalam implementasi saya). Tidak akan terlalu banyak pekerjaan. Saya tidak berpikir untuk memindahkan pendaftaran ke konteks lain selain ClassDB.

^ Apakah kompromi itu dapat diterima? Jika tidak, Anda harus mengatur mikro setiap lokasi yang memungkinkan di mana Object mendapatkan skrip yang ditugaskan untuk diperiksa dengan pihak ketiga. Itu akan jauh lebih kompleks.

Implementasi yang telah saya lakukan sejauh ini sangat jelas mengenai "tipe" mana yang merupakan skrip dan mana yang bukan. Lagi pula, Anda masih dapat dengan jelas melihat dan mengakses skrip yang terkait dengan jenis khusus di dock adegan di video yang saya bagikan.

@willnationsdev Saya mengerti apa yang Anda coba lakukan, tetapi saya rasa ini tidak akan pernah bisa dilakukan dengan bersih. Itu menyembunyikan kompleksitas yang tidak memiliki alasan untuk disembunyikan, dengan cara yang tidak akan pernah sepenuhnya berfungsi seperti yang diharapkan.

@Zylann Saya pikir itu sama, tetapi a) skripnya adalah gdnative internal b) ia menggunakan metode internal ke gdnative. Saya tidak cukup akrab dengan itu jujur ​​untuk mengatakan.

@reduz Apakah Anda mengatakan bahwa Anda tidak ingin mengizinkan segala bentuk pembuatan batasan berbasis skrip pada Objek? Karena saya dapat memindahkan logika pemeriksaan ke dalam Editor itu sendiri dan itu akan memberi Anda pemeriksaan batasan waktu desain dengan mudah (UI berubah, seperti yang Anda katakan), tetapi mereka tidak akan berfungsi saat runtime, jadi orang masih berpotensi mampu mengubah banyak hal setelah game berjalan. Apakah itu akan bekerja lebih baik untuk Anda? Saya masih lebih suka dapat memeriksa barang-barang saat runtime ...

@willnationsdev batasan berbasis skrip seperti apa yang ingin Anda lakukan?

Batasan yang sama dengan properti skrip khusus sejak awal: memaksa skrip yang ditetapkan untuk memperoleh beberapa skrip lain.

Saya akan merekomendasikan untuk menyembunyikan ikon skrip untuk skrip yang diperluas dalam hierarki adegan dan jika seseorang mengklik tombol "Tambah Skrip" alih-alih mewarisi kelas dasar dari node, itu mewarisi skrip yang diserang. Transparan dan tidak perlu dipusingkan dengan ClassDB sama sekali

Jadi, hanya dengan meninjau beberapa informasi di script_language.h , saya merasa seperti saya benar-benar dapat memindahkan konten baru yang saya tambahkan di ClassDB ke kelas ScriptLanguage dan membuat semacam ScriptDB singleton yang hanya pernah dibuat jika bahasa skrip bermaksud menggunakannya. Dan karena object.cpp sudah termasuk script_language.h , itu akan dapat melakukan hal berikut di set_script(const RefPtr &p_script) ...

  1. periksa apakah p_script sebenarnya adalah skrip
  2. periksa bahasa apa yang dimiliki p_script
  3. serahkan p_script dan Object instance custom_script ke ScriptDB untuk ScriptLanguage terkait,
  4. dapatkan respons dari ScriptDB apakah p_script dapat ditetapkan ke Object mengingat batasan yang tersirat oleh custom_script pada Object contoh.

Ini akan memungkinkan kita untuk menjaga ClassDB bersih dari modifikasi apa pun dan menjaga object.h bersih (selain dari setter/getter untuk custom_script ). Ini juga mencegah komplikasi yang tidak perlu dari bahasa scripting yang tidak perlu mengandalkan Godot untuk mendefinisikan pengenal dan ruang nama (seperti yang dibutuhkan GDScript dan VisualScript, tidak seperti C#, C++, Python, dll.).

Maka yang perlu Anda lakukan hanyalah menentukan metode ScriptServer yang dapat melakukan pemeriksaan pengenal / namespace di semua bahasa skrip yang berlaku untuk menggantikan fungsionalitas ClassDB eksperimental untuk mengonfirmasi jenis khusus / pewarisan jenis khusus hierarki. Cukup mudah.

Apakah semua ini terdengar seperti alternatif yang dapat diterima @reduz?

Hanya menambahkan suara saya di sini. Saya baru saja mulai bekerja dengan Godot dan, ketika saya membaca tentang add-on tipe kustom, saya memang berpikir bahwa saya akan membuat tipe dasar baru yang dapat digunakan kembali. Seperti bagaimana ketika Anda membuat KinematicBody Anda dapat melampirkan skrip ke dalamnya, tetapi skrip itu masih akan melakukan semua hal KinematicBody .

Hal ini diperkuat dengan dua cara:

  1. Mereka disebut tipe. Meskipun bahasa berbeda dalam hal apakah suatu Tipe dapat diperpanjang atau tidak (javascript: yes, golang: no, python: yes), tipe yang Anda definisikan umumnya dapat diperpanjang jika tipe bahasa kelas satu dapat diperpanjang. Di Godot, tipe kelas pertama dapat diperpanjang, tetapi tipe kustom tidak (setidaknya tidak dengan cara yang sama). Menyebutnya sebagai sesuatu yang lain, seperti adegan cetakan atau adegan templat, akan membantu menandainya sebagai berbeda.
  1. Mereka muncul di pohon yang sama dengan node kelas pertama di jendela 'Buat Node Baru'. Ini menyiratkan bahwa Anda menggunakannya dengan cara yang sama. Memiliki bagian terpisah untuk 'Prefab' atau 'Templat' atau apa pun yang Anda ingin menyebutnya akan kembali menyebutnya sebagai berbeda.

@JPTeasdale Sayangnya, pada titik ini kekhawatiran yang lebih besar adalah implementasinya, bukan pertanyaan "bagaimana Anda mendefinisikan ini". Dan tipe kustom Godot ADALAH dapat diperpanjang (mereka hanya skrip). Editor belum memiliki dukungan kode untuk menampilkan hubungan pewarisan antara tipe khusus dalam dialog pembuatan simpul, tetapi data tersedia. Saya juga tidak benar-benar melihat alasan untuk mengganti namanya dari "tipe khusus" menjadi yang lain. "Prefab" dan "templat" bukanlah istilah yang benar-benar tepat, juga bukan adegan (itu hanya skrip, polos dan sederhana).

saya pikir ini jauh lebih sederhana daripada solusi yang dimaksudkan:

  1. Tambahkan properti yang disembunyikan di inspektur ke kelas Object yang disebut "custom_type_script" dan tetapkan skrip khusus untuk memilih properti ini alih-alih Script
  2. Saat Anda mencoba untuk memperpanjang simpul, periksa apakah properti ini nol, jika tidak, perpanjang skrip ini alih-alih kelas simpul (tulis ekstensi "res:/path/to/script.gd")
  3. Ubah get_script_instance untuk menunjuk ke instance skrip khusus jika skrip simpul adalah nol

@MarianoGnu Nah, dalam hal membuat perubahan editor, lebih mudah dilakukan dengan hanya mengisi otomatis properti script dan mencegahnya menjadi nol sejak awal (karena editor hanya melihat script , dan kita tidak perlu menemukan setiap kali referensi properti script dan memodifikasi kode itu jika yang kita lakukan hanyalah mengubah nilai script ) .

Dengan demikian, bagian dari tujuan mengulangi proses ini adalah untuk memungkinkan bahasa skrip secara umum memilih untuk menggunakan pengidentifikasi daripada jalur file untuk menemukan kelas skrip. Itulah satu-satunya alasan mengapa konsep ScriptDB atau ClassDB pernah disarankan sejak awal. Tapi sekarang saya mengerti mengapa Juan sangat keberatan dengan perubahan ClassDB , oleh karena itu saran untuk menyimpan informasi di API skrip saja. Itu sendiri berisi semua informasi dalam bahasa scripting individu.

Kombinasi dapat dilakukan, alih-alih menyimpan skrip tak terlihat di objek simpan di ScriptDB, tambahkan pra-pass ke pembaca skrip untuk mengganti " extend CustomClassName" menjadi "extend "res:/path/stored/inScriptDB.gd " di precompiler GdScript, karena skrip keluar dari hierarki pewarisan skrip sangat merepotkan (hierarki harus garis lurus dari bawah ke root, memiliki cabang menyebabkan kebingungan)

karena mengeluarkan skrip dari hierarki pewarisan skrip sangat merepotkan (hierarki harus menjadi garis lurus dari bawah ke root, memiliki cabang menyebabkan kebingungan)

@MarianoGnu Mungkin ada kesalahpahaman di sini. Pada titik mana menurut Anda tidak ada garis lurus pewarisan? Sejauh yang saya lakukan, selalu ada hierarki pewarisan yang sangat jelas di antara skrip. Saya belum mengubah apa pun tentang cara kerja hierarki warisan itu sendiri. Saya baru saja memungkinkan untuk memetakan skrip yang diberikan ke StringName dan mencarinya di semacam DB.

Dan jika kita sudah melakukan pekerjaan itu, tidak ada alasan untuk mengganti teks skrip kembali ke jalur di kompiler GDScript. Yang dilakukan oleh kompiler hanyalah menetapkan instance Script script . Apakah saya telah memuat skrip melalui metode ResourceLoader::load(path) atau dengan mengambilnya dengan Class/ScriptDB::get_script(namespace_and/or_identifier) tidak terlalu penting.

Hanya ingin menyebutkan, sebagai pengguna baru Godot, saya membuat plugin dengan kesan "Node Kustom" saya dari plugin akan bertindak sebagai node bawaan. Yaitu, ketika saya memilihnya dari daftar simpul, saya berharap saya akan mendapatkan simpul tanpa skrip, tetapi dengan fungsionalitas yang saya skrip di plugin yang diwarisi sudah bawaan (seperti itu untuk simpul bawaan). Hanya berpikir saya harus memberikan pendapat lain dari seseorang yang baru saja datang (meskipun sepertinya diskusi di sini sudah luas).

Karena "node khusus" hanyalah skrip, apa bedanya dengan hanya menetapkan skrip ke simpul bawaan? Apa yang seharusnya dilakukan oleh fitur simpul khusus?

@MCrafterzz Telah dibahas bahwa harus ada kemampuan node kustom untuk memiliki kemampuan untuk menambahkan skrip di atas node kustom yang dibuat dari plugin.

Saat ini simpul khusus hanyalah simpul yang dibuat dengan skrip yang sudah dilampirkan dan ikon serta nama sudah diubah.

@willnationsdev Seberapa jauh Anda telah mengimplementasikan fitur ini.
Saya sangat ingin fitur ini ada di sini sebelum 3.1. Ini akan menjadi tambahan yang sangat luar biasa.
Untuk plugin Godot dan sistem addon.

Saya tidak ingin menekan siapa pun. Jadi tolong jangan menganggapnya sebagai cara kerja.

Saya telah menerapkan backend baru untuk sistem tipe kustom sepenuhnya. Yang baru memungkinkan pengguna untuk melakukan semua fungsi asli, ditambah membuatnya sehingga tombol Add-a-Script menambahkan skrip baru yang memperluas skrip khusus secara default (daripada membuka skrip khusus) dan membuatnya sedemikian rupa Anda tidak dapat menghapus skrip khusus (Anda harus menggunakan perintah editor Ubah Jenis, sama seperti jenis mesin lainnya).

@swarnimarun

Selain itu, ini akan memungkinkan pengguna untuk mendaftarkan tipe ke global yang menyediakan akses ke pemetaan typename-to-filepath. GDScript akan dapat melihat pemetaan ini sebagai nama tipe global yang pada dasarnya sederhana. Selanjutnya, jenis tidak harus menjadi jenis khusus untuk didaftarkan dan jenisnya dapat berupa skrip atau adegan.

Sejauh ini, saya telah mengimplementasikan backend baru dan saya telah mengatur ulang fungsionalitas skrip tipe kustom asli. Saat ini akan bekerja pada fitur baru. Mulai seminggu dari sekarang mungkin. Kalau tidak, saya sibuk minggu ini.

@willnationsdev Jangan khawatir, jika itu menjadi 3.1 saya akan puas.
Dan saya menyadari bahwa itu mungkin sedikit pekerjaan.
Pertahankan pekerjaan yang baik.

Saat ini, editor memang memiliki kemampuan untuk memperluas skrip node dengan mudah:

extend

Node itu sendiri saat ini terlihat seperti ini:

2

Dan perhatian utama @reduz adalah menyembunyikan fakta bahwa sudah ada skrip yang dilampirkan. Di satu sisi, masuk akal untuk tidak menyembunyikannya dari pengguna. Tetapi di sisi lain, node khusus hampir selalu memiliki skrip yang dilampirkan. Tanpa skrip, simpul khusus hanyalah simpul biasa yang ada dengan ikon khusus dan tidak ada fungsionalitas tambahan yang ditambahkan.

Dan meskipun Anda dapat memperluas skrip kustom, sangat mengganggu bahwa node kustom biasa terlihat sama dengan node kustom yang diperluas.

Jadi, inilah solusi sederhana saya: Ketika skrip simpul khusus sama dengan skrip dalam definisi simpul khusus, ikon skrip harus memudar, seperti ini:

3

Berarti:

4

Kawan, contoh kehidupan nyata: Jika saya memiliki Banyak catatan khusus dari jenis yang sama, setiap skrip disesuaikan untuk contohnya sendiri, apa yang terjadi jika saya ingin mengubah skrip simpul kustom dasar? Saya beri tahu Anda: YANG TERBURUK, karena saya perlu memodifikasinya, DAN semua contoh lain yang sesuai, memberikan kemungkinan besar kesalahan manusia dan kesalahan ketik.

Anda tidak ingin menyembunyikan skrip? Baik, lalu tunjukkan skrip custom_node DAN skrip simpul proyek.

@aaronfranke Menurut pendapat saya ini adalah solusi terbaik. Bahkan adegan yang dibuat dapat mengambil manfaat dari ini.

@zatherz dkk, sekarang #30697 telah diimplementasikan, apa lagi yang bisa diperbaiki? Apakah ada hal lain di https://github.com/godotengine/godot/issues/6067#issuecomment -238250383 yang penting untuk dimiliki?

Penutupan sebagaimana ditetapkan oleh #30697. Sementara proposal asli dalam OP yang diuraikan di https://github.com/godotengine/godot/issues/6067#issuecomment -238250383 belum diterapkan, ini tidak akan terjadi karena kekhawatiran @reduz di https:// github.com/godotengine/godot/issues/6067#issuecomment -239060186.

Apakah halaman ini membantu?
0 / 5 - 0 peringkat