Godot: أفضل محرر مخصص العقد

تم إنشاؤها على ٧ أغسطس ٢٠١٦  ·  121تعليقات  ·  مصدر: godotengine/godot

العقد التي تم إنشاؤها بواسطة الوظيفة add_custom_type في EditorPlugin تم تعيين البرنامج النصي المحدد لها عند الإضافة. هذا يجعلها عديمة الفائدة تقريبًا ، حيث يمكنك فقط استخدام الوظائف المحددة في هذا البرنامج النصي في العقد الأخرى.

هذا يختلف تمامًا عن العقد الأخرى ويجعل إضافات العقدة غير مجدية إلى حد كبير / مزعج للاستخدام.

feature proposal plugin usability

التعليق الأكثر فائدة

كما أفهمها ، فإن التوقع هو أن يكون لديك إمكانية إنشاء عقد مخصصة تتصرف مثل العقد المضمنة ، أي يجب أن تحتوي على الميزات التالية:

  • رمز مخصص ، معرف مخصص
  • قابل للتجربة عبر أداة إضافة عقدة (وأعتقد عبر البرنامج النصي ، لذا هل تتعرض لـ Global Scope؟)
  • احصل على واجهة برمجة تطبيقات مخصصة مشفرة عبر برنامج نصي (على سبيل المثال ، قد يؤدي RedNode2D إلى تمديد Node2D ، ولديه تعديل أحمر محدد عبر برنامج نصي مخصص)
  • ثم يجب أن تتصرف هذه العقدة المخصصة كعقدة مضمنة ، أي يجب أن يكون المستخدم قادرًا على مثيلها بدون برنامج نصي على الإطلاق (لن يتم عرض واجهة برمجة التطبيقات المخصصة بشكل مباشر للمستخدم ، تمامًا كما هو الحال في البرنامج النصي المدمج حيث يتم تشفيره بشكل ثابت في C ++) ، وإرفاق برنامج نصي به من شأنه أن يوسع العقدة المخصصة (على سبيل المثال extends RedNode2D ).

سيكون هذا هو التوقع "الطبيعي" عند الإعلان عن عقدة مخصصة ، وسيكون ميزة قوية للغاية ؛ أجمع مما سبق أنه لا يعمل بهذه الطريقة حتى الآن ، ويرجع ذلك جزئيًا إلى قرارات التصميم. إذا كانت هناك طريقة للحصول على وظيفة مثل ما وصفته أعلاه ، فأنا متأكد من أنها ستحتوي على الكثير من التطبيقات. سيكون دفتر الأصول مليئًا بالعقد المخصصة التي تقوم بالكثير من العمل خارج الصندوق ويمكن استخدامها كما لو كانت مضمنة.

إعادة الفتح حتى يكون هناك توافق في الآراء بشأن ما يمكن / ينبغي القيام به أم لا.

ال 121 كومينتر

أنا لا أفهم ما تقصد

reduz عندما تضيف إلى المشهد عقدة من النوع الذي تم إنشاؤه بواسطة مكون إضافي ، فإنه يحتوي بالفعل على البرنامج النصي الإضافي المرفق. لذلك من المستحيل إضافة نص برمجي آخر بسلوك مخصص.

بالطبع لا ، هذا من خلال التصميم الأساسي ولن يتغير.

في 7 آب (أغسطس) 2016 ، الساعة 18:11 ، كتب "George Marques" [email protected] :

reduz https://github.com/reduz عندما تضيف إلى المشهد العقدة التي a
النوع الذي تم إنشاؤه بواسطة مكون إضافي ، فقد تم بالفعل إرفاق البرنامج النصي للمكوِّن الإضافي. لذا
من المستحيل إضافة نص برمجي آخر بسلوك مخصص.

-
أنت تتلقى هذا لأنه تم ذكرك.

قم بالرد على هذا البريد الإلكتروني مباشرة ، وقم بعرضه على GitHub
https://github.com/godotengine/godot/issues/6067#issuecomment -238108767 ،
أو كتم الخيط
https://github.com/notifications/unsubscribe-auth/AF-Z29F5q8PaoBv4OrzAUayzrfNjfHyZks5qdkoUgaJpZM4JejbZ
.

هذا محزن. ولكن يمكنك دائمًا إضافة البرنامج النصي إلى الوالد أو الطفل.

إغلاق كما wontfix.

ربما أسيء فهم شيء ما ، ولكن إذا كان النوع المخصص هو نص برمجي ،
كيف لن يتم تضمينه في العقدة التي تم إنشاؤها؟ لا معنى لها
أن تكون مختلفة

في 7 أغسطس 2016 ، الساعة 9:52 مساءً ، كتب "George Marques" [email protected] :

هذا محزن. ولكن يمكنك دائمًا إضافة البرنامج النصي إلى الوالد أو الطفل.

إغلاق كما wontfix.

-
أنت تتلقى هذا لأنه تم ذكرك.
قم بالرد على هذا البريد الإلكتروني مباشرة ، وقم بعرضه على GitHub
https://github.com/godotengine/godot/issues/6067#issuecomment -238120392 ،
أو كتم الخيط
https://github.com/notifications/unsubscribe-auth/AF-Z27Zo4Ixvo4APSC4Fxf5ZqCJRsAxXks5qdn3igaJpZM4JejbZ
.

أعتقد أنه سيحتاج إلى القدرة على وجود نصين (أو أكثر) لكل عقدة ، على الرغم من أن هذا في الحقيقة لا معنى له.

دعم جودو هذا أصلاً ، لكنه كان مشكلة أكثر منه ميزة

في 7 آب (أغسطس) 2016 ، الساعة 10:36 مساءً ، كتب "George Marques" [email protected] :

أعتقد أنه سيحتاج إلى القدرة على وجود نصين (أو أكثر) لكل منهما
العقدة ، على الرغم من أن هذا لا معنى له حقًا.

-
أنت تتلقى هذا لأنه تم ذكرك.
قم بالرد على هذا البريد الإلكتروني مباشرة ، وقم بعرضه على GitHub
https://github.com/godotengine/godot/issues/6067#issuecomment -238123729 ،
أو كتم الخيط
https://github.com/notifications/unsubscribe-auth/AF-Z27jidVZl-hHWW3G_ESr8Cqj3eX7Eks5qdogRgaJpZM4JejbZ
.

تكمن المشكلة في أن العقد المخصصة بجوار العقد غير مجدية لأنها ليست "عُقدًا مخصصة" حقًا ، إنها مجرد عقد أساسية مع برنامج نصي محدد مسبقًا وأيقونة مختلفة.
ما توقعته من "العقد المخصصة" هو أنه يمكنني تمديد العقدة لاستخدام كل ما هو محدد في البرنامج النصي. سيناريو مثال:
لدي عقدة مخصصة تسمى Test وهي تابعة لـ Sprite وتضيف الدالة test() التي ترجع true . بعد ذلك ، أود إنشاء عقدة اختبار جديدة ، وتعيين برنامج نصي لها واستخدام الوظيفة test() .
هذا مستحيل.

أعتقد مرة أخرى إلى مكان الحادث لترث + النصي لتوسيع التحرير والسرد بعد ذلك.

حسنًا ، يعد IMO عقدة محددة مسبقًا بنص محدد مسبقًا وأيقونة مختلفة
ما يكفي من العرف ، ولكن إذا كنت تريد حقًا وضع التعليمات البرمجية المخصصة الخاصة بك
هناك ، يمكنك دائمًا وراثة تلك التي تأتي مع العقدة. نستطيع
اجعل هذا أسهل قليلاً من واجهة المستخدم إذا رغبت في ذلك حقًا.

يوم الإثنين 8 أغسطس 2016 الساعة 10:40 صباحًا ، أرسل رسالة دومينيك باناسزاكإخطارات github.com
كتب:

تكمن المشكلة في أن العقد المخصصة بجوار العقد غير مجدية لأنها ليست كذلك بالفعل
"العقد المخصصة" ، إنها مجرد عقد أساسية بنص محدد مسبقًا ومختلف
أيقونة. أعتقد مرة أخرى إلى مكان الحادث لترث + النصي لتوسيع التحرير والسرد بعد ذلك.

-
أنت تتلقى هذا لأنه تم ذكرك.
قم بالرد على هذا البريد الإلكتروني مباشرة ، وقم بعرضه على GitHub
https://github.com/godotengine/godot/issues/6067#issuecomment -238240130 ،
أو كتم الخيط
https://github.com/notifications/unsubscribe-auth/AF-Z27eHoXwgr6buF6CCAHfxwx1dKkCiks5qdzHhgaJpZM4JejbZ
.

أرغب في أن تتم أتمتة / جعلها أسهل من خلال واجهة المستخدم.

كما أفهمها ، فإن التوقع هو أن يكون لديك إمكانية إنشاء عقد مخصصة تتصرف مثل العقد المضمنة ، أي يجب أن تحتوي على الميزات التالية:

  • رمز مخصص ، معرف مخصص
  • قابل للتجربة عبر أداة إضافة عقدة (وأعتقد عبر البرنامج النصي ، لذا هل تتعرض لـ Global Scope؟)
  • احصل على واجهة برمجة تطبيقات مخصصة مشفرة عبر برنامج نصي (على سبيل المثال ، قد يؤدي RedNode2D إلى تمديد Node2D ، ولديه تعديل أحمر محدد عبر برنامج نصي مخصص)
  • ثم يجب أن تتصرف هذه العقدة المخصصة كعقدة مضمنة ، أي يجب أن يكون المستخدم قادرًا على مثيلها بدون برنامج نصي على الإطلاق (لن يتم عرض واجهة برمجة التطبيقات المخصصة بشكل مباشر للمستخدم ، تمامًا كما هو الحال في البرنامج النصي المدمج حيث يتم تشفيره بشكل ثابت في C ++) ، وإرفاق برنامج نصي به من شأنه أن يوسع العقدة المخصصة (على سبيل المثال extends RedNode2D ).

سيكون هذا هو التوقع "الطبيعي" عند الإعلان عن عقدة مخصصة ، وسيكون ميزة قوية للغاية ؛ أجمع مما سبق أنه لا يعمل بهذه الطريقة حتى الآن ، ويرجع ذلك جزئيًا إلى قرارات التصميم. إذا كانت هناك طريقة للحصول على وظيفة مثل ما وصفته أعلاه ، فأنا متأكد من أنها ستحتوي على الكثير من التطبيقات. سيكون دفتر الأصول مليئًا بالعقد المخصصة التي تقوم بالكثير من العمل خارج الصندوق ويمكن استخدامها كما لو كانت مضمنة.

إعادة الفتح حتى يكون هناك توافق في الآراء بشأن ما يمكن / ينبغي القيام به أم لا.

+1
كانت هذه أول حواجز الطرق الرئيسية بالنسبة لي عندما حاولت نقل مشروع قائم من "OtherEngine (tm)" إلى Godot. يجب أن تتصرف الأنواع المخصصة ، مثل @ akien-mga الموضحة أعلاه ، مثل أي نوع آخر مدمج بعد التسجيل.

يرجى توضيح الطريقة التي تعتقد أنها لا تفعل ذلك

في 8 آب (أغسطس) 2016 الساعة 11:50 صباحًا ، كتب "رالف هولزمير" [email protected] :

+1
كانت هذه أول حواجز الطرق الرئيسية بالنسبة لي عندما حاولت نقل ملف
مشروع قائم من "OtherEngine (tm)" إلى Godot. أنواع مخصصة ، مثل
@ akien-mga https://github.com/akien-mga الموضح أعلاه ، يجب فقط
تتصرف مثل أي نوع آخر مدمج بعد التسجيل.

-
أنت تتلقى هذا لأنه تم ذكرك.
قم بالرد على هذا البريد الإلكتروني مباشرة ، وقم بعرضه على GitHub
https://github.com/godotengine/godot/issues/6067#issuecomment -238261603 ،
أو كتم الخيط
https://github.com/notifications/unsubscribe-auth/AF-Z25PJzv9w7iXO350tRF3FcEuYQYUKks5qd0IrgaJpZM4JejbZ
.

كما ذكرنا سابقًا ، فإن أكبر عيب في الوقت الحالي هو أن الأنواع المخصصة ليست أكثر من طريقة سريعة لتثبيت النوع الأساسي لهذا البرنامج النصي وتعيين البرنامج النصي المناسب لذلك المثال. هذا يجعل من المستحيل تمديد تلك العقدة في المحرر بنص آخر - كما يمكنك القيام به مع الأنواع المضمنة.

ولكن من المستحيل أيضًا إنشاء أشجار وراثة بعقد مخصصة في مربعات حوار "إنشاء عقدة / مورد جديد" لأنها تظهر فقط في هذه الأشجار عند تسجيلها بنوع مضمن كأحد الوالدين عبر add_custom_type.

على سبيل المثال ، لنفترض أنني أريد أن أرث جميع الأنواع المخصصة في مشروعي من نوع أساسي واحد.

base.gd

extends Node
export (Color) var color

type_a.gd

extends base.gd

type_b.gd

extends base.gd

كما هو الحال الآن ، لا بد لي من تسجيل هذه الأنواع مثل هذا. في هذه الحالة ، يجب أن تكون الوسيطة الثانية لـ add_custom_type هي "Node" ، وإلا فلن تظهر في مربعات الحوار.

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"))

... وهذه هي النتيجة.

add_node_flat

في حين أنه من الجيد أن تكون قادرًا على تسجيل أنواع مخصصة مثل هذا ، فإن الحوارات لا تعكس طبيعة وراثة تلك الأنواع مثل الأنواع الأخرى المضمنة. بالنسبة لأي نوع مدمج ، يمكنني إلقاء نظرة على تلك الشجرة وأرى في لمحة ما أتعامل معه. يمكنني ، على سبيل المثال ، التأكد من أن Sprite هي Node2D ومن ثم ترث جميع الوظائف التي يوفرها Node2D. نفس الشيء لا ينطبق على الأنواع المخصصة.

الآن ، إذا كان من الممكن تسجيل الأنواع المخصصة بالكامل في النطاق العالمي ، مثل @ akien-mga المذكور أعلاه ، فسيكون فهم الأشياء واستخدامها أسهل بكثير.

أولاً ، يمكنك أن ترث من نوع مخصص يُشار إليه باسم النوع بدلاً من مسار / اسم الملف.

base.gd

extends Node
export (Color) var color

type_a.gd

extends Base

type_b.gd

extends Base

... ثم ، يمكن تبسيط تسجيل الأنواع المخصصة مثل هذا. لاحظ المعلمة الثانية المفقودة من 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"))

... وستحصل على نظرة عامة أجمل بكثير في مربعات حوار "إنشاء عقدة / مورد جديد":

add_node_tree

.. وبالطبع القدرة على توسيع هذه الأنواع في المحرر بنص مخصص:

custom_type_no_script

... والتي ستتم الإشارة إليها أيضًا باسم النوع بدلاً من اسم / مسار البرنامج النصي

extends Base

إليك مثال المكون الإضافي من أعلى للتجول فيه.
addons.zip

أوه أرى .. يجب أن يكون هذان thigs قابل للإصلاح ، مع
إضافة دعم الميراث إلى النص النصي إنشاء الحوار

في 8 آب (أغسطس) 2016 الساعة 1:54 مساءً ، كتب "رالف هولزمير" [email protected] :

كما ذكرنا سابقًا ، فإن أكبر عيب في الوقت الحالي هو ذلك
الأنواع المخصصة هي أكثر قليلاً من مجرد طريقة سريعة لتثبيت النوع الأساسي
من هذا البرنامج النصي وتعيين البرنامج النصي المناسب لذلك المثال. هذه
يجعل تمديد تلك العقدة في المحرر بنص آخر مستحيل -
كما يمكنك أن تفعل مع الأنواع المضمنة.

ولكن من المستحيل أيضًا إنشاء أشجار وراثة مع وجود عقد مخصصة في
مربعات حوار "إنشاء عقدة / مورد جديد" لأنها تظهر فقط فيها
الأشجار عند تسجيلها بنوع مدمج كأحد الوالدين عبر
add_custom_type.

على سبيل المثال ، لنفترض أنني أريد أن أرث جميع الأنواع المخصصة في ملفي
مشروع من نوع قاعدة واحدة.

_base.gd http: //base.gd_

يمتد العقدة
تصدير (لون) فار لون

_type_a.gd http: //type_a.gd_

يمتد base.gd

_type_b.gd http: //type_b.gd_

يمتد base.gd

كما هو الحال الآن ، لا بد لي من تسجيل هذه الأنواع مثل هذا. في هذا
الحالة ، يجب أن تكون الوسيطة الثانية لـ add_custom_type هي "عقدة" ، وإلا
لن يظهروا في الحوارات.

func _enter_tree ():
add_custom_type ("Base" ، "Node" ، التحميل المسبق ("base.gd") ، التحميل المسبق ("base.png"))
add_custom_type ("TypeA" ، "Node" ، التحميل المسبق ("type_a.gd") ، التحميل المسبق ("type_a.png"))
add_custom_type ("TypeB" ، "Node" ، التحميل المسبق ("type_b.gd") ، التحميل المسبق ("type_b.png"))

... وهذه هي النتيجة.

[الصورة: add_node_flat]
https://cloud.githubusercontent.com/assets/8785013/17486294/9bcc029c-5d90-11e6-81e6-6fce6b0e7cf0.png

في حين أنه من الجيد أن تكون قادرًا على تسجيل أنواع مخصصة مثل هذا ، فإن ملف
الحوارات لا تعكس طبيعة وراثة تلك الأنواع مثل
أنواع أخرى مدمجة. بالنسبة لأي نوع مدمج ، يمكنني إلقاء نظرة على تلك الشجرة و
انظر في لمحة ما أتعامل معه. يمكنني ، على سبيل المثال ، التأكد من ذلك
Sprite _is a_ Node2D وبالتالي يرث جميع الوظائف _ المقدمة
عن طريق_ Node2D. نفس الشيء لا ينطبق على الأنواع المخصصة.

الآن ، إذا كان من الممكن تسجيل الأنواع المخصصة بالكامل في النطاق العالمي ، مثل
@ akien-mga https://github.com/akien-mga المذكورة أعلاه ، الأمور ستفعل
أسهل بكثير في الفهم والاستخدام.

أولاً ، يمكنك أن ترث من نوع مخصص مشار إليه بواسطة _type name_
بدلاً من مسار الملف / الاسم.

_base.gd http: //base.gd_

يمتد العقدة
تصدير (لون) فار لون

_type_a.gd http: //type_a.gd_

يمتد القاعدة

_type_b.gd http: //type_b.gd_

يمتد القاعدة

... ثم ، يمكن تبسيط تسجيل الأنواع المخصصة مثل
هذه. لاحظ المعلمة الثانية المفقودة من add_custom_type.

func _enter_tree ():
add_custom_type ("Base" ، التحميل المسبق ("base.gd") ، التحميل المسبق ("base.png"))
add_custom_type ("TypeA" ، التحميل المسبق ("type_a.gd") ، التحميل المسبق ("type_a.png"))
add_custom_type ("TypeB" ، التحميل المسبق ("type_b.gd") ، التحميل المسبق ("type_b.png"))

... وستحصل على نظرة عامة أفضل بكثير في قسم "إنشاء جديد
مربعات حوار العقدة / المورد ":

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

.. وبالطبع القدرة على توسيع تلك الأنواع في المحرر ب
برنامج نصي مخصص:

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

... والتي ستتم الإشارة إليها أيضًا بواسطة _type name_ بدلاً من النص البرمجي
الاسم / المسار

يمتد القاعدة

إليك مثال المكون الإضافي من أعلى للتجول فيه.
addons.zip https://github.com/godotengine/godot/files/407291/addons.zip

-
أنت تتلقى هذا لأنه تم ذكرك.
قم بالرد على هذا البريد الإلكتروني مباشرة ، وقم بعرضه على GitHub
https://github.com/godotengine/godot/issues/6067#issuecomment -238299152 ،
أو كتم الخيط
https://github.com/notifications/unsubscribe-auth/AF-Z20FQioFVkVcvhhbvDQ7jQKv5De7Hks5qd19QgaJpZM4JejbZ
.

ما لن يحدث أبدًا هو اختفاء البرامج النصية من العقد المثبتة ، أو
كونها مخفية ، يجب توضيح أن العقدة مكتوبة ، ولكن
ستظل إضافة برنامج نصي إليه تسمح باستبدال البرنامج النصي بآخر
يرث منه

في 8 آب (أغسطس) 2016 الساعة 2:02 ظهرًا ، كتب [email protected] "Juan Linietsky":

أوه أرى .. يجب أن يكون هذان thigs قابل للإصلاح ، مع
إضافة دعم الميراث إلى النص النصي إنشاء الحوار

في 8 آب (أغسطس) 2016 الساعة 1:54 مساءً ، كتب "رالف هولزمير" [email protected] :

كما ذكرنا سابقًا ، فإن أكبر عيب في الوقت الحالي هو ذلك
الأنواع المخصصة هي أكثر قليلاً من مجرد طريقة سريعة لتثبيت النوع الأساسي
من هذا البرنامج النصي وتعيين البرنامج النصي المناسب لذلك المثال. هذه
يجعل تمديد تلك العقدة في المحرر بنص آخر مستحيل -
كما يمكنك أن تفعل مع الأنواع المضمنة.

ولكن من المستحيل أيضًا إنشاء أشجار وراثة مع وجود عقد مخصصة في
مربعات حوار "إنشاء عقدة / مورد جديد" لأنها تظهر فقط فيها
الأشجار عند تسجيلها بنوع مدمج كأحد الوالدين عبر
add_custom_type.

على سبيل المثال ، لنفترض أنني أريد أن أرث جميع الأنواع المخصصة في ملفي
مشروع من نوع قاعدة واحدة.

_base.gd http: //base.gd_

يمتد العقدة
تصدير (لون) فار لون

_type_a.gd http: //type_a.gd_

يمتد base.gd

_type_b.gd http: //type_b.gd_

يمتد base.gd

كما هو الحال الآن ، لا بد لي من تسجيل هذه الأنواع مثل هذا. في هذا
الحالة ، يجب أن تكون الوسيطة الثانية لـ add_custom_type هي "عقدة" ، وإلا
لن يظهروا في الحوارات.

func _enter_tree ():
add_custom_type ("Base" ، "Node" ، التحميل المسبق ("base.gd") ، التحميل المسبق ("base.png"))
add_custom_type ("TypeA" ، "Node" ، التحميل المسبق ("type_a.gd") ، التحميل المسبق ("type_a.png"))
add_custom_type ("TypeB" ، "Node" ، التحميل المسبق ("type_b.gd") ، التحميل المسبق ("type_b.png"))

... وهذه هي النتيجة.

[الصورة: add_node_flat]
https://cloud.githubusercontent.com/assets/8785013/17486294/9bcc029c-5d90-11e6-81e6-6fce6b0e7cf0.png

في حين أنه من الجيد أن تكون قادرًا على تسجيل أنواع مخصصة مثل هذا ، فإن ملف
الحوارات لا تعكس طبيعة وراثة تلك الأنواع مثل
أنواع أخرى مدمجة. بالنسبة لأي نوع مدمج ، يمكنني إلقاء نظرة على تلك الشجرة و
انظر في لمحة ما أتعامل معه. يمكنني ، على سبيل المثال ، التأكد من ذلك
Sprite _is a_ Node2D وبالتالي يرث جميع الوظائف _ المقدمة
عن طريق_ Node2D. نفس الشيء لا ينطبق على الأنواع المخصصة.

الآن ، إذا كان من الممكن تسجيل الأنواع المخصصة بالكامل في النطاق العالمي ،
مثل @ akien-mga https://github.com/akien-mga المذكورة أعلاه ، أشياء
سيكون من الأسهل بكثير فهمها واستخدامها.

أولاً ، يمكنك أن ترث من نوع مخصص مشار إليه بواسطة _type name_
بدلاً من مسار الملف / الاسم.

_base.gd http: //base.gd_

يمتد العقدة
تصدير (لون) فار لون

_type_a.gd http: //type_a.gd_

يمتد القاعدة

_type_b.gd http: //type_b.gd_

يمتد القاعدة

... ثم ، يمكن تبسيط تسجيل الأنواع المخصصة مثل
هذه. لاحظ المعلمة الثانية المفقودة من add_custom_type.

func _enter_tree ():
add_custom_type ("Base" ، التحميل المسبق ("base.gd") ، التحميل المسبق ("base.png"))
add_custom_type ("TypeA" ، التحميل المسبق ("type_a.gd") ، التحميل المسبق ("type_a.png"))
add_custom_type ("TypeB" ، التحميل المسبق ("type_b.gd") ، التحميل المسبق ("type_b.png"))

... وستحصل على نظرة عامة أفضل بكثير في قسم "إنشاء جديد
مربعات حوار العقدة / المورد ":

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

.. وبالطبع القدرة على توسيع تلك الأنواع في المحرر ب
برنامج نصي مخصص:

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

... والتي ستتم الإشارة إليها أيضًا بواسطة _type name_ بدلاً من النص البرمجي
الاسم / المسار

يمتد القاعدة

إليك مثال المكون الإضافي من أعلى للتجول فيه.
addons.zip https://github.com/godotengine/godot/files/407291/addons.zip

-
أنت تتلقى هذا لأنه تم ذكرك.
قم بالرد على هذا البريد الإلكتروني مباشرة ، وقم بعرضه على GitHub
https://github.com/godotengine/godot/issues/6067#issuecomment -238299152 ،
أو كتم الخيط
https://github.com/notifications/unsubscribe-auth/AF-Z20FQioFVkVcvhhbvDQ7jQKv5De7Hks5qd19QgaJpZM4JejbZ
.

تضمين التغريدة
هل هناك سبب تقني لتوضيح أن العقدة مكتوبة برمجية وإذا كان الأمر كذلك ، فهل يجب أن تكون فتحة نصية مشغولة؟

تبدو لي طريقة خرقاء إلى حد ما للإشارة إلى نوع مخصص وأعتقد أنه لا أحد سيأتي بفكرة أنه من خلال استبدال النص الحالي على عقدة ، ستحصل على نص يمد النص الذي كان موجودًا بالفعل. هذه ليست الطريقة التي يعمل بها التوسيع عبر البرنامج النصي للأنواع الأساسية.

وماذا سيحدث إذا مسح المستخدم حقل النص هذا؟ هل يعود النوع المخصص إلى النص السابق أم يعود تمامًا إلى النوع الأساسي؟ مرة أخرى ، لا أعتقد أن هذه ستكون فكرة جيدة.

بدلاً من ذلك ، يمكن الإشارة إليه كنوع مخصص في شجرة العقدة أو محرر الخصائص عبر لون مختلف ، أو رمز ما أو أي شيء آخر ، دون التضحية بفتحة البرنامج النصي الفارغة.

ما لن يحدث أبدًا هو اختفاء البرامج النصية من العقد المثبتة ، أو كونها مخفية ، يجب توضيح أن العقدة تمت كتابتها ، ولكن إضافة برنامج نصي إليها سيظل يسمح باستبدال البرنامج النصي الذي يرث منه

النقطة هنا هي أن البرنامج النصي الذي يحدد العقدة المخصصة _should_ يكون مخفيًا ، لأنه ليس خاصية للعقدة _instanced_ بل من نوعها. لذلك يجب أن يمنح هذا البرنامج النصي الخصائص للعقدة المخصصة ، ولكن يجب أن يكون غير مرئي لمستخدم العقدة المثبّتة مثل فئات C ++ للعقد المدمجة. سيوفر واجهة برمجة تطبيقات ، ولكن لن يكون قابلاً للتعديل ، قابل للتوسيع فقط. تمامًا كما هو الحال عند مثيل Sprite ، فلن تحصل على scenes/2d/sprite.cpp مرفقًا باعتباره البرنامج النصي للعقدة المثبتة ، يجب ألا تحصل على my_custom_node.gd مرفقًا باعتباره البرنامج النصي القابل للتعديل للعقدة المخصصة للمثيل.

الآن ، لا أعرف ما إذا كان _ ممكنًا _ تقنيًا في الوقت الحالي ، لكنه سيكون حالة الاستخدام الطبيعي AFAIU. إذا قمت بتعديل البرنامج النصي للنوع المخصص ، فسيؤدي ذلك إلى تعديل النوع نفسه ، وبالتالي سيؤثر على جميع مثيلات هذا النوع. لكن العقد المثبتة التي تستخدم النوع المخصص يجب أن يكون لها نصها الخاص بها extends CustomNode .

أعتقد أن هذه الميزة ستحتاج إلى أن يكون لدى الكائن مؤشر إضافي إلى "نوع البرنامج النصي الأساسي المخصص" ، لأنك تحتاج إلى هذه المعلومات عندما تريد إزالة برنامج نصي للمستخدم منه (والذي يجب أن يحل محله بالفعل بالنص الأساسي).
بمجرد حصولك على ذلك ، فإن الباقي هو مسألة تضمينه في جميع الحالات ، لأنه قد يؤدي إلى ظهور العديد من الآثار الجانبية. في النهاية ، لن يكون هناك سوى نص واحد مرفق ، فقط طريقة مختلفة للتعامل معه.
أنا لست من أشد المعجبين بالميراث بشكل عام ، لكن هكذا سأفعل ذلك.

في الواقع ، لا يمكن حتى أن تكون هناك حاجة إلى هذا المؤشر. سيكون وضع علامة على البرنامج النصي كافيًا ، على سبيل المثال ، إذا قمت بإضافة_custom_type () باستخدام برنامج نصي ، يمكن للمحرك تعيين علامة على الفئة بحيث تكون المعلومات متاحة ، مثل "مهلا ، فئة البرنامج النصي هذا هي امتداد لنوع المحرك". ستؤدي إزالة البرنامج النصي للمستخدم بعد ذلك إلى استبداله بأول فئة نصية موروثة تم تمييزها على أنها "نوع مخصص" ، أو إزالتها إذا لم يكن هناك أي منها.

عذرًا ، أنا ضد إخفاء برنامج نصي إذا كانت العقدة تحتوي على نص برمجي. ما هو
نقطة محاكاة شيء ليس كذلك؟

حقيقة أنه يحتوي على برنامج نصي لا يعني أن الفتحة مشغولة أو أنها تحتاج إلى ملف
النص الثاني ، لأنه يمكنك ببساطة إنشاء نص جديد يرث الامتداد
واحد موجود.

ما يمكننا فعله ، إذا وافقت ، هو إخفاء رمز البرنامج النصي في شجرة المشهد إذا
البرنامج النصي المعين هو من النوع المخصص ، وقم بعمل البرنامج النصي
يعرض عليك إنشاء مربع حوار تلقائيًا أن ترث عند إنشاء البرنامج النصي.
هل هذا سيكون كافيا؟

في 10 آب (أغسطس) 2016 ، الساعة 11:01 مساءً ، كتب "مارك" [email protected] :

في الواقع ، لا يمكن حتى أن تكون هناك حاجة إلى هذا المؤشر. بمناسبة البرنامج النصي
كن كافيًا ، على سبيل المثال إذا قمت بإضافة_custom_type () مع برنامج نصي ، المحرك
يمكن وضع علامة على الفصل بحيث تكون المعلومات متاحة ، مثل "مرحبًا ، هذا
فئة البرنامج النصي هي امتداد لنوع المحرك ". تؤدي إزالة برنامج نصي للمستخدم
ثم استبدلها بأول فئة نصية موروثة تم تمييزها على أنها "مخصصة
اكتب "، أو قم بإزالته إذا لم يكن موجودًا.

-
أنت تتلقى هذا لأنه تم ذكرك.

قم بالرد على هذا البريد الإلكتروني مباشرة ، وقم بعرضه على GitHub
https://github.com/godotengine/godot/issues/6067#issuecomment -239055986 ،
أو كتم الخيط
https://github.com/notifications/unsubscribe-auth/AF-Z2xLGOhgMk__ZoRW1neRu1aRb5Qr_ks5qeoJogaJpZM4JejbZ
.

reduz أعتقد أن هذا سيكون جيدًا بما يكفي: ابتسم:

reduz أوافق ، ولم أقل أننا بحاجة إلى نص ثانٍ. كنت أتساءل فقط عما سيحدث إذا أضفت نصًا برثًا يرث النص الأول (المخصص المحدد بواسطة المكون الإضافي) ، ولكن بعد ذلك قررت إزالته. هل ستعيد العقدة بعد ذلك إلى نوع المحرك الأساسي دون أي نص برمجي؟

أفترض أنه يمكننا بطريقة ما جعله أكثر سهولة في الاستخدام في هذا الصدد

في 11 آب (أغسطس) 2016 06:10 ، كتب "Marc" [email protected] :

reduz https://github.com/reduz أوافق ، ولم أقل أننا بحاجة إلى ملف
السيناريو الثاني. كنت أتساءل فقط ماذا سيحدث إذا أضفت نصًا
يرث الأول (العرف المحدد بواسطة المكون الإضافي) ، ولكن بعد ذلك قرر
أزلها. عندئذٍ ستعيد العقدة إلى نوع المحرك الأساسي دون أي نوع
البرنامج النصي بعد ذلك؟

-
أنت تتلقى هذا لأنه تم ذكرك.
قم بالرد على هذا البريد الإلكتروني مباشرة ، وقم بعرضه على GitHub
https://github.com/godotengine/godot/issues/6067#issuecomment -239109334 ،
أو كتم الخيط
https://github.com/notifications/unsubscribe-auth/AF-Z26JUJ0gjaCFwlsIDsINWp3_nqliwks5qeubygaJpZM4JejbZ
.

أحفر جزء الامتدادات بواسطة العقدة المحددة اكتب بدلاً من المسار الموضح في هذا التعليق https://github.com/godotengine/godot/issues/6067#issuecomment -238299152.

بعض الاقتراحات الأخرى لإضافتها:

  • يجب أن يقوم node.get_type () في نوع الملحق بإرجاع اسم النوع.

مثال:

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

node.get_type() should return "MyCustomNode" instead of "Node2D"
  • يمكن أن يوسع المكون الإضافي مكونًا إضافيًا آخر حسب نوعه

مثال:
يقوم المستخدم أ بعمل مكون إضافي لمنبه رؤية أكثر دقة بناءً على Node2D
add_custom_type("PreciseNotifier", "Node2D", preload("precise_notifier.gd"), preload("icon.png"))

ثم يقوم المستخدم ب بتطوير ملحق Trigger استنادًا إلى المخطر الدقيق في مجلد إضافي آخر مع تهيئة أخرى.
add_custom_type("Trigger", "PreciseNotifier", preload("trigger.gd"), preload("icon.png"))
وعلى البرنامج النصي المشغّل.gd ، يجب عليه تمديده باستخدام اسم النوع أيضًا
extends PreciseAddon
بالطبع يجب على المستخدم إضافة كلتا الوظائف الإضافية لاستخدام المشغل

يبدو أن إحدى المجموعات تريد تحديد نوع عقدة مخصصة بدون برنامج نصي كنوع لا يزال مشتقًا من نوع العقدة المخصصة التي تستند إليها بينما تريد المجموعة الأخرى تحديد نفس السيناريو كعقدة عادت إلى قاعدتها في- نوع المحرك. بينما أنا أنتمي إلى المجموعة السابقة ، يمكنني أيضًا رؤية نقطة المجموعة الأخيرة فيما يتعلق بالنوع المخصص الذي لا يزال "مكتوبًا" ويرغب في توضيح ذلك في واجهة المستخدم.

قد يكون الحل الوسط هو الحصول على زر واجهة مستخدم إضافي على صف العقدة في رصيف شجرة المشهد بجوار رمز البرنامج النصي الخاص به مع رمز البرنامج النصي ++. يؤدي النقر فوقه إلى المرور بالنافذة المنبثقة النموذجية "إنشاء برنامج نصي" مع برنامج نصي موروث بالفعل من النوع المخصص ، على سبيل المثال extends Base أو extends "Base" . سيتم بعد ذلك إنشاء البرنامج النصي المحدد وسيحل محل البرنامج النصي المحدد مسبقًا على الفور. لذلك ما زلت تُظهر بوضوح أن هناك برنامجًا نصيًا موجودًا بالفعل على العقدة ، ولكن سيكون لديك أيضًا واجهة مألوفة لاستبدال هذا البرنامج النصي المحدد مسبقًا بسهولة.

من المحتمل أن يكون هذا الاقتراح أقل سهولة لأنه لا يزال يتعامل مع العقد المخصصة بشكل مختلف نوعًا ما عن نظيراتها في المحرك. أفكار؟

بعد إعطاء سنتي 2 في هذه المناقشة ، أعتقد أن المشكلة تكمن في حقيقة أن العقد المتعددة التي ترث ملحقًا تشترك في نفس البرنامج النصي الأصلي افتراضيًا ؛ لا أمانع في رؤية الكود ، كما جادل خوان في بداية هذا الموضوع ، هو اختيار تصميم وأيضًا شيء مهم لجعل سلوك العقدة شفافًا للمطور باستخدام الملحق. ولكن عادةً ما ترغب في تغيير سلوك العقد المختلفة في التعليمات البرمجية ، والطريقة الوحيدة الآن للقيام بذلك هي إزالة مرجع البرنامج النصي الأصلي ، وإنشاء برنامج نصي جديد ونسخ رمز البرنامج النصي الأساسي ولصقه. لا يمكنك حتى save as البرنامج النصي الخاص بالعقدة الإضافية الجديدة إلى ملف .gd جديد ، حيث سيؤدي ذلك إلى تغيير المرجع إلى جميع العقد الأخرى باستخدام البرنامج النصي الأصلي ، لذلك يوجد هذا النسخ واللصق المكون من ثلاث خطوات المراوغة الإجراء.

مرة أخرى ، ليس الأمر معقدًا ، هو أنه في هذه الحالة بالذات ، لا يتصرف الخيار save as في محرر GDScript كما أتوقع ، وأعتقد أنه سيكون أكثر ملاءمة لواجهة المستخدم أن يكون لديك ' زر النسخ والحفظ في محرر GDScript للسماح بالتخصيص السريع للوظائف الإضافية (ومن ناحية الهندسة ، فإن جعل هذا الزر مرئيًا أمرًا منطقيًا لأن هذا يعد أسلوبًا جيدًا لإنشاء ألعاب على Godot دون الحاجة إلى استخدام البرامج النصية الموروثة).

henriquelalves اعتقدت أن تخصيص العقد المخصصة في التعليمات البرمجية هو في الأساس وراثة؟ مثل ، extends "addons/thing/thing.gd" ؟ سيستمر البرنامج النصي الموروث في القيام بنفس الأشياء التي يقوم بها الإصدار الإضافي ، نظرًا لأنك تعرف ما الذي تقوم بتجاوزه. لا حاجة للنسخ / اللصق.

Zylann أنت على حق ، لكن عادةً لا أحب هذا النهج المحدد بسبب رؤية الكود ومراوغات الإكمال التلقائي (على الأقل في 2.1 ، لم أختبره الآن). وفي معظم الأوقات لا أرغب في تجاوز الطرق ، فقط قم بتغيير أشياء معينة ليست متغيرات ممتدة في البرنامج النصي الإضافي الأصلي. هذا ما يزعجني في السلوك الحالي save as ، لا يمكنني إنشاء نسخة من البرنامج النصي بسرعة دون تغيير كل إشارة عقدة إلى هذا البرنامج النصي ؛ وحل هذا بطريقة سهلة لواجهة المستخدم يحل المشكلة الأصلية المتمثلة في وجود عدة عقد للتخصيص ، بالإضافة إلى وجود رؤية للكود وما إلى ذلك (على الأقل في سير العمل الخاص بي ، يمكنني أن أكون الشخص الوحيد الذي يفكر مثل هذا على الرغم من هههه).

henriquelalves حسنًا ، لا يمكنني تحمل النسخ / اللصق tbh xD ويمكنك أيضًا تفرع المكون الإضافي مع التحكم في الإصدار واستخدامه بدلاً من ذلك في المقام الأول.

Zylann Forking يضيف البرنامج المساعد المزيد من الخطوات إلى شيء يجب أن يكون بسيطًا للغاية ، هاهاها. أعتقد أنني سألتزم بلصق النسخ اليدوي إذا لم تكن هذه أولوية ، على الرغم من أنني ما زلت أعتقد أن سلوك save as غريب.

henriquelalves نسخ / لصق IS forking ^^ ولكن إذا تم ذلك بدون التحكم في الإصدار ، فسوف يعضك في الخلف في المستقبل إذا تم تحديث المكون الإضافي.

لا يوفر السلوك الحالي لوجود برنامج نصي مرفق بالعقدة المخصصة أي فائدة تقريبًا لوجود تلك العقدة المخصصة كإضافة مقابل مجرد إرفاق البرنامج النصي بالعقدة. الفائدة الوحيدة هي أنها تظهر في مربع حوار العقدة ، وهي ليست في الحقيقة فائدة على الإطلاق.

أنا في المخيم يقول إن العقدة المخصصة يجب أن تتصرف تمامًا مثل النوع المدمج من الدرجة الأولى. وإلا ، فلماذا عناء صنع / استخدام ملحق لذلك؟ فقط حتى تتمكن من رؤيته في مربع الحوار وليس عليك النقر فوق الزر "إضافة برنامج نصي"؟

RodeoMcCabe تكمن المشكلة في أنه تحت الغطاء ، لا تزال الأنواع المخصصة عبارة عن نصوص برمجية موضوعة في أعلى عقدة داخل المحرك عمليًا ، ولا يمكن تغيير ذلك نظرًا لعدم تجميع عقد النوع المخصص في مصدر المحرك مباشرةً. ما نحتاج إلى القيام به هو صياغة مجموعة محددة من الخطوات / الميزات التي من شأنها أن تسمح لهذه العقد المبرمجة بمحاكاة ، في نظر المستخدم ، سلوكيات عقدة داخل المحرك. فمثلا...

  1. إضافة العقدة إلى نافذة "إنشاء عقدة" (تم)
  2. السماح للمستخدم بتقديم "وصف موجز" نصي للعقدة لنافذة "إنشاء عقدة" (لا يبدو أنه تم إنجازه؟ - على الأقل ، هذا ليس جزءًا من add_custom_type ).
  3. السماح للمستخدم بعرض التسلسلات الهرمية للعقد وتحديد أنواع مخصصة مجردة في نافذة "إنشاء عقدة". قد يتضمن هذا على الأرجح إضافة منطقي إلى الوظيفة add_custom_type لمعرفة ما إذا كان نوعًا مجردًا أم لا. سيحتاج معالج "إنشاء عقدة" إلى التحديث لمنع إنشاء أنواع مخصصة مجردة وفقًا لذلك.
  4. اجعل العقدة SEEM كما لو أنها لا تحتوي على نص برمجي.

    أ. يجب ألا تحتوي العقدة على رمز "البرنامج النصي موجود على هذه العقدة" في إرساء المشهد. لجعل الأمور أكثر شفافية ، ربما يجب أن يكون هناك رمز "هذه عقدة من النوع المخصص" بدلاً من ذلك. قد يؤدي النقر فوق ذلك إلى نقل المستخدم مباشرةً إلى البرنامج النصي المخصص ذي النوع المضاف. إنه يكسر "الانغماس" ، لكنه سيكون تضحية ضرورية لأسباب قابلية الاستخدام (من الواضح أنك تريد أن تكون قادرًا على النظر ورؤية كيفية عمل عقدة من النوع المخصص ، إذا كنت تريد ذلك).

    ب. يجب أن تظهر خاصية البرنامج النصي التي يتم عرضها في المفتش ، بشكل افتراضي ، على أنها فارغة ، ما لم يقم المستخدم بتحميل برنامج نصي عليها ، وفي هذه الحالة يجب أن يشتق البرنامج النصي من نوع البرنامج النصي المستخدم كنوع مخصص. لا يجب على المستخدم معرفة موقع ملف البرنامج النصي للنوع المخصص (يجب إخفاء مفهوم أنه برنامج نصي عنهم). هذا يعني أنه يجب التعرف على اسم السلسلة للفئة المخصصة بواسطة محلل GDScript مثل الفئات الأخرى داخل المحرك (لست متأكدًا من مدى سهولة / صعوبة ذلك) أو يجب أن يكون هناك نوع من الوظيفة العامة لجلب السجل عبر اسم الفئة ، على سبيل المثال بالنسبة للنص المكتوب في add_custom_type("MyClass", "Node", load(res://addons/git-repo/api/my_class.gd), load(res://addons/git-repo/icons/icon_myclass.svg) ، يمكن للمستخدم إنشاء نص باستخدام extends MyClass أو extends custom("MyClass") .

    ج. إذا قام المستخدم بتحميل نص برمجي من نوع مخصص على العقدة ، عندها فقط يجب أن تظهر أيقونة "هذه العقدة لها نص برمجي" في رصيف المشهد.

  5. أيًا كان رمز المحرر المستخدم للنص البرمجي ، يجب إضافته إلى مجموعة الفئات بدلاً من رمز المربع الأبيض المستخدم حاليًا للنصوص البرمجية (في property_editor.cpp ). يجب أن يكون هذا جزءًا من خاصية القاموس __meta__ لكائن عقدة النوع المخصص.

  6. عند النقر فوق "إضافة برنامج نصي" على نوع مخصص ، يجب أن يملأ حقل "يرث" مسبقًا بأي طريقة مستخدمة في 4 ب.
  7. إذا قمت بإزالة نص برمجي ، فيجب أن يظل البرنامج النصي المخصص موجودًا تحت الغطاء ولا تتم إزالته. ستستخدم عقد النوع المخصص بشكل فعال البرنامج النصي من النوع المخصص كبرنامج نصي احتياطي في الحالات التي يتم فيها تعيين البرنامج النصي المحمّل على قيمة خالية. على هذا النحو ، لا يزال يتعين عليك رؤية رمز محرر الأنواع الأساسية وخصائص البرنامج النصي في رصيف مشهد المحرر ورصيف المفتش. أنا بالفعل بصدد الدمج في ميزة لاستبدال "Script Variables" بأسماء البرامج النصية الفعلية ، على الرغم من أنها قد تحتاج إلى التحديث في حالة إضافة كل هذه التغييرات.
  8. يجب أن يُرجع Object::get_script() null للعقد بنص نصي مخصص ولا يوجد نص برمجي محمل.
  9. Object::get_property_list ، والوظائف المماثلة للطرق والإشارات يجب أن تتضمن محتويات البرنامج النصي من النوع المخصص حتى لو لم يكن هناك نص برمجي محمل.
  10. من المحتمل أن تكون هناك حاجة إلى وظيفة كائن C ++ ثانية مثل Object::get_custom_script() أو شيء ما بحيث يمكن للمحرك معرفة ما إذا كان هناك نص برمجي ، حتى لو لم يكن جانب البرمجة النصية على دراية بهذا النص الثاني.
  11. يجب أن تفشل محاولات تحميل برنامج نصي مشتق من النوع غير المخصص على كائن بشكل واضح والإبلاغ عن خطأ (ربما يكون Bool مرجع &is_valid في الوظيفة المرتبطة) لتأكيد ما إذا كان الكائن مسموحًا له بالقيام بذلك. يجب أيضًا تحديث سيناريوهات Godot Editor المرتبطة التي يجب أن تقدم تعليقات على هذه المعلومات لتأخذ في الاعتبار ذلك.

هذا مجرد خدش للسطح ، لكنني أعتقد أن نوع السلوك الذي يبحث عنه المستخدمون يدور حول هذا النطاق الواسع (لذا فهو مكثف جدًا). نريد أن نجعل وجود أنواع مخصصة يمكن الوصول إليها إذا لزم الأمر (لذا اجعل رمز النوع المخصص في رصيف المشهد في صف العقدة لعرض البرنامج النصي الخاص به) ، ولكننا نريد أيضًا إخفاء وجودها قدر الإمكان حتى نتمكن من إدراك لهم كأنواع داخل المحرك. سيستغرق الأمر الكثير من العمل للقيام بذلك بشكل صحيح لأنه قد يؤدي إلى كسر الأشياء في الكثير من الأماكن.

هل أي من هذا يبدو جيدا؟ أنا متأكد من أن هناك المزيد من العناصر التي أفتقدها لأنني أفكر في الأمر قليلاً. إذا كان هذا يبدو مجنونًا ، فأخبرني فقط. ؛-)

تحرير: آه ، لكن اقتراح reduz بإخفاء رمز البرنامج النصي فقط في قفص الاتهام إذا كان البرنامج النصي يتطابق مع نص النوع المخصص قد يكون ذا قيمة أيضًا. فقط ، يجب أن تستمر الطريقة get_script() في إرجاع أي شيء. ربما هناك طريقة للقيام بذلك دون الحاجة إلى إنشاء خاصية نصية منفصلة على الكائن نفسه؟ Idk ، لأن هناك الكثير من الافتراضات الموجودة بالفعل في مصدر البرنامج النصي لكل كائن ، والتي أعتقد أننا نريد الاحتفاظ بها ، ولكن يصعب الحفاظ عليها مع مفهوم البرنامج النصي custom_type .

اقتراحات جيدة ، مدروسة جيدا. أعتقد أنه إذا تم تنفيذ كل هذا ، فسيعطي السلوك الذي نبحث عنه ، ومع ذلك أعتقد أن كسر النص الواحد لكل قاعدة عقدة قد يكون أخبارًا سيئة قد يتردد صداها في العديد من الأجزاء غير المتوقعة من الكود. خذ ذلك بحبة من الملح لأنني لا أعرف قاعدة الكود بشكل جيد و C ++ الخاص بي متواضع. ذكر Reduz أعلاه أنهم حاولوا في الأصل الحصول على أكثر من برنامج نصي واحد لكل عقدة و "لقد كان الأمر أكثر صعوبة ، وهو ما يبدو معقولًا بالنسبة لي.

النقاط من 1 إلى 4 رائعة ، وأعتقد أنها قابلة للتحقيق دون كسر قاعدة النص الواحد. من الواضح أن الأنواع المخصصة للملخص ليست مشكلة نظرًا لأنه لا يمكنك إنشاء مثيل لها على أي حال ، وبالتالي لا يمكن للمستخدم إضافة برنامج نصي إليها في المحرر. ومع ذلك ، فمن المتصور أنهم قد يحاولون القيام بذلك من خلال التعليمات البرمجية ، لذلك يجب وضع الفحوصات والأخطاء الضرورية في مكانها الصحيح.

النقطة 6 جيدة أيضًا ، وهنا أعتقد أنه يمكننا التخلص من هذا. سيؤدي إنشاء برنامج نصي جديد وفقًا للنقطة 6 إلى تغيير البرنامج النصي المرفق حاليًا بالعقدة المخصصة إلى البرنامج النصي الجديد (المشتق). تتم إزالة البرنامج النصي القديم (الأساسي) من العقدة. نظرًا لأن النص المرفق الجديد مشتق من النص الأصلي ، تظل جميع الوظائف. غالبًا ما أفعل هذا ، حيث لدي فئة أساسية (مجردة أم لا) وأرفق نصوصًا مشتقة بالعقد. الاختلاف هنا هو أن البرنامج النصي الجديد قد يضطر إلى نطق extends "res://addons/path/to/base-script.gd" بدلاً من مجرد اسم العقدة المخصصة ، لأن النوع المخصص لم يعد مرفقًا بهذا النص البرمجي .... على الرغم من أنه عند التفكير الثاني ، remove_custom_type() لم يتم استدعاء

النقاط 7 و 8 و 9 جيدة ، وربما لا تكون صعبة للغاية مع الحفاظ على قاعدة النص 1. 10 ليس ضروريًا إذا احتفظنا بقاعدة البرنامج النصي 1. 11 جيد ، لأن هذه هي الطريقة التي تتصرف بها العقد المضمنة إذا حاولت إرفاق نص برمجي بها لا يمد نوع العقدة.

على أي حال ، يبدو أن هناك الكثير من العمل ، ونحن في مرحلة تجريبية بالفعل ، لذلك أعتقد أن هذا سيكون 3.1 أو حتى 3.2 (لم ألق نظرة على خريطة الطريق مؤخرًا).

RodeoMcCabe نعم ، هذا بالتأكيد لن يكون لـ 3.0.

قد يكون كسر البرنامج النصي الواحد لكل قاعدة عقدة أخبارًا سيئة قد يتردد صداها في العديد من الأجزاء غير المتوقعة من الكود

أفكاري بالضبط. أفكر في واجهة عامة يكون فيها الكائن على دراية بنصه الاحتياطي المخصص ، لكن الكائنات الأخرى لا تدركه ، وتدرك ببساطة أن الكائن يحتوي على نص برمجي واحد. ستكون الحيلة في تحرير واضع و getter لخاصية البرنامج النصي. يجب أن يتحقق الحاصل من قيمة فارغة. إذا كان فارغًا ، فيجب أن يعيد البرنامج النصي الاحتياطي بدلاً من ذلك. وبالمثل ، يجب أن يتحقق الواضع مرة أخرى من أن أي برنامج نصي جديد يمتد إلى نص النسخ الاحتياطي ، وإلا فإنه يجب أن يبلغ عن فشل بطريقة ما.

من الواضح أن الأنواع المخصصة للملخص ليست مشكلة نظرًا لأنه لا يمكنك إنشاء مثيل لها على أي حال ، وبالتالي لا يمكن للمستخدم إضافة برنامج نصي إليها في المحرر.

لا توجد أنواع مجردة في جانب البرمجة (afaik). هل تقول أنك تعرف كيف تصنع سيناريو مجردة؟ تعرض طريقة can_instance إلى جانب البرمجة النصية ، ولكن كل ما تفعله هو التحقق مما إذا كان البرنامج النصي نفسه صالحًا ، وإذا كان أداة ، ما إذا كان ScriptServer قد تم تمكين البرمجة النصية في الوقت الحالي. لا علاقة له بتجريد نوع السيناريو ، لا أعتقد ذلك.

يجب أن تكون قادرًا على التحقق مما إذا كان الفصل مجردة حتى تتمكن طريقة CreateDialog::_update_search من معرفة وقت جعل النص معطلاً / غير قابل للتحديد ، وما إلى ذلك.

لمعلوماتك ، لقد خلقت مشكلة حول الجزء المجرد من المشكلة (# 13401).

أعتقد بشكل عام أنه سيكون ممكنًا إذا كان لدينا عضو خاص backup_script تمت إضافته إلى النوع Object ، ثم استخدم ذلك لإجراء عمليات التحقق من الخاصية script .

ما أفعله في العقد المخصصة لدي هو أن أرث برنامجًا نصيًا أساسيًا ، مما يجعل برنامج العقدة المخصص فارغًا بشكل افتراضي ...


سيؤثر التوريث التلقائي على المكون الإضافي نفسه ، ولن يكون من الممكن إنشاء أكثر من مكون بدون تكرار المكون الإضافي ، أليس كذلك ؟.

تمت إضافة Multiscript للمرة الثانية هذا العام وكان من السهل التخلص منه مرة أخرى (يثير العديد من المشكلات).


قد يؤدي السماح بمشهد كقاعدة للعقدة المخصصة بدلاً من نص برمجي إلى السماح بجذر خالٍ من البرامج النصية.

ما أفعله في العقد المخصصة لدي هو أن أرث برنامجًا نصيًا أساسيًا ، مما يجعل برنامج العقدة المخصص فارغًا بشكل افتراضي ...

عذرًا ، هل تقول أن هذا يؤثر بطريقة ما على التجريد أو بعض الاقتراحات الأخرى التي قدمتها سابقًا؟ أنا لا أرى أين يربط هذا ...

سيؤثر التوريث التلقائي على المكون الإضافي نفسه ، ولن يكون من الممكن إنشاء أكثر من مكون بدون تكرار المكون الإضافي ، أليس كذلك؟

هل تحاول أن تقول إن محاولة تضمين المكون الإضافي في المجلد /addons/ مرتين وتمكينهما في قسم المكوِّن الإضافي في إعدادات المشروع قد يتسبب في حدوث مشكلات بطريقة ما (أعني ، هذا يبدو طبيعيًا جدًا إذا كنت تضيف المكون الإضافي مخصصًا أنواع. لا يمكن أن يكون هناك أنواع مخصصة متعددة معرّفة بنفس الاسم).

لست متأكدًا تمامًا مما تقصده بعبارة "لن يكون من الممكن إنشاء أكثر من واحد دون تكرار المكون الإضافي." يمكنك إنشاء مثيلات متعددة من عقدة من النوع المخصص على ما يرام (؟) لأنها ستنشئ العقدة وتعلق تلقائيًا البرنامج النصي المحدد من النوع المخصص. قد يتضمن اقتراحي تغيير عملية إنشاء البرنامج النصي في CreateDialog للقيام ...

  1. دع البرنامج النصي المدمج في العقدة يقرر ما إذا كان يمكن تثبيت العقدة أم لا (مجردة).
  2. إنشاء نوع عقدة مضمنة.
  3. عيّن البرنامج النصي المخصص كخاصية backup_script للعقدة (غير مكشوفة لواجهة برمجة تطبيقات البرمجة النصية).
  4. دع رمز Object الخاص بالعقدة يتولى مهمة خداع أي شخص آخر لعرض backup_script # $ كخاصية script الرسمية على الكائن.
  5. قم بتحديث البيانات الوصفية لرمز المحرر
  6. قم بتحديث البيانات الوصفية للوصف المختصر (؟)

...بدلا من...

  1. قم بإنشاء العقدة المضمنة.
  2. قم بإرفاق نوع البرنامج النصي المخصص كخاصية script .
  3. تحديث البيانات الوصفية لرمز المحرر المخصص.

تمت إضافة Multiscript للمرة الثانية هذا العام وكان من السهل التخلص منه مرة أخرى (يثير العديد من المشكلات).

أنا موافق. أعتقد أن الكائنات متعددة النصوص ستكون فكرة سيئة في هذه المرحلة (وليست هناك حاجة لها على أي حال). ليس هذا ما أقترحه. في العرض العام ، لا يزال من المفترض أن يحتوي Object على نص برمجي واحد فقط ، لكنني أوصي بتوفر برنامج نصي احتياطي يتولى دور البرنامج النصي (لذلك يعين نفسه لخاصية script ) عندما يتم تعيين الخاصية script الرئيسية إلى null / unloaded ، إلخ. سيسمح لنا هذا بدعم "الأنواع المخصصة" بشكل أكثر فاعلية دون تغيير واجهة قاعدة الشفرة تجاه فئة الكائن. يمكننا بعد ذلك فقط أن يكون لدينا محددًا / جامعًا مخصصًا لخاصية البرنامج النصي للنسخ الاحتياطي التي تسمح للكود (مثل الكود الذي يعين نصوصًا مخصصة من النوع في CreateDialog ) بإضافة وجوده أو إزالته. وبهذه الطريقة ، يعد تعديلًا اختياريًا لكيفية عمل خاصية script وسيؤدي إلى تغييرات ضرورية أقل نسبيًا على المحرك.

أعتقد أن خيارًا جديدًا للقائمة السياقية على العقد من شأنه أن يحل هذه المشكلة "استبدال البرنامج النصي للموروث" ، وقد يكون لهذا الخيار أيضًا قائمة فرعية بجميع النصوص البرمجية المكتشفة التي ترث من البرنامج النصي الحالي و "البرنامج النصي الجديد" في النهاية ، عند النقر فوق البرنامج النصي الجديد يجب أن يعرض مربع الحوار مسار البرنامج النصي في حقل "الامتداد".

أليس من الأسهل والأكثر شفافية مجرد إضافة أداة محرر "استبدال ووراثة البرنامج النصي"؟ أعني ، هذه مشكلة فقط لأنه عندما نقوم بإنشاء عقدة إضافية ، نتوقع أن تكون بدون نصوص - لكن العقد الإضافية هي حقًا مجرد عقد مخصصة تضيفها إلى شجرة إنشاء العقدة ، ويجب أن يعرف المستخدم ذلك. من منظور UX (لكنني لست خبيرًا) ، لا أعتقد أننا يجب أن نضحي بالشفافية من أجل الراحة.

تضمين التغريدة دلالة "النوع المخصص" هي أنك تحاكي نوع عقدة داخل المحرك. قد يعني ذلك أن النص نفسه لا يمكن إزالته. الوظيفة التي تضفيها على العقدة مدمجة فيها ، بنفس الطريقة التي لن تكون فيها قادرًا على إزالة Node2D-ness من Node2D لجعلها تعمل كعقدة نقية.

يغطي منشور Akien الشهير الذي تم التصويت عليه أعلاه تفاصيل مماثلة:

النقطة هنا هي أن النص الذي يحدد العقدة المخصصة يجب أن يكون مخفيًا ، لأنه ليس خاصية للعقدة المثبّتة بل من نوعها. لذلك يجب أن يمنح هذا البرنامج النصي الخصائص للعقدة المخصصة ، ولكن يجب أن يكون غير مرئي لمستخدم العقدة المثبّتة مثل فئات C ++ للعقد المدمجة. سيوفر واجهة برمجة تطبيقات ، ولكن لن يكون قابلاً للتعديل ، قابل للتوسيع فقط.

إذا أنشأنا أي أدوات محرر لتسهيل "استبدال البرنامج النصي للأشياء الموروثة" ، فسيكون ذلك رائعًا ، ولكن لا ينبغي أن تتمكن أي من الوظائف من رؤية طبقات التسلسل الهرمي للبرنامج النصي عند أو أسفل البرنامج النصي المخصص لأنه من المفترض لمحاكاة السلوك "الداخلي".

في الواقع ، لكي يمكن الوصول إلى المحتوى من gdscript_parser ومحتوى البرمجة النصية الأخرى ، قد يكون من الأفضل التأكد من تضمين معلومات النوع المخصص في ClassDB المفرد بدلاً من EditorNode::get_editor_data().get_custom_types() فقط منذ ذلك الحين لن تتمكن الوحدات النمطية من الوصول إلى هذه المعلومات ، ولكن يجب حقًا الوصول إليها.

ليس لدي أي مشكلة شخصية في الكشف عن النص ، فهذه في الحقيقة مسألة مصطلحات وفلسفة ، وفقًا لما ذكرته ، ما يمكن فعله هو إضافة فئة جديدة إلى ClassDB وإضافة خاصية البرنامج النصي إلى تلك الفئة بدلاً من يجب أن تتحقق العقدة والفئة من وجود هذا البرنامج النصي للطرق واستدعائها قبل استدعاء والدها. أعتقد أنه ممكن ، لكنني سأكسر التوافق مع الإصدارات السابقة إذا لم يتم ذلك قبل RC1

willnationsdev أرى ، أنا لا أتفق تمامًا مع الأنواع المخصصة التي يتم التعامل معها كعقد داخل المحرك. بالنسبة لي ، تكمن "قوة" إضافات المحرر في مدى سهولة إنشاء "حزمة" من العقد المخصصة وأدوات التحرير ومشاركتها عبر github ؛ كل هذه الأدوات والعقد هي ، في الواقع ، مجرد مشاهد ونصوص يمكنك نسخها ولصقها ، لكن Godot يوفر واجهة برمجة تطبيقات Addon لتسهيل ذلك. عندما استخدمتها لأول مرة ، توقعت أيضًا أن تكون الإضافات بدون نصوص ، ولكن فقط لأن المحرك نفسه بدا وكأنه يعاملهم كعقد داخل المحرك ، وهذه مشكلة UX ، وليست معمارية. ما أعتقد أنه سيصحح هذا هو:

  1. تظهر الأنواع المخصصة في شجرة إنشاء العقدة بلون مختلف (تشير بوضوح إلى أنها أنواع مخصصة).
  2. عند إضافتها إلى المشهد الخاص بك ، تكون أيقونة البرنامج النصي موجودة ، لكنها شفافة قليلاً (تشير إلى أن لديهم نصًا افتراضيًا معهم ، ولكن يمكن استبداله). سيؤدي النقر فوق رمز البرنامج النصي إلى إظهار البرنامج النصي ذي النوع المخصص في المحرر.
  3. سيؤدي الزر "إضافة نص برمجي" على الأنواع المخصصة إلى ملء خيار "يرث" تلقائيًا بنص من النوع المخصص.

مرة أخرى ، أنا بالتأكيد لست خبيرًا ، لذا فإن افتراضي الأصلي للأنواع المخصصة! = العقد داخل المحرك قد تكون خاطئة ؛ أيضًا ، حلك هو الأكثر وضوحًا الذي رأيته في هذا الموضوع ، لذلك أفهم تمامًا ما إذا كان تطوير Godot يسير على هذا النحو.

تحرير: لقد قرأتها مرة أخرى ، و "الحل" الخاص بي هو في الأساس خطوات الحل الست الأولى ، هاهاها.

henriquelalvesMarianoGnu أعتقد أن مزيجًا من هؤلاء سيكون ضروريًا بالتأكيد. إضافة فئة النوع المخصص إلى ClassDB أمر لا بد منه. أحب حقًا الاقتراحات الثلاثة التي قدمتها لـ Henrique. فكرة خاصة 2 (أفضل بكثير من اقتراح رمز مخصص منفصل). وأنا أتفق معك في أننا بحاجة إلى التأكد من أن "أنواع التخصيص" تظل شفافة إلى حد ما. أشعر أنه يجب الحفاظ على التوازن: يجب أن يكون الأشخاص قادرين على فهم ما إذا كان شيء ما نوعًا مخصصًا وما يعنيه ذلك ، ولكن يجب علينا أيضًا بذل قصارى جهدنا لجعل الأنواع المخصصة تبدو وكأنها أنواع محركات.

willnationsdev لقد أخذت هذا من الأصول ، نقلت كود العقدة المخصصة إلى نص برمجي "أساسي":
collision_path_2d-1-modified.zip

المشكلة الفورية التي أراها في ذلك هي أن المكون الإضافي يقوم بتحميل البرنامج النصي ، وهذا البرنامج النصي فريد ، إذا أضفت عقدة مخصصة أخرى ، فسيكون لها نفس البرنامج النصي.

إذن ، ما الذي يعنيه استبدال البرنامج النصي للمكوِّن الإضافي في هذه الحالة؟ (ربما لا شيء ، لست متأكدًا).

إذا لم تكن هناك مشكلات في استبدال البرنامج النصي (قد لا يكون وضع الأداة سعيدًا في بعض الحالات) ، يمكن لقائمة العقد المخصصة إضافة إدخال "توسيع البرنامج النصي المخصص" للقيام بعملية الاستبدال هذه.

henriquelalves @ eon -s أعتقد أننا نفكر في نفس الأشياء. أنا على متن الطائرة مع كونها مشكلة UX أكثر من أي شيء آخر. حتى الآن أنا متحيز لهذا النهج لأنني أعتقد أنه يبقي الأمور بسيطة قدر الإمكان ، وهو أمر جيد دائمًا IMO.

إذا لم تكن هناك مشكلات في استبدال البرنامج النصي (قد لا يكون وضع الأداة سعيدًا في بعض الحالات) ، يمكن لقائمة العقد المخصصة إضافة إدخال "توسيع البرنامج النصي المخصص" للقيام بعملية الاستبدال هذه.

أعتقد أنه نظرًا لأن البرنامج النصي الموسع يجب أن يرث من البرنامج النصي للمكون الإضافي ، فلن يكون استبداله مشكلة. لكن ، مرة أخرى ، لست على دراية بقاعدة الشفرة. على أي حال ، لقد أعطيت 2 سنتي ، سأتركها للمطورين الحقيقيين من هنا ؛)

willnationsdev آسف ، لقد اختلطت حول الأشياء المجردة. تحتوي الأصناف الأساسية "abstract" على تعليمة طباعة في _init () لإخباري إذا قمت بتكوين مثيل لها عن طريق الصدفة ....

فقط للتناغم هنا ، يجب أن تتصرف أنواع العقد المخصصة تمامًا مثل أنواع المحرك ، بما في ذلك تعيين نص برمجي مخصص ، والقدرة على الإحالة والوراثة بالاسم في GDScript ، وعدم القدرة على إزالة البرنامج النصي الأساسي للنوع. هذا يحاكي سلوك العقد التي ينفذها المحرك ، مما يعزز الاتساق الداخلي وسهولة الاستخدام.

فيما يتعلق بمسألة إظهار أنها عقدة "مخصصة" ، أقترح أن العقدة لديها إدخال في القائمة المنسدلة للمفتش أعلى "إظهار في التعليمات" والتي تعرض ملف البرنامج النصي الأساسي للكائن. من وجهة نظر المستخدم والمطور ، يجب أن تعرف أنها عقدة مخصصة فقط باستخدامها (من أضافها أيضًا إلى المشروع؟) ، والهدف من العقد "المخصصة" (IMO) هو السماح بتحديد الأنواع في GDScript التي لا يمكن تمييزها من أنواع المحركات المدمجة.

@ Web-eWorks أنا أعمل بالفعل على هذا (في هذه اللحظة بالذات) وقد أنجزت جزءًا لائقًا منه (لا يزال لدي بعض الطرق للقيام بها). لقد قمت بإعداد برنامج نصي احتياطي في فئة الكائن وأنشأت تخزينًا لأنواع مخصصة في ClassDB جنبًا إلى جنب مع تحديث أساليب EditorPlugin لاستخدام واجهة برمجة التطبيقات الجديدة. لا يزال يتعين عليك إجراء تحديثات لوظائف ClassDB ذات الصلة (أشياء مثل can_instance و get_parent_class ، إلخ.) وتحديث جميع عناصر Editor / CreateDialog.

willnationsdev ، تجدر الإشارة إلى أن التسجيل في ClassDB يعني أيضًا أن الأشخاص الذين يصنعون مكونات إضافية يجب أن يسبقوا فئاتهم لمنع الاصطدامات ^^ "

Zylann نعم ، سيكون ذلك ضروريًا ، للأسف.

في هذه المرحلة ، أعتقد أنني قمت بفرز معظم الارتباطات والتغييرات الأساسية. إنها مجرد مسألة تحديث فئات Editor و CreateDialog و EditorHelp / DocData الآن (ومجمع GDScript).

كما ذكرت من قبل .. ما زلت لا أعتقد أن الحل المقترح جيد.
Plese تحقق معي قبل محاولة شيء من المرجح أن يكون
مرفوض.

في 7 فبراير 2018 20:05 كتب "Will Nations" [email protected] :

Zylann https://github.com/zylann نعم ، سيكون ذلك ضروريًا ،
لسوء الحظ.

في هذه المرحلة ، أعتقد أنني قمت بفرز معظم الارتباطات والجوهر
التغييرات. إنها مجرد مسألة تحديث المحرر و CreateDialog و
دروس EditorHelp / DocData الآن.

-
أنت تتلقى هذا لأنه تم ذكرك.
قم بالرد على هذا البريد الإلكتروني مباشرة ، وقم بعرضه على GitHub
https://github.com/godotengine/godot/issues/6067#issuecomment-363893711 ،
أو كتم الخيط
https://github.com/notifications/unsubscribe-auth/AF-Z2xIYRcs0BFDqTyiFwqlhQWTqjEZtks5tSgIVgaJpZM4JejbZ
.

reduz حسنًا ، لقد كنت أحاول مراعاة المخاوف التي ذكرتها سابقًا.

أنا لا أقوم بتنفيذ أي نوع من نظام متعدد النصوص. أنا أيضًا لا أقوم بصنع البرامج النصية تتنكر ككائنات ClassInfo في ClassDB. كل ما قمت به حتى الآن هو إرفاق برنامج نصي (عبر RefPtr) بالتسلسل الهرمي للميراث في ClassDB. لن تستخدم فئة الكائن "backup_script" إلا عندما يحاول تعيين البرنامج النصي العادي انتهاك التسلسل الهرمي للوراثة في البرنامج النصي للنسخ الاحتياطي.

آه فهمت .. ما هي الحالة إذن؟

في 7 فبراير 2018 20:32 كتب "Will Nations" [email protected] :

reduz https://github.com/reduz حسنًا ، لقد كنت أحاول المشاركة
ضع في اعتبارك المخاوف التي حددتها مسبقًا.

أنا لا أقوم بتنفيذ أي نوع من نظام متعدد النصوص. أنا لست كذلك
جعل البرامج النصية تتنكر ككائنات ClassInfo في ClassDB. كل ما لدي
تم حتى الآن إرفاق برنامج نصي (عبر RefPtr) بالوراثة
التسلسلات الهرمية في ClassDB. ستستخدم فئة الكائن فقط ملف
"backup_script" كلما حاول تعيين البرنامج النصي العادي الانتهاك
في التسلسل الهرمي لميراث البرنامج النصي الاحتياطي.

-
أنت تتلقى هذا لأنه تم ذكرك.
قم بالرد على هذا البريد الإلكتروني مباشرة ، وقم بعرضه على GitHub
https://github.com/godotengine/godot/issues/6067#issuecomment-363900920 ،
أو كتم الخيط
https://github.com/notifications/unsubscribe-auth/AF-Z2yn68Iy6AgAKJHZ4qImH4UBAm5skks5tSghSgaJpZM4JejbZ
.

حالة الاستخدام هي عندما يرغب شخص ما في تقديم نوع جديد من العقدة إلى المحرك باستخدام EditorPlugin ، لكنهم لا يرغبون في أن يكون النوع المبرمج من تلك العقدة قابلاً للتعديل (يريدون التفاعل معها لتقليد نوع داخل المحرك ). لذلك ، على سبيل المثال ، إذا حاولت استخدام get_script() على عقدة بنصها الاحتياطي فقط ، فسيعود فارغًا. إذا حاولت استخدام set_script(null) ، فسيتم تعيين البرنامج النصي على البرنامج النصي للنسخ الاحتياطي. إذا حاولت إجراء set_script(a_script) ، فسيتم تعيين البرنامج النصي بنجاح فقط إذا كان البرنامج النصي الجديد في التسلسل الهرمي للوراثة في البرنامج النصي للنسخ الاحتياطي.

بالنسبة إلى تجربة المستخدم ، أخطط لجعل رمز البرنامج النصي يظهر في المحرر كأيقونة شفافة في حالة وجود نص النسخ الاحتياطي فقط. في هذه الحالة ، سيظل الزر لإضافة نص برمجي عبارة عن زر "إضافة نص برمجي" بدلاً من زر "إزالة البرنامج النصي" ، وسيؤدي النقر عليه إلى ملء النص مسبقًا باسم النوع (على الرغم من أنني قد أحتاج إلى إجراء يتم تعبئته مسبقًا بمسار البرنامج النصي إذا قام المستخدم بتغيير نوع البرنامج النصي بعيدًا عن GDScript / VisualScript ، وما إلى ذلك). بمجرد تعيين نص مختلف ، ستصبح الأيقونة الشفافة غير شفافة مرة أخرى. سيؤدي النقر فوق رمز البرنامج النصي في كلتا الحالتين إلى نقلك إلى التعليمات البرمجية المصدر للبرنامج النصي النشط (رمز مصدر البرنامج النصي الاحتياطي في حالة عدم وجود برنامج نصي آخر).

يجب أن أعترف أنني لا أرى حقًا فائدة هذا ، لذا مرة أخرى ما هو
حالات استخدام محددة تفكر فيها؟

في 7 فبراير 2018 الساعة 20:46 كتب "Will Nations" [email protected] :

حالة الاستخدام هي عندما يرغب شخص ما في تقديم نوع جديد من العقدة إلى
المحرك باستخدام EditorPlugin ، لكنهم لا يرغبون في النوع النصي من
هذه العقدة قابلة للتحرير (يريدون التفاعل معها لتقليد ملف
في نوع المحرك). لذلك ، على سبيل المثال ، إذا حاولت الحصول على get_script () على عقدة
بنصه الاحتياطي فقط ، ثم سيعود فارغًا. إذا حاولت
set_script (خالية) ، ثم يتم تعيين البرنامج النصي على البرنامج النصي الاحتياطي. اذا انا
محاولة set_script (a_script) ، فسيتم تعيينها بنجاح فقط
البرنامج النصي إذا كان البرنامج النصي الجديد في التسلسل الهرمي للوراثة للنسخة الاحتياطية
النصي.

بالنسبة إلى تجربة المستخدم ، أخطط لجعل رمز البرنامج النصي يظهر في المحرر كملف
رمز شفاف في حالة وجود نص النسخ الاحتياطي فقط. في هذه الحالة ، فإن
سيظل الزر لإضافة نص برمجي عبارة عن زر "إضافة نص برمجي" بدلاً من ملف
زر "إزالة البرنامج النصي" ، والنقر فوقه سيؤدي إلى ملء النص بالاسم
من النوع (على الرغم من أنني قد أحتاج إلى جعله مملوءًا مسبقًا بمسار البرنامج النصي
إذا قام المستخدم بتغيير نوع البرنامج النصي بعيدًا عن GDScript / VisualScript ،
إلخ.). بمجرد تعيين برنامج نصي مختلف ، تظهر الأيقونة الشفافة
تصبح مبهمة مرة أخرى. النقر فوق رمز البرنامج النصي في كلتا الحالتين
يأخذك إلى شفرة مصدر البرنامج النصي النشط (رمز مصدر البرنامج النصي الاحتياطي إذا
لا يوجد نص آخر موجود).

-
أنت تتلقى هذا لأنه تم ذكرك.
قم بالرد على هذا البريد الإلكتروني مباشرة ، وقم بعرضه على GitHub
https://github.com/godotengine/godot/issues/6067#issuecomment-363904934 ،
أو كتم الخيط
https://github.com/notifications/unsubscribe-auth/AF-Z26oeOMT4HpjzDsX8eygMSeUhbTgVks5tSgurgaJpZM4JejbZ
.

حالة الاستخدام عالية المستوى هي السماح للمكونات الإضافية (EditorPlugins ، نظام PluginScript / SubModule) بتعريف أنواع العقدة المخصصة "غير المخادعة". في الوقت الحالي ، يعد نظام النوع المخصص مصنعًا رقيقًا لـ "البرنامج النصي على عقدة" ، والذي يحتوي على العديد من مشكلات سير العمل وقابلية الاستخدام إذا كنت تحاول إنشاء أنواع عقدة جديدة ، وأقلها عدم القدرة الكاملة على سهولة وبساطة وفعالية تمديد العقدة المخصصة مع رمز اللعب (على عكس العقد المضمنة). المشكلة الأكثر إلحاحًا هي عدم القدرة على إنشاء عقد مخصصة ترث من العقد المخصصة الأخرى.

تتمثل بعض حالات الاستخدام المحددة في إنشاء عقد منخفضة المستوى: ربما يكون تنفيذ خريطة شبكة فوكسل القائمة على مكعبات السير للتضاريس القابلة للتدمير ، أو Minecraft أو أي نظام تضاريس آخر باستخدام مكعبات السير / الكنتور المزدوج ؛ أنواع التحكم المخصصة (حاوية قائمة دائرية ، كما هو مطبق في العديد من الألعاب الحديثة ، أي نوع من التحكم منخفض المستوى مرتفع بما يكفي ليكون خارج مواصفات المحرك) ؛ وأي مكان تريد إنشاء مكون إضافي يسجل العقد الجديدة. في كل حالة من هذه الحالات ، تريد عادةً إضافة نص برمجي مخصص للتعامل مع كود اللعب ، وأن يكون منفصلاً عن كود "التنفيذ" (مكتوب في GDScript / GDNative).

أعتقد أن ما لم يتم إيصاله هنا هو أن الهدف هو جعل العقد المخصصة تتصرف مثل عقد المحرك دون الحاجة إلى كتابة وحدة محرك وتجميعها.

هذا التحسن ليس بالضرورة مدفوعًا بميزة معينة (على الرغم من وجود العديد منها) ، بل بالأحرى بسبب منطق "الطريقة الحالية متخلفة ، واهية ، ومملة". إذا تم تنفيذه بالكامل ، فإن هذا النظام سيسمح بطريقة قوية للغاية لتوسيع أنواع المحرك المدمجة من GDScript / GDNative دون الحاجة إلى إعادة ترجمة المحرك. من وجهة نظر التصميم ، يعد هذا حرفياً تحسينًا مباشرًا على النظام الحالي.

إذا كنت تريد حالة استخدام معينة بعد كل ذلك: النظام البيئي للمكوّن الإضافي / AssetLibrary بالكامل .
هذا هو نطاق الفوائد من هذا التغيير.

حسنًا ، إليك مثال واضح:

لدي مكون إضافي أعمل عليه ، godot-skills ، والذي يقدم مجموعة متنوعة من أنواع العقد الجديدة:

التأثير: إيماء للمنفذ
الهدف: متشابه ، لكنه يبحث فقط عن العقد الأخرى ويجمعها
المهارة: تجمع بين التسلسلات الهرمية للمستهدفات والتأثيرات للعثور على العقد وتطبيق التأثيرات عليها جميعًا
SkillUser: "يمتلك" عدة مهارات

أرغب في أن تكون كل من هذه العقد أشياء يمكن للمستخدمين إنشاؤها وإضافتها إلى المشهد مباشرةً. ومع ذلك ، تم تصميم كل واحدة من هذه العقد لتكون بمثابة نوع أساسي. ليس لديهم الكثير من الوظائف خارج الصندوق ، ويجب أن يكون لديهم نص اشتقاق موضوع على أي عقدة يمكن أن يشاركوا فيها. بالنسبة لحالات الاستخدام مثل هذه ، قد يكون من المفيد إنشاء عقدة لا تريد أن يتمكن المستخدم من إزالة مجموعة معينة من وظائف البرمجة النصية منها. على سبيل المثال ، أريد منع المستخدمين من وضع نص برمجي غير مشتق من Targeter على أي عقدة Targeter يضيفونها إلى مشهدهم. هذا بسبب وجود وظائف فورية تحصل عليها المهارات من وجود مستهدفين كأطفال (على غرار عقد Area2D و CollisionShape2D).

يتطلب سير العمل الحالي أن المستخدمين ...

  1. أضف عقدة من النوع المخصص
    2 أ. قم بإزالة البرنامج النصي المرفق به وانقر فوق الزر "إضافة برنامج نصي" أو
    2 ب. قم بتعيين خاصية البرنامج النصي على العقدة
  2. ابحث في نافذة الحوار حيث يحتفظ EditorPlugin بالنوع النصي المخصص الذي ترغب في اشتقاقه.

سيسمح لك هذا النظام باستبدال كل هذا بـ:

  1. أضف نوع عقدة مخصص.
  2. إضافة كبرنامج نصي (والذي يبدأ تلقائيًا في اشتقاق نوع البرنامج النصي المخصص)

سيتمكن المستخدمون من إضافة الأنواع المخصصة الخاصة بهم ديناميكيًا والتي تشتق الأنواع الموجودة في المحرك (لتسهيل الاستخدام). سيعزز أيضًا أمان وظيفة المكون الإضافي من خلال فرض وجود الوظيفة النصية على العقدة المعنية. حاليًا ، يمكن للمستخدمين بسهولة إزالة البرنامج النصي وكسر الأشياء (غير مرغوب فيه). علاوة على ذلك ، إذا أراد شخص ما "مسح" البرنامج النصي الموجود على العقدة ، فلا يجب أن تفقد هذه العقدة وظائفها من النوع المخصص (هذه مهمة كبيرة). يجب أن يعود إلى وجود نوع البرنامج النصي المخصص.

حسنًا ، تحديث. لدي حاليا ما يلي.

  • يمكن الآن لـ ClassDB إضافة أنواع مخصصة وإزالتها مباشرةً.
  • يحتوي EditorPlugin على أساليب نوع مخصصة مماثلة لا تضيف وتزيل فقط النوع المخصص فحسب ، بل تضيف البيانات الأخرى المتعلقة بالمحرر مثل الرمز. ترتبط هذه الطرق بإشارة جديدة تنبعث عندما يتم تبديل EditorPlugin نشطًا / غير نشط.
  • يمكن أن ترث GDScripts الآن بشكل صحيح مباشرة من أسماء الأنواع المخصصة لتوريثها من البرنامج النصي.
  • ستنشئ رصيف المشهد أيقونة برنامج نصي شفاف عندما يتطابق النص الحالي مع نوع البرنامج النصي المخصص للعقدة. سيؤدي النقر فوقه إلى فتح البرنامج النصي المخصص للنوع في المحرر. أثناء وجودك في هذه الحالة ، يتم عرض الزر "إضافة برنامج نصي" بدلاً من زر "إزالة برنامج نصي". إذا تم تحديده ، فسيقوم هذا الزر بملء حقل "يرث" مسبقًا باسم البرنامج النصي من النوع المخصص (إذا لم يكن فارغًا).
  • ستؤدي أي محاولات لإزالة برنامج نصي إلى إعادة تعيين نوع البرنامج النصي المخصص كقيمة البرنامج النصي. على هذا النحو ، لإزالة البرنامج النصي ، يجب عليك أولاً مسح قيمة البرنامج النصي من النوع المخصص بـ set_custom_script(RefPtr()); .
  • يعرض مربع حوار إنشاء عقدة بشكل صحيح علاقات الوراثة والعقد المجردة للأنواع المخصصة.
  • يتم ملء الملف project.godot بجميع الأنواع المخصصة بحيث يمكن للألعاب المنفذة إعدادها في main.cpp قبل بدء بقية اللعبة.

المهام المتبقية التي يتعين إكمالها ...

  • السماح للمستخدمين بإنشاء مستندات API للفئة لأنواع مخصصة.
  • إصلاح خطأ منفصل تمامًا يمنع المستخدمين من تحرير حقل الميراث في script_create_dialog.cpp .
  • ابحث عن طريقة لإضافة أنواع مخصصة وإزالتها ديناميكيًا من الخريطة / المصفوفة العالمية لـ GDScript *
  • تنفيذ دعم النوع المخصص في VisualScript

* لدي بالفعل بعض الأسئلة حول هذا الموضوع.

أولاً ، أرى فقط add_global_constant / _add_global في ملف gdscript_compiler.cpp بدون أي وسيلة لإزالة globals من فئة GDScriptLanguage. هل تتم إعادة تهيئته تمامًا بمجرد إضافة أو إزالة مفردات؟ كيف يتم تحرير المعرفات العالمية ديناميكيًا؟ سيكون هذا حتى يتمكن المستخدمون من تنفيذ MyNode.static_func() دون الحاجة إلى تحميل البرنامج النصي في متغير أولاً.

أثناء تواجدي فيه ، أشعر أن GDScript الخاص بـ Godot يمكن أن يستفيد بشكل كبير من إدخال مسافات الأسماء ، خاصة كجزء من هذا التغيير. سيتعين علينا العثور على المحدد الصحيح لوضع علامة عليها ، ولكن يمكنك التخلص من المخاوف المتعلقة بتضارب الأسماء من أنواع المحركات والمكونات الإضافية عند إنشاء البرامج النصية الخاصة بك. على سبيل المثال ، بافتراض أن \ هو محدد الاختيار ...

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

على أي حال ، كل هذا ^ مجرد أفكار يتم طرحها في الوقت الحالي. إذا تم تقديم مسافات الأسماء ، فيمكنك حتى ربط البرامج النصية تلقائيًا باسم بناءً على اسم الملف الخاص بها باستخدام إشارة resource_saved في EditorNode . لن تكون بالضرورة أنواعًا مخصصة (بمعنى أنه لا يمكنك إزالة البرنامج النصي من الكائن) ، ولكن سيكون من الممكن الوصول إليها بالاسم وحده مما سيكون مفيدًا للغاية وبديهيًا. يمكن أن تتجاوز البرامج النصية التسمية التلقائية الافتراضية ( filename.capitalize().replace(" ", "") ؟) من خلال توفير عنوان محدد في الأعلى ، على سبيل المثال \MyPlugin\mynode . الآن فجأة أصبح "\ MyPlugin \ mynode" معرّفًا عامًا لهذا البرنامج النصي.

إليك مقتطف من تقدمي حتى الآن.

willnationsdev يرجى عدم اختيار \ ، فهو مستخدم بالفعل للهروب وخطوط متعددة. يبدو . أو : أو :: أفضل.

Zylann لقد خططت لاستخدام المحدد كبادئة لأي عقد تتم إضافتها إلى المشروع أيضًا. إذن ، على سبيل المثال ، لن يرغب البرنامج النصي في res://container.gd في حدوث تضارب مع فئة Container الفعلية. إذا استخدمنا نقطة (.) ، فقد تبدو هكذا.

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

أي شخص لديه اعتراضات على هذا النوع من التنسيق؟

تعديل:

قد يواجه ذلك مشكلات داخل وظائف الفئة المشتقة على الرغم من أن ذلك يستدعي طريقة الأصل داخلها:

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

حسنًا ... هل يمثل ذلك مشكلة بالنسبة للثوابت و / أو المتغيرات؟ إذا لم يكن الأمر كذلك ، فيمكننا أن نفترض أن الأقواس تعني أنها دالة فائقة وإلا فهي معرّف مساحة اسم محتمل.

بصراحة ، سأمتنع عن تحديد تباعد الأسماء في الوقت الحالي - يمكن تقديمه لاحقًا ، وأنا أفضل تشغيل النظام الحالي في أقرب وقت ممكن. سنحتاج أيضًا إلى نظام مدروس جيدًا للتسجيل التلقائي للاسم ، وربما يمتد إلى إعادة صياغة الهيكل التنظيمي بأكمله ، وهو قدر لا بأس به من العمل ويتجاوز نطاق هذه المشكلة.

أنا شخصياً أفضل أن يتم التحكم في اسم البرنامج النصي "المسجل تلقائيًا" من خلال إعلان في الملف ، على سبيل المثال

register <NAME> extends <PARENT>

أو صيغة مشابهة تستند إلى مقدمة extend <NAME> الحالية الموجودة بالفعل لـ GDScript.

تحرير: أردت أيضًا أن أسأل كيف سيتم التعامل مع تعيين البرامج النصية المشتقة من أحد الوالدين (على سبيل المثال Spatial) لطفل مخصص (على سبيل المثال Sprite3D-> CustomType)؟ يعمل هذا بالفعل مع أنواع المحركات ، ولن ينجح تقييد البرامج النصية المعينة المراد اشتقاقها من النوع المخصص نفسه بشكل جيد.

@ Web-eWorks عادل بما فيه الكفاية. سأعمل على إتقان واجهة برمجة التطبيقات الحالية ثم سأفتح مشكلة جديدة لتحديد تباعد الأسماء بمجرد تقديم العلاقات العامة.

إذا فهمت جيدًا ما تعنيه @ Web-eWorks ، فلا يزال لدي هذا السؤال بنفسي: كيف يمكنك الالتفاف على حقيقة أن Object يمكن أن يكون له نص برمجي واحد فقط؟ كيف ستكون ... "قابلة للنصوص"؟ لأنه بصرف النظر عن ذلك ، فإن التسجيل في ClassDB ليس أكثر من معرف عالمي من حيث الاستخدام للمبرمجين والمصممين.

Zylann ما فعلته في custom_script مقابل Object . تصبح مهمة فقط إذا تم تعيين قيمة لها ، ولكن إذا تم تعيين نص برمجي لها ، فإنها تعمل كنص / قيد احتياطي لما يمكن أن تكون عليه خاصية script . سيؤدي مسح script إلى تعيينه ليكون custom_script ، وإذا قمت بتعيين Script جديدًا إلى script ، فسيتم تعيينه بنجاح فقط إذا كان Script مثيل custom_script . وكل هذا تتم إدارته بواسطة Object خلف الكواليس ، وبقدر ما يتعلق الأمر بالمحرك ، لا يزال لدى Object s برنامج نصي واحد فقط.

يحتوي محتوى ClassDB فقط على خريطة ثانوية للأنواع المخصصة التي يتم تسجيلها ، وتعيين البرنامج النصي نفسه وبعض المعلومات الأخرى إلى الاسم الذي قمت بتعيينه له. ثم يوفر هذا الاسم وتسلسل الوراثة الخاص به مع طرق الوراثة ذات الصلة ( get_class_list ، is_parent_class ، get_parent ، إلخ). ويتم ذلك كعلامة اختيار لبعض الأساليب. get_class_list سيأخذ الآن علم منطقي حيث يتضمن فقط الأنواع المخصصة إذا قمت بتمرير true كمعامل ثاني. هذه هي الطريقة التي يمنع بها كسر التوافق مع بقية المحرك.

willnationsdev ، مع نظام يجعل البرامج النصية تتصرف مثل الفئات المضمنة ، ما الذي يمنع المستخدمين من الرغبة في اعتبار جميع البرامج النصية والوظائف الإضافية الخاصة بهم مواطنين من الدرجة الأولى مثل الفصول المضمنة ، وإسقاط طريقة "المدرسة القديمة"؟

آه. الطريقة التي تعمل بها البرامج النصية حاليًا هي أنه يمكنك وضع نص برمجي extends Node على VBoxContainer ، ولا يزال يعمل بشكل جيد. إذا كسر التنفيذ الحالي هذا السلوك للأنواع المخصصة ، فستكون هناك بعض المشكلات - هل هناك أي طريقة للحفاظ على سلوك البرنامج النصي المخصص أثناء وجود نص "عادي" مشتق مباشرة من نوع المحرك؟

Zylann هذا هو بالضبط سبب رغبتي في إدخال مسافة الأسماء بحيث يمكن دمج البرامج النصية والمكونات الإضافية بأمان عبر الأسماء دون الاصطدام بالأنواع الموجودة في المحرك. لن يكون هناك ما يمنع الناس من استخدام الطريقة الجديدة فقط وتجاهل الطريقة القديمة. وأعتقد أن ذلك سيكون أفضل بشكل عام. من الشاق أن تضطر إلى استخدام مسار واضح في كل مرة.

@ Web-eWorks لست متأكدًا مما إذا كنت أتابع هنا ، ولكن ...

تعمل الأنواع المخصصة بشكل خاص مثل الأنواع الموجودة في المحرك للوراثة. لذلك إذا قمت بالامتداد من نوع مخصص ، فسيبدو الأمر كما لو كنت تمتد من فرع مختلف تمامًا من التسلسل الهرمي داخل المحرك. السابق. إذا أنشأت نوعًا مخصصًا MyNode يمتد Node ، فلن أتمكن من وضع هذا البرنامج النصي على VBoxContainer تمامًا مثلما لا يمكنني وضع Node2D "على" a VBoxContainer . سيكون هذا في الواقع هو السلوك المقصود.

الآن ، مع مفهوم مسافة الأسماء ، من الأفضل أن تقوم بتسمية البرامج النصية التي ليست أنواعًا مخصصة. لذلك ، في هذه الحالة ، يمكنني إنشاء نص برمجي يمتد إلى Node ووضعه على Node ، VBoxContainer و MyNode . هل هذا منطقي؟

لذا فإن ما أقوله هو أنك إذا أنشأت نوعًا مخصصًا MyNode موروثًا قل MeshInstance ، قم بتكوين عقدة منه في المحرر ، وحاولت إضافة برنامج نصي يرث Spatial إلى العقدة المكتوبة MyNode ، هل سيعمل ذلك بشكل صحيح؟ إنه يعمل بشكل صحيح مع عُقد "المحرك" ، وهذا هو السلوك الذي نحتاج إلى محاكاته.

يجب أن تكون مستقلة عن مساحة الاسم ، لأن هذه مسألة تتعلق بالتأكد من استدعاء البرنامج النصي للنوع المخصص بغض النظر عن النقطة في التسلسل الهرمي للوراثة في البرنامج النصي "على مستوى المستخدم".

@ Web-eWorks نعم ، هذا من شأنه أن يعمل. يجب أن يرتبط كل إدخال من "المستوى الأول" في خريطة custom_types في خريطة ClassDB بالرجوع إلى نوع في خريطة classes ، وإلا سيحدث خطأ والنوع المخصص ليس تم إنشاؤه. يضمن هذا الحفاظ على سلسلة الوراثة عند الانتقال من الأنواع المخصصة إلى أنواع المحركات على طول الطريق حتى Object .

willnationsdev فقط للتأكد - إذا أضفت طريقة _ready في MyNode ، وعقدة جاهزة في البرنامج النصي للمستخدم مشتق من Spatial ، فسيتم تسميتها مثل Spatial._ready(), MeshInstance._ready(), MyNode._ready(), script._ready() ؟ (أو أياً كان الطلب الذي تم إرساله _ready .)

ما زلت متمسكًا بوجهة نظري القائلة بأن هذا غير ضروري ومربك. يجب حل هذه المشكلة من محرر واجهة المستخدم ، وليس من المحرك الأساسي.

reduz هذا ليس شيئًا يمكن حله من واجهة مستخدم المحرر وحدها. ليس إذا كنت تريد التحكم في معالجة المستخدمين للبرنامج النصي على الكائن. يبدو لي أن هذه ميزة يرغب الكثير من الناس في إعدادها.

هل تقترح أن gdscript_compiler يجب أن يشير إلى المحتوى في EditorData من أجل إعداد معرفات عالمية جديدة للأنواع النصية ، بدلاً من تتبعها جميعًا في ClassDB والسماح لـ ClassDB بإدارة جميع معلومات الوراثة في المحرك؟

بالتأكيد هناك جزء منها يحتاج إلى حل من منظور محرر واجهة المستخدم ، ولكن هناك أيضًا جزء يحتاج إلى حل في جوهره. تعد إضافة أنواع مخصصة إلى المحرك ، أنواع الأنواع من منظور ClassDB ، ميزة قوية جدًا وضرورية في النهاية. بقدر ما هو مربك ، ما زلت أصر على أنه ليس أكثر إرباكًا من النظام الحالي ، وربما أقل.

@ Web-eWorks أوافق. لجعل تتبع بيانات الوراثة في المحرر سيكون في الواقع أكثر إرباكًا في رأيي. وقد ينتج عن ذلك حلول بديلة لأن معلومات النوع هذه لن تكون موجودة بعد الآن بمجرد تشغيل اللعبة بدون المحرر (وهذا هو السبب في أنني اضطررت بالفعل إلى بدء تحميل المعلومات في project.godot ليتم تحميلها في ClassDB عند بدء التشغيل. لم يكن هناك EditorPlugins لإضافة الأنواع المخصصة مما تسبب في فشل تجميع GDScripts عند تشغيل المشهد).

@ Web-eWorks وللإجابة على سؤالك السابق ، نعم ، هذا يعمل بشكل صحيح.

في سيناريو الاختبار الخاص بي ، لدي Node.gd الذي يمتد GDSkillsEffect > GDSkillsAPI > Node ، ويتم تشغيل الطرق _ الجاهزة المطبقة في كل نص برمجي بالشكل المناسب الترتيب: API ، التأثير ، Node.gd.

أواجه حاليًا خطأ حلقة لا نهائية من نوع ما على الرغم من أنه عندما يحاول نصان كلاهما الوراثة من البرامج النصية المخصصة حسب الاسم. السابق. إذا كان Node.gd يحتوي على extends GDSkillsEffect و gdskills_effect.gd يحتوي على extends GDSkillsAPI ، فإن محاولة تعديل وحفظ gdskills_effect.gd أو gdskills_api.gd ستؤدي إلى بلا حدود "تحميل" ثم تعطل. ربما هذا هو أكبر خطأ لي في الوقت الحالي.

willnationsdev آه ، لا ، أنا أتحدث عن تمديد Node.gd Node ، _not_ GDSkillsEffect . إذا _that_ يعمل ، فكل شيء جيد.

على سبيل المثال ، إليك تمثيل لشجرة المشهد:

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

@ Web-eWorks آه ، أرى ما تعنيه. حسنًا ، يجب أن يعمل ، لكنني اختبرته للتو ويبدو أن المنطق الخاص بي في Object::set_script() يمنعه لسبب ما ، لذلك هذا خطأ سأحتاج إلى إصلاحه. XD إنه فشل لأنه اكتشف أن Node لا يشتق البرنامج النصي من النوع المخصص (وهذا صحيح ، نعم) ، لكن لا ينبغي أن يفشل في هذه الحالة ، لول.

@ Web-eWorks كما ذكرت ، هذا ليس شيئًا يحتاج إلى التغيير في ClassDB.

لا أعتقد حقًا أن هذا يحتاج إلى حل في جوهره ، لأن كل لغة برمجة تتعامل معها بشكل مختلف. يمكنك بسهولة إنشاء فصل دراسي جديد في Mono وسيعمل. بالنسبة إلى GDScript ، قد تكون حالة بسيطة تتمثل في عرض ملف نصي على أنه ملف عالمي تم تحميله مسبقًا وهذا كل شيء. حل مقاس واحد يناسب الجميع ، كما هو مقترح في العلاقات العامة ، ليس بالتأكيد هو السبيل للذهاب.

willnationsdev أنا أقدر جهودك ، ولكن تمت مناقشة هذا بلا نهاية بالفعل والإجماع هو:

  • تختلف إضافة نوع مخصص لكل لغة نصية ، لذا فإن اختراق شيء ما في ClassDB ، والذي يُقصد به فقط تسجيل عناصر C ++ ، ليس هو السبيل للذهاب.
  • قبل الذهاب إلى مثل هذه الأطوال ، يمكننا تحسين قابلية استخدام واجهة المستخدم للحالات التي تريد فيها توسيع البرنامج النصي لعقدة مخصصة ، لذلك فهي تنشئ وراثة بسيطة.
  • بشكل عام ، فإن إضافة الاختراقات إلى المحرك الأساسي للتعامل مع حالات الزوايا ليس بالطريقة المثلى على الإطلاق. يجب أن تظل Core خالية من الاختراق.

willnationsdev كمرجع ، يتمثل سلوك المحرك في أنه يمكن إضافة أي برنامج نصي يمتد _something_ يساوي أو سابقًا في تسلسل الوراثة إلى عقدة. وبالتالي ، يمكن إضافة نص برمجي extends Spatial إلى MeshInstance لكن ليس Control أو Node ، لأن أيًا من الأخير لا يرث من Spatial . هذا هو السلوك الذي يجب تكراره. (بدون ضغط ...)

reduz لكن هل يؤدي إنشاء فئة جديدة في Mono إلى إضافتها إلى التسلسل الهرمي لميراث المحرك؟ أو مربع الحوار إنشاء عقدة المحرر؟ ربما يجب فتح عدد جديد يوضح بإيجاز الغرض من ذلك ، لأنني أعتقد أننا لا نتحدث عن نفس الشيء هنا.

الهدف من تعديلات ClassDB هو السماح بتسجيل أنواع جديدة من العقد (أو الموارد) دون الحاجة إلى إعادة ترجمة المحرك. عدم إضافة كرات أرضية مخصصة جديدة في GDScript ، على الرغم من أن هذه مشكلة عرضية يعمل willnationsdev عليها في نفس الفرع.

الهدف من ذلك ليس إضافة الاختراقات ، ولكن لإنشاء نظام مصمم جيدًا لتوسيع أنواع المحرك.

@ Web-eWorks التسلسل الهرمي لتوريث المحرك مخصص لـ C ++ ، وليس البرامج النصية. محاولة خلط كلاهما خطأ من الناحية المفاهيمية.

ربما يكون سوء الفهم هو أن مربع حوار إنشاء عقدة يجعل الأمر يبدو وكأنه تمت إضافة فئة جديدة ، لذلك قد يكون من الجيد وضع علامة على هذه الأنواع المخصصة على أنها تحتوي بوضوح على نص برمجي.

@ Web-eWorks إذا كنت تستخدم Mono ، فستبدو بشفافية كما لو تمت إضافة فئة جديدة ، لأنها فئة جديدة. بالنسبة إلى GDScript ، نظرًا لأن الفئات هي ملفات بشكل افتراضي ، فلا يمكن القيام بذلك بهذه الطريقة ، لذا قد تكون طريقة القيام بذلك هي إضافة عالمي جديد بواجهة مستخدم مخصصة لإعداده (كما فعلنا مع التحميلات التلقائية المفردة) ... لكن هذا لا يزال فئة البرنامج النصي ، وليس فئة المحرك.

willnationsdev وجهة نظري في هذا هو أنني أعتقد أنه من الخطأ جعله يبدو كما لو كنت تضيف فئات جديدة فعلية إلى المحرك ، لأنها ليست كذلك. إنه مفتوح للارتباك. إنها مجرد عقدة بها نص ، لذا بدلاً من إخفاء النص ، أعتقد أن الشيء الصحيح الذي يجب فعله هو جعله أكثر وضوحًا في مربع حوار الإنشاء.

reduz حسنًا ، هذا هو الشيء. العقدة + البرنامج النصي هو مشهد. يجب أن تتصرف آلية add_custom_type مثل Mono ، مسجلة "فئة جديدة" ، حتى لو لم تكن "فئة" تقنيًا بأي معيار. إذا كانت هناك طريقة للقيام بذلك دون الحاجة إلى لمس ClassDB ، فأنا آذان صاغية.

أيضًا ، اقترح @ akien-mga أنه في عرض شجرة المشهد ، يمكننا إخفاء البرامج النصية للعقد المخصصة ، لتجنب إرباك المستخدمين بشأن قيامهم بإنشاء هذا البرنامج النصي وتعديله عن طريق الخطأ (ولكن مع الاستمرار في إظهاره في المفتش في الأسفل) .

في مثل هذه العقد ، ستؤدي إضافة برنامج نصي إلى فتح مربع حوار الإنشاء في وضع التوريث ، لذلك سيظل شفافًا جدًا بالنسبة لسير عمل المستخدم ، في حين أنه من الواضح أنه عقدة مخصصة وليست جزءًا من المحرك.

willnationsdev هل من اعتراضات على فتح مشكلة جديدة أكثر إيجازًا تتناول بالتفصيل نطاق التنفيذ على وجه التحديد؟

@ Web-eWorks Node + Script ليس مشهدًا ، العقد في تخطيط الشجرة هي مشهد. يمكنك أيضًا إضافة أنواع موارد مخصصة ، وليس مجرد عقد.

ولا ، لا ينبغي أن يتصرف مثل تسجيل فصل جديد. يجب أن يكون واضحًا تمامًا أنه فئة C ++ مع برنامج نصي مضاف مسبقًا.

@ Web-eWorks نعم ، هذه ليست مشكلة معي. يرجى ذكرني حتى أحصل على ping إذا قمت بذلك. لست متأكدًا مما إذا كنا بحاجة إلى مشكلة منفصلة؟

انظر إليها من وجهة نظر أخرى. حجتك هي جعلها تبدو للمستخدم كما لو كنت تقوم بتوسيع أنواع المحركات بأنواع محركات جديدة.

وجهة نظري هي أنك تقوم بتوسيع أنواع المحركات بالنصوص ، وليس بأنواع المحركات الجديدة. وأن المستخدم ليس غبيًا ويحتاج إلى معرفة ذلك.

reduz ما قصدته عن Node + Script هو أن هذه الآلية تمت تغطيتها بالفعل من خلال إنشاء مثيل للمشاهد.

ربما أخطأت في فهم تطبيق Mono ، لكن أليست الفئات Mono لا تزال برامج نصية؟

reduz أتفق معك في الغالب ، أيضًا عندما قلت إن إضافة برنامج نصي إلى عقدة مخصصة سيقترح ببساطة وراثة ذلك. ولكن كيف تتوقع أن يعمل هذا مع أنواع مخصصة لشبكة GDNative؟

reduz أحد أهدافنا على الرغم من ذلك هو السماح للنصوص البرمجية المخصصة ، هذه البرامج النصية المعينة مسبقًا الموضوعة على فئات C ++ ، حتى لا تكون قابلة للإزالة. هذا شيء لا يمكن القيام به في سياق المحرر حيث يمكنك دائمًا إزالة برنامج نصي في وقت التشغيل (إلا إذا كنت ترغب في الحفاظ على هذه الوظيفة وتأمين نص برمجي مخصص فقط في وقت التصميم في المحرر)

سأكون بالتأكيد منفتحًا على طريقة بديلة. في كلتا الحالتين ، أسهل طريقة هي جعل الكائن يقوم بتعيين البرامج النصية بشكل مشروط لنفسه (كما فعلت في التنفيذ الخاص بي) عن طريق التحقق من بعض فئات التسجيل التابعة لجهة خارجية (سواء كانت ClassDB أو ProjectSettings أو EditorData أو من يعرف أي شيء آخر) . يصبح من السهل جدًا على المحرر نفسه التحقق من ذلك الطرف الثالث وعرض الأشياء بشكل مختلف (كما فعلت في التنفيذ الخاص بي). لن يكون هناك الكثير من العمل ولا أعتقد أن نقل التسجيل إلى سياق آخر غير ClassDB بالرغم من ذلك.

^ هل هذا الحل الوسط مقبول؟ خلاف ذلك ، يجب عليك إدارة كل موقع محتمل يتم فيه تعيين برنامج نصي للكائن للتحقق مع الطرف الثالث. سيكون ذلك أكثر تعقيدًا.

لقد كان التنفيذ الذي قمت به واضحًا جدًا حتى الآن فيما يتعلق بأي "أنواع" البرامج النصية وأيها ليست كذلك. بعد كل شيء ، لا يزال بإمكانك رؤية البرنامج النصي المرتبط بأنواع مخصصة في رصيف المشهد والوصول إليه بوضوح في الفيديو الذي قمت بمشاركته.

willnationsdev أنا أفهم ما تحاول القيام به ، لكنني لا أعتقد أن هذا يمكن إجراؤه بطريقة نظيفة. إنه يخفي تعقيدًا ليس له سبب لإخفائه ، بطريقة لن تعمل تمامًا كما هو متوقع.

Zylann أعتقد أنهما نفس الشيء ، لكن إما أ) النص هو gdnative داخلي ب) يستخدم طريقة داخلية لـ gdnative. أنا لست على دراية كافية بها لأقول بصراحة.

reduz هل تقول أنك لا تريد السماح بأي شكل من أشكال إنشاء قيود قائمة على البرنامج النصي على الكائنات؟ لأنني أستطيع نقل منطق التحقق إلى المحرر نفسه وهذا من شأنه أن يمنحك فحصًا لوقت التصميم للقيود بنفس السهولة (تتغير واجهة المستخدم ، كما قلت) ، لكنها لن تعمل في وقت التشغيل ، لذلك من المحتمل أن يظل الأشخاص قادر على تغيير الأشياء بمجرد تشغيل اللعبة. هل سيعمل هذا بشكل أفضل بالنسبة لك؟ ما زلت أفضل أن أتمكن من التحقق من الأشياء في وقت التشغيل على الرغم من ...

willnationsdev ما نوع القيود المستندة إلى البرنامج النصي الذي تريد القيام به؟

نفس القيود التي كانت تدور حولها خاصية البرنامج النصي المخصص منذ البداية: فرض أن البرنامج النصي المعين يشتق بعض البرامج النصية الأخرى.

أوصي بإخفاء رمز البرنامج النصي للنص الموسع في التسلسل الهرمي للمشهد وفي حالة قيام شخص ما بالنقر فوق الزر "إضافة نص برمجي" بدلاً من وراثة الفئة الأساسية للعقدة ، فإنه يرث البرنامج النصي المهاجم. إنه شفاف ولا يحتاج إلى العبث مع ClassDB على الإطلاق

لذا ، بمجرد مراجعة بعض المعلومات الموجودة في script_language.h ، أشعر أنه يمكنني بالفعل نقل المحتوى الجديد الذي أضفته في ClassDB إلى فئة ScriptLanguage وإنشاء نوع من الفردي ScriptDB لا يتم إنشاؤه إلا إذا كانت لغة البرمجة النصية تنوي استخدامه. ولأن object.cpp يتضمن بالفعل script_language.h ، سيكون قادرًا على القيام بما يلي بـ set_script(const RefPtr &p_script) ...

  1. تحقق مما إذا كان p_script هو في الواقع نص برمجي
  2. تحقق من اللغة التي ينتمي إليها p_script
  3. تسليم p_script و Object المثيل custom_script إلى ScriptDB لـ ScriptLanguage المرتبط ،
  4. الحصول على رد من ScriptDB حول ما إذا كان يمكن تعيين p_script إلى Object نظرًا للقيود التي ينطوي عليها custom_script على Object .

سيسمح لنا ذلك بالحفاظ على كلٍ من ClassDB نظيفًا من أي تعديلات والحفاظ على object.h نظيفًا (بصرف النظر عن أداة ضبط / أداة الحصول على custom_script ). كما أنه يمنع المضاعفات غير الضرورية للغات البرمجة النصية التي لا تحتاج إلى الاعتماد على Godot لتحديد المعرفات ومساحات الأسماء (مثل GDScript و VisualScript ستحتاج ، على عكس C # و C ++ و Python وما إلى ذلك).

بعد ذلك ، كل ما عليك فعله هو تحديد طرق ScriptServer التي يمكنها إجراء عمليات التحقق من المعرف / مساحة الاسم عبر جميع لغات البرمجة النصية القابلة للتطبيق من أجل استبدال الوظيفة التجريبية ClassDB لتأكيد الأنواع المخصصة / وراثة النوع المخصص التسلسلات الهرمية. سهل بما فيه الكفاية.

هل أي من هذا يبدو كبديل مقبولreduz؟

فقط أضف صوتي هنا. لقد بدأت للتو العمل مع Godot ، وعندما قرأت عن إضافات النوع المخصص ، كنت أعتقد بالفعل أنني سأقوم بإنشاء نوع أساسي جديد قابل لإعادة الاستخدام. مثلما تفعل عند إنشاء KinematicBody ، يمكنك إرفاق نص برمجي به ، لكنه لا يزال يفعل كل ما هو KinematicBody الأشياء.

يتم تعزيز هذا بطريقتين:

  1. يطلق عليهم الأنواع. بينما تختلف اللغات فيما إذا كان النوع قابلاً للتمديد أم لا (جافا سكريبت: نعم ، جولانج: لا ، بيثون: نعم) ، فإن النوع الذي تحدده عمومًا يكون قابلاً للتمديد إذا كانت أنواع اللغات من الدرجة الأولى قابلة للتمديد. في Godot ، أنواع الدرجة الأولى قابلة للتمديد ، لكن الأنواع المخصصة ليست كذلك (على الأقل ليس بالطريقة نفسها). من شأن وصفهم بشيء آخر ، مثل مشاهد المباني الجاهزة أو مشاهد القوالب ، أن يساعد في تمييزها على أنها مختلفة.
  1. تظهر في نفس الشجرة كعقد من الدرجة الأولى في نافذة "إنشاء عقدة جديدة". هذا يعني أنك تستخدمها بنفس الطريقة. إن وجود قسم منفصل لـ "المباني الجاهزة" أو "القوالب" أو أيًا كان ما تريد تسميته سيُسميها مرة أخرى على أنها مختلفة.

JPTeasdale لسوء الحظ ، في هذه المرحلة ، الشاغل الأكبر هو التنفيذ ، وليس السؤال "كيف تحدد هذا". وأنواع Godot المخصصة قابلة للتمديد (فهي مجرد نصوص). المحرر ليس لديه دعم التعليمات البرمجية حتى الآن لعرض علاقات الوراثة بين الأنواع المخصصة في مربع حوار إنشاء العقدة ، ولكن البيانات متاحة. أنا أيضًا لا أرى سببًا لإعادة تسميتها من "النوع المخصص" إلى شيء آخر. "المباني الجاهزة" و "النموذج" ليست مصطلحات مناسبة حقًا ، ولا هي مشاهد في المقام الأول (إنها مجرد نصوص ، بسيطة وبسيطة).

أعتقد أنه أبسط بكثير من الحل المقصود:

  1. أضف خاصية مخفية في العارض إلى فئة الكائن تسمى "custom_type_script" وقم بتعيين البرنامج النصي المخصص لتحديد هذه الخاصية بدلاً من البرنامج النصي
  2. عندما تحاول تمديد فحص العقدة إذا كانت هذه الخاصية خالية ، إذا لم يكن الأمر كذلك ، فقم بتمديد هذا البرنامج النصي بدلاً من فئة العقدة (كتابة "res: /path/to/script.gd")
  3. غيّر get_script_instance للإشارة إلى مثيل البرنامج النصي المخصص إذا كانت العقدة النصية خالية

MarianoGnu حسنًا ، من حيث إنشاء تغييرات المحرر ، من الأسهل القيام بذلك عن طريق الملء التلقائي لخاصية script ومنعها من أن تصبح فارغة في المقام الأول (لأن المحرر ينظر فقط إلى script property ، ولا يتعين علينا العثور في كل مرة تشير فيها إلى خاصية script وتعديل هذا الرمز إذا كان كل ما نفعله هو تغيير قيمة script ) .

مع ذلك ، فإن جزءًا من هدف إعادة هذه العملية هو السماح للغات البرمجة النصية بشكل عام بالاشتراك في استخدام المعرفات بدلاً من مسارات الملفات من أجل تحديد موقع فئات البرامج النصية. هذا هو السبب الوحيد وراء اقتراح تعديلات على مفهوم ScriptDB أو تعديل ClassDB في المقام الأول. لكنني الآن أدرك سبب اعتراض خوان على التغييرات الكبيرة التي طرأت على ClassDB ، ومن هنا جاء اقتراح تخزين المعلومات في واجهة برمجة تطبيقات البرمجة النصية وحدها. إنه يحتوي على جميع المعلومات بلغة البرمجة النصية الفردية.

يمكن إجراء مجموعة ، بدلاً من تخزين البرنامج النصي غير المرئي في ملف تخزين العناصر في ScriptDB ، قم بإضافة تمرير مسبق لقارئ البرنامج النصي لاستبدال "extension CustomClassName" بـ "extension" res: /path/stored/inScriptDB.gd "في المترجم المسبق لـ GdScript ، لأن إخراج البرنامج النصي من التسلسل الهرمي الوراثي للنص أمر مزعج للغاية (يجب أن يكون التسلسل الهرمي عبارة عن خط مستقيم من أسفل إلى الجذر ، حيث يؤدي وجود فرع إلى حدوث ارتباك)

لأن إخراج النص من التسلسل الهرمي من البرنامج النصي أمر مزعج للغاية (يجب أن يكون التسلسل الهرمي عبارة عن خط مستقيم من الأسفل إلى الجذر ، حيث يؤدي وجود فرع إلى الارتباك)

MarianoGnu ربما بعض سوء التفاهم هنا. في أي نقطة تعتقد أنه لا يوجد خط مستقيم للميراث؟ بقدر ما ذهبت في تنفيذ الأشياء ، هناك دائمًا تسلسل هرمي واضح جدًا بين النصوص. لم أغير أي شيء حول كيفية عمل التسلسلات الهرمية للوراثة. لقد جعلت من الممكن تعيين نص معين إلى StringName والبحث عنه في قاعدة بيانات من نوع ما.

وإذا كنا نعمل بالفعل على القيام بذلك ، فلا يوجد سبب لاستبدال نص البرنامج النصي بالعودة إلى مسار في مترجم GDScript. كل ما يفعله المترجم هو تخصيص مثيل Script script لمتغير $ # $ 1 $ # $. سواء قمت بتحميل البرنامج النصي من خلال طريقة ResourceLoader::load(path) أو عن طريق جلبه باستخدام Class/ScriptDB::get_script(namespace_and/or_identifier) لا يهم حقًا.

أردت فقط أن أذكر ، كمستخدم جديد لـ Godot ، أنشأت مكونًا إضافيًا تحت الانطباع بأن "العقدة المخصصة" الخاصة بي من المكون الإضافي ستكون بمثابة عقدة مضمنة. أي ، عندما حددته من قائمة العقدة ، توقعت أن أحصل على عقدة بدون برنامج نصي ، ولكن مع الوظيفة التي قمت بكتابتها في المكون الإضافي الذي تم توريثه بالفعل (كما هو الحال بالنسبة للعقد المضمنة). فقط اعتقدت أنه يجب أن أعطي رأيًا آخر من شخص قادم للتو (على الرغم من أنه يبدو أن المناقشة هنا كانت مكثفة بالفعل).

نظرًا لأن "العقدة المخصصة" هي مجرد نص برمجي ، فما هو الاختلاف بين مجرد تعيين البرنامج النصي لعقدة مضمنة؟ ما هي ميزة العقدة المخصصة المفترض أن تفعل؟

MCrafterzz نوقش أنه يجب أن تكون هناك إمكانية لتخصيص العقد لتتمكن من إضافة برنامج نصي عبر عقدة مخصصة تم إنشاؤها من مكون إضافي.

العقدة المخصصة حاليًا هي مجرد عقدة تم إنشاؤها باستخدام برنامج نصي مرفق بالفعل وتغير الرمز والاسم بالفعل.

willnationsdev إلى أي مدى وصلت إلى تطبيق هذه الميزة.
أود حقًا أن تكون هذه الميزة هنا قبل الإصدار 3.1 ، فستكون إضافة رائعة حقًا.
لمكوِّن Godot ونظام الملحق.

لا أريد الضغط على أحد. لذا من فضلك لا تأخذ طريق العمل.

لقد كنت أقوم بتنفيذ خلفية جديدة لنظام النوع المخصص بالكامل. يسمح الجديد للمستخدمين بالقيام بجميع الوظائف الأصلية ، بالإضافة إلى جعلها بحيث يضيف زر Add-a-Script نصًا جديدًا يقوم بتوسيع البرنامج النصي المخصص افتراضيًا (بدلاً من فتح البرنامج النصي المخصص) ويجعله هكذا لا يمكنك إزالة البرنامج النصي المخصص (يجب عليك استخدام أمر محرر تغيير النوع ، تمامًا مثل أي نوع محرك آخر).

تضمين التغريدة

بالإضافة إلى ذلك ، سيسمح للمستخدمين بتسجيل أنواع إلى عالمي يوفر الوصول إلى تعيينات اسم النوع إلى مسار الملف. سيكون GDScript قادرًا على إدراك هذه التعيينات على أنها أسماء أنواع عامة بسيطة بشكل أساسي. علاوة على ذلك ، لا يلزم أن تكون الأنواع أنواعًا مخصصة حتى يتم تسجيلها ويمكن أن تكون الأنواع إما نصوص أو مشاهد.

حتى الآن ، حصلت على الواجهة الخلفية الجديدة مطبقة وأعدت إعداد وظيفة البرنامج النصي الأصلي من النوع المخصص. حاليا سوف تعمل على الميزات الجديدة. ربما يبدأ أسبوع من الآن. أنا مشغول بخلاف ذلك هذا الأسبوع.

willnationsdev لا تقلق ، إذا وصلت إلى 3.1 سأكون راضيًا.
وأدركت أنه قد يتطلب القليل من العمل.
ثابر على العمل الجيد.

في الوقت الحالي ، يتمتع المحرر بالقدرة على توسيع نص برمجي لأي عقدة بسهولة:

extend

تبدو العقدة نفسها حاليًا كما يلي:

2

وكان شاغلreduz الرئيسي هو إخفاء حقيقة أن هناك نصًا مرفقًا بالفعل. من ناحية أخرى ، من المنطقي عدم إخفاء ذلك عن المستخدم. ولكن من ناحية أخرى ، فإن العقد المخصصة ستحتوي دائمًا على نصوص ملحقة. بدون البرامج النصية ، تكون العقد المخصصة مجرد عقد عادية موجودة مع رموز مخصصة ولا تتم إضافة وظائف إضافية.

وعلى الرغم من أنه يمكنك توسيع البرنامج النصي المخصص ، إلا أنه من المزعج جدًا أن تبدو العقد المخصصة العادية مثل العقد المخصصة الموسعة.

إذن ، هذا هو الحل البسيط: عندما يكون البرنامج النصي للعقدة المخصصة هو نفس البرنامج النصي في تعريف العقدة المخصصة ، يجب أن يتلاشى رمز البرنامج النصي ، مثل هذا:

3

المعنى:

4

يا رفاق ، مثال من الحياة الواقعية: إذا كان لدي العديد من الملاحظات المخصصة من نفس النوع ، كل نص برمجي مخصص لمثيله الخاص ، ماذا يحدث إذا كنت أرغب في تغيير البرنامج النصي الأساسي المخصص للعقدة؟ أقول لكم: الأسوأ ، لأنني بحاجة إلى تعديله ، وجميع الحالات الأخرى وفقًا لذلك ، مما يوفر فرصة كبيرة للأخطاء البشرية والأخطاء المطبعية.

أنت لا تريد إخفاء السيناريو؟ حسنًا ، ثم اعرض البرنامج النصي custom_node والبرنامج النصي لعقدة المشروع.

aaronfranke في رأيي هذا هو الحل الأفضل. حتى المشاهد التي تم التقاطها يمكن أن تستفيد من هذا.

zatherz et al ، الآن بعد أن تم تنفيذ # 30697 ، ما الذي يمكن تحسينه أيضًا؟ هل هناك أي شيء آخر في https://github.com/godotengine/godot/issues/6067#issuecomment -238250383 مهم أن تمتلكه؟

إغلاق كما تم تحديده بواسطة # 30697. بينما لم يتم تنفيذ الاقتراح الأصلي في OP في https://github.com/godotengine/godot/issues/6067#issuecomment -238250383 ، لن يحدث هذا بسبب مخاوفreduz في https: // github.com/godotengine/godot/issues/6067#issuecomment -239060186.

هل كانت هذه الصفحة مفيدة؟
0 / 5 - 0 التقييمات