Godot: لا أحد يعرف كيف يعمل جودو. (عقدة Re-MultiScript ، تعتمد على Re-Class)

تم إنشاؤها على ١٦ أكتوبر ٢٠١٨  ·  63تعليقات  ·  مصدر: godotengine/godot

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

بعض القضايا ذات الصلة: # 19486 # 7402 # 15996 # 8502
هذه هي المراكز الأربعة الأولى ، ولكن هناك الكثير من المشكلات المماثلة التي تهدف جميعها إلى حل نفس المشكلة: يبحث الجميع عن سير عمل قابل للاستخدام.

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


هناك وحدة زائفة ، وتعرف أيضًا باسم العقد الفرعية:


يستخدم مستخدمو Godot العقد الفرعية لإنشاء مكافئ لـ MultiScripts.

MeshInstance (Spatail + نصي)
--مش (مش + نصي)
- مادة (عقدة + نص برمجي) - شادر (عقدة + نص برمجي) - نسيج (عقدة + نص برمجي)
- التحويل (Position3D + script)

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

مشاكل:
1.) هو المكافئ الرقمي لإضافة الماء البارد إلى وعاء الغليان ؛ يساعد على المدى القصير ولكنه يسبب المزيد من الارتباك في المشاريع الكبيرة.
2.) ينتهي الأمر بمعظم المستخدمين باستخدام إشارات مثل الأحداث ، وربطهم فقط بالعقدة التي ترسلهم واستخدام التصدير للعثور على الهدف.
3.) يمكن اعتراض الأحداث قبل الوصول إلى العقد السفلية.
4.) الأداء بطيء ويمكن أن يتوقف عند حوالي 50000 عنصر عندما تحاول اللعبة تحميل المشاهد.


Pseudo Unreal ، ويعرف أيضًا باسم وحدات التحكم والمتوسط:

يقوم مستخدمو Godot بعمل وحدات تحكم وعقد حيازة تتلاعب بجميع الأطفال. العلامة التجارية لسير العمل هذا هي الفئات المشتقة مع الامتدادات.

MeshWithTexturedMaterial.instanced () * فقط العقدة في الشجرة
-> يمتد من -> MaterialTextured -> يمتد من -> مادة -> يمتد من -> Shader

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


Pseudo Panda3D ، المعروف أيضًا باسم التحميل المسبق (سيناريو):

هذا واحد يكرر سير العمل لكيفية عمل معظم المحركات القائمة على الكود. غالبًا ما يكون للمطورين نصوص أكثر من العقد.

MeshInstance (عقدة)
التحميل المسبق (نص شبكة)
التحميل المسبق (نص المادة)
التحميل المسبق (تحويل البرنامج النصي)

الغريب أن هؤلاء المطورين هم من يرفضون التخلي عن GDscript ، حتى عندما يكون من الواضح أن C # أفضل لهذا النهج. لهذا أفترض أنهم على دراية ببايثون.
مشاكل:
1.) ارتباك حول كيفية تسمية الواردات ، حيث أن الثوابت ربما تكون متغيرات مع الجاهزية ؛ من تعرف.
2.) نادرًا ما تستخدم عقد Godot ، حتى أنني رأيت مطورين يتجاهلون أدوات واجهة المستخدم تمامًا.
3.) ألم في التصحيح حيث لا يوجد مؤشر على مكان ربط البرنامج النصي.


نص WTF:

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

يسمح MeshInstance (العقدة) التي تحتوي على عقدة فارغة في الأعلى بتحريك الأطفال وإعادة تصميمهم بسهولة.
- مش (مش + سيناريو || إشارة)
- المادة (سبرايت + سيناريو || إشارة)
- التحويل (الموضع ثلاثي الأبعاد + البرنامج النصي || الإشارة)

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

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

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

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

archived discussion core

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

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

ال 63 كومينتر

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

يمكن أن تجعل فئة معقدة مثل MeshInstance مع مكونات متعددة

ما هي المكونات بالضبط؟

تحرير: وفقط كما تعلم ، تم إغلاق إحدى المشكلات التي أشرت إليها حيث قال المؤلف "هذه الفكرة مقرفة حقًا وغير منطقية تمامًا."

لإثبات ذلك ، سأستخدم فئة وهمية لما سيبدو عليه MeshInstance ، إذا تم تصنيعه في Godot.
هناك وحدة زائفة ، وتعرف أيضًا باسم العقد الفرعية:
يستخدم مستخدمو Godot العقد الفرعية لإنشاء مكافئ لـ MultiScripts.
Pseudo Unreal ، ويعرف أيضًا باسم وحدات التحكم والمتوسط:
Pseudo Panda3D ، المعروف أيضًا باسم التحميل المسبق (سيناريو):
نص WTF:
نعم ، أعرف أن Godot لديه فصل MeshInstance.
النقطة التي يوضحها ذلك هي أن معظم مهام سير العمل التي يستخدمها المطورون في الوقت الحالي يمكن أن تجعل فئة معقدة مثل MeshInstance مع مكونات متعددة ؛ باستثناء أن كل سير عمل معيب بشكل خطير.

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

إذا كان السؤال ببساطة: "هل هناك عدة طرق لتحقيق نفس النتيجة في Godot؟" ، فإن الإجابة هي نعم ...

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

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

ما هي المكونات بالضبط؟

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

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

نحن نعلم أنه لا يمكننا الحصول على كل شيء ، لذا فإن السؤال هو ماذا لدينا؟ كيف تم تصميمه للعمل؟

MysteryGM المقارنات الفضفاضة وغير المتصلة ليست مفيدة.

أشياء مثل المواد والتحولات

التحويل خاصية مكانية والمواد هي خاصية Mesh. تم إنشاء MeshInstance فوق Spatial لذا فهي ترث جميع خصائص Spatial. إنه تسلسل هرمي بسيط منطقي بالنسبة لي.

إذا قمنا بإنشاء مكونات مماثلة ، فكيف نربطها بالعقدة؟

لماذا ستنشئ نظام الشبكات الشبكية الخاص بك في حين أن Godot يمتلكها بالفعل؟

ماذا عن المهام الأخرى ، مثل "متابعة الهدف" أو "إطلاق النار على الهدف"

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

لماذا ستنشئ نظام الشبكات الشبكية الخاص بك في حين أن Godot يمتلكها بالفعل؟

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

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

يذهب كود في البرامج النصية.

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

ما أريد معرفته هو كيف يتعامل Godot مع الألعاب الكبيرة ذات الأنظمة المعقدة مثل تأثيرات الطقس والضباب الحجمي والتضاريس الكبيرة؟

ما يلي يتعلق بي وآرائي وتجربتي _YMMV_

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

إذا أخذنا Unity 4/5 كمثال (الذي كنت مقيدًا به لسنوات) ، فإنه يحتوي على مكونات منتفخة للغاية بحيث لا يمكن مقارنتها بأي نظام ECS آخر استخدمته على الإطلاق. وأوه ، هل تريد تقديم طلب http؟ بالتأكيد ، أضف مكونًا جديدًا إلى كائن جديد إلى هيكل المشهد الخاص بك لأنه من المنطقي جدًا ربط طلبات http بالكائنات الموجودة في المشهد ومكوناتها. يبدو أن ميزة "حفظ مشهد بدون تغييرات تكسر جميع UUIDs" تم صياغتها فقط لجعل الأمر أكثر صعوبة على المصممين غير التقنيين لاستخدام التحكم في الإصدار. لا أريد حتى أن أبدأ في "لا تدمر عند التحميل" والمباني الجاهزة.

ما هو الأساس المنطقي بين معظم هذه الأشياء على أي حال؟ أود أن أقول إنه من المحتمل أن يكون تطويرًا عضويًا تكراريًا وبعض الحلول البديلة هنا وهناك (توجد أيضًا في Godot وربما جميع محركات الألعاب الأخرى). أعني ، لقد تحطمت كثيرًا لدرجة أن لوحة مفاتيح Swift الخاصة بي بدأت في التنبؤ بالكلمات "_Unity تحطم_" في كل مرة كتبت فيها "_With_". كان هذا جزءًا كبيرًا من سير العمل الخاص بي ، تعطل -> أعد استيراد جميع الأصول لمدة دقيقة ، واعمل لمدة 30 دقيقة ، كرر.

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

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

لم أستخدم بالفعل Unreal (أو أي محرك لعبة آخر ذي صلة) لأكثر من نماذج أولية ومشاريع اختبار ، لا يمكن مقارنتها بعمق معقول.

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

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

ما أريد معرفته هو كيف يتعامل Godot مع الألعاب الكبيرة ذات الأنظمة المعقدة مثل تأثيرات الطقس والضباب الحجمي والتضاريس الكبيرة؟

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

ضباب صوتي؟ أعتقد أنني رأيت هذا في الإصدار التجريبي الجديد من FPS.

تضاريس شاسعة؟ كان لدي مشروع به شبكات تضاريس إجرائية مرة واحدة وكان يعمل بسلاسة على جهاز الكمبيوتر المحمول الذي يبلغ عمره عامين.

هذه ليست سوى بعض الوظائف وليست "مشكلة كبيرة" تتحدث عنها في OP بالرغم من ذلك.

تأثيرات الجو؟ أنشئ مشهدًا يحتوي على عقدة جسيمية ...

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

تضاريس شاسعة؟

مساحة كبيرة. نحتاج إلى طريقة ما لإعادة تعيين المشاهد إلى Vector3 (0،0،0) بدون تجميدها نظرًا لأنه يلزم إزالة عدد كبير جدًا من العقد. الفيزياء وكل شيء يهتز مع العوامات الكبيرة.

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

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

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

آخر شيء نريد القيام به هو محاربة تصميم المحركات بشدة بينما نحاول تطوير اللعبة.

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

الفيزياء وكل شيء يهتز مع العوامات الكبيرة.

انظر # 288

ومع ذلك ، ليس لدينا أي فكرة عن الاستراتيجية التي خطط جودو لها أو ما إذا كانت قد فعلت ذلك.

أنا أفهم أنه نوع غريب في البداية ، لكن بالنسبة لي ، فإن استخدام العقدة + البرنامج النصي واضح ومباشر. أوصي بالتأكيد بإلقاء نظرة (على الأقل) على نسخة الهوايات من هذه الدورة هنا: https://gumroad.com/gdquest
إنها تستخدم بنية نصية للعقدة تشبه إلى حد بعيد هيكلي ، ويمكن أن تعطيك بالتأكيد رؤية أفضل حول كيفية استخدام أولئك المشاركين حقًا في المحرك ؛ المؤلف مساهم رئيسي في مستندات godot.

تحرير: في الواقع ، يمكنك إلقاء نظرة على المصدر في المستودع ، إذا كنت لا تريد الدورة التدريبية https://github.com/GDquest/make-pro-2d-games-with-godot

مع بقاء 14 يومًا لاتخاذ قرار بشأن استخدام Godot ، آمل أن يتمكن مطورو المحرك من شرح كيف يُفترض أن يعمل في مشاريع كبيرة.

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

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

أعتقد أنه يمكن تقديم حجة لمزيد من التوثيق حول أمثلة هيكل المشروع ، لكنني أعتقد أن هذه مجرد مسألة المزيد من المساهمات في التوثيق.

مشاهد منفصلة واستخدام OOP لإعادة استخدام العمل.

كما ذكرت من قبل ، فإن تحريك الأشياء بعد توصيل الإشارات يمثل ألمًا. خاصة عندما يتوقفون عن العمل دون إعطاء استثناء أو تحذير.
قررنا استخدام أداة إعادة بناء ديون خارجية ، بعد أن ذكرها مطور آخر ؛ ولكن مع ذلك لا يمكنها حل مشاكل جودو الفريدة.
ينتج عن عدم تحريك الأشياء هذه المشكلة (صور من "لوحة المشكلات" الخاصة بنا):
pawndefend
لإصلاح هذا قمنا بعمل عقد فرعية. باستثناء حوالي 50000 يبدأ في التسبب في مشاكل حتى لو كانت مجرد عقد.
pawnfollow

ما نريد أن نعرفه هو كيف نتعامل مع هذه المشكلات ، وكيف خطط جودو للتعامل معها ؛ اختبرنا كل سير عمل ذكرته أعلاه.

انظر # 288

شكرًا على ذلك ، نحن معتادون على تنسيق عالم الراحة ، ولم نتحقق من هذا مطلقًا.

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

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

لماذا تحتاج 50000 عنصر في لعبتك؟ بالتأكيد هذا من شأنه أن يتخلف عن أي محرك.

لماذا تحتاج 50000 عنصر في لعبتك؟

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

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

في هذه الحالة ، يبدو أنك قد اخترقت المنطقة التي تعد فيها الوحدات المخصصة خيارًا جيدًا.
http://docs.godotengine.org/en/3.0/development/cpp/custom_modules_in_cpp.html
يمكنك إنشاء عقد مخصصة هناك ، وتجنب الكثير من التداخل.

تحرير: على الرغم من أنني أزعم أن 800 عنصر لواجهة مستخدم واحدة (أصغر؟) تشير إلى التصميم / الهندسة المعمارية السيئة.

أخفق بشدة في فهم كيف يمكنك الحصول على ما يقرب من 64 نصًا لكائن واحد. تبدو هذه مشكلة تصميم لمشروعك أكثر من كونها مشكلة جودو (مرة أخرى ، من المحتمل أن تتأخر عن أي محرك). دمج التعليمات البرمجية الخاصة بك في عدد أقل من البرامج النصية. لا تقم بإنشاء نص برمجي لكل جزء من الوظائف ، ولكن بدلاً من ذلك لكل نوع من الكائنات (إذا كان بإمكان عقدة "العدو" تنفيذ XYZ ، فقم بإضافة هذا الجزء إلى البرنامج النصي للعدو بدلاً من إضافة العقد الفرعية لوظائف X و Y و Z) . إذا كنت بحاجة إلى المزيد من الميزات المتقدمة للقيام بذلك ، فربما يمكنك الاستفادة من الوراثة المخصصة و / أو واجهات C #.

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

نرى أن هذا كان أحد الأشياء التي نتساءل عنها ، لأننا جميعًا نعرف C ++ إذا كانت هناك حاجة إلى Custom Modulse ، فسنقوم بدلاً من ذلك بتحرير محرك Godot.
نعلم أنه يمكننا استخدام # بأمان حيث يكون تحميل Godot المسبق () موضع شك ؛ لا أحد يستطيع أن يخبرنا عن مدى استقراره أو ما إذا كان هناك أي سلبيات.

أخفق بشدة في فهم كيف يمكنك الحصول على ما يقرب من 64 نصًا لكائن واحد.

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

قاعدتنا في الوقت الحالي هي فصل ملاحظات المستخدم عن الآلية.

إذا كان بإمكان عقدة "العدو" تنفيذ XYZ ، فقم بإضافة هذا الجزء إلى نص العدو بدلاً من إضافة العقد الفرعية لوظائف X و Y و Z

إذا نظرت إلى الصور و Pseudo Unreal ، ويعرف أيضًا باسم وحدات التحكم والمتوسط.

لأننا جميعًا نعرف C ++ إذا كانت هناك حاجة إلى Custom Modulse ، فسنقوم بدلاً من ذلك بتحرير محرك Godot.

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

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

ردًا على المشكلات المشار إليها في OP:

  • 19486:

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

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

  • 7402: مرة أخرى ، فئات البرامج النصية هي الحل لهذه المشكلة ("الحل الأبسط" الذي فكر فيه reduz ، إذا رأيت بعض التعليقات النهائية من هذا العدد).

  • 15996: كان هذا أنا أدرك أن ما كنت أريده هو نظام السمات (قبل أن أفهم ما هي السمات) وبالتالي أدرك مدى فظاعة اقتراحي الأولي لأنه يشوه تمامًا التصميم المستهدف للمشاهد والعقد ويحول بالكامل شيء في نظام وراثي قائم على التركيب - شيء يشبه ما تفعله الوحدة في الواقع ، وهو أمر مثير للاشمئزاز (في Unity ، يمكنك استخدام getComponent من أي مكون ويقوم بجلب المكون الشقيق في كائن GameObject الذي يمتلكه. المكونات ، في الممارسة ، تمديد كائن GameObject ، ودفع تبعياتهم على بعضهم البعض).

  • 8502: MultiScript هي ببساطة أدوات للسماح للغات البرمجة النصية المختلفة أن ترث من بعضها البعض ، على غرار الطريقة التي يمكن أن ترث بها مخططات UE4 مباشرة من نصوص C ++ (والتي ، في Godot لن تكون ممكنة لأن المقارنة لها GDScript يمدد NativeScript. لا يدعم VisualScript حتى الوراثة في المقام الأول ، لذا فإن GDScript هي المقارنة الأكثر ملاءمة هنا).

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

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

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

الشيء الوحيد الذي يجب فعله لإصلاح المشكلة 1 هو أن يتحدث هؤلاء الأشخاص عن مشكلتهم وأن يقوم شخص آخر بإعادة توجيههم إلى المستندات أو موقع الأسئلة والأجوبة لمساعدتهم في العثور على حلهم. لقد أنشأت عددًا (# 23043) يقترح السماح للأشخاص بتصفح موقع الأسئلة والأجوبة واستخدامه مباشرةً من المحرر والذي من شأنه أن يساعد كثيرًا في حل المشكلة الثانية. ويرد وصف الأسباب في الرابط.

(تعديل: إذا كان هناك العديد من الطرق لحل مشكلة ، وكانت إحدى هذه الطرق أفضل بكثير من أي طريقة أخرى ، ولم يقم Godot بعد بتنفيذ الحل الأصلي الخاص به لها ، فسيكون هذا شيئًا يمكن اقتراحه كميزة جديدة هذه هي الطريقة التي تم بها إضافة عناصر SimplexNoise لأن الناس كانوا يكتبون خوارزميات SimplexNoise الخاصة بهم في GDScript / shader code ، وما إلى ذلك).


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


بالنسبة لأمثلة سير العمل في OP ...

  • نهج الوحدة ، العقد الفرعية:

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

  • نهج UE4 مع وحدات التحكم:

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

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

  • نهج Panda3D مع التحميل المسبق:

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

  • نهج البرنامج النصي WTF:

    لا أفهم حقًا كل المشكلات التي تواجهها هنا ، ربما لأنه ليس لدينا الكثير من السياق.

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

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

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

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

    إن تحريك كائن به العديد من الإشارات هو أمر محبط في أقل تقدير.

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

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

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


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

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

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

دروس البرنامج النصي تحل المشكلة الأخيرة.

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

ولكن إذا تم إعادة تقديم MultiScripts على الإطلاق ، فمن الممكن أن تزيفها بشكل معقول.
من المفهوم تمامًا إذا لم يقم Godot مطلقًا بتنفيذ MultiScripts. في الحقيقة ، كنت أشير للتو إلى أن الكثير من المستخدمين على GitHub بحثوا عن حلول سير عمل مماثلة كما حاولنا.

متى تريد أن يكون لديك سلوك محفز لأحد الوالدين في سليل؟ لماذا لا يُطلب من الوالد فقط الاتصال بالسليل وطريقته؟

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

هذه بالفعل علامة على أن تصميم المشروع ليس جيدًا.

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

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

"ما هي أفضل طريقة لتصميم نظام مثل X" والذي ... لا يمثل مشكلة في GitHub حقًا.

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

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

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

بشكل أساسي ، جربنا الكثير من التصميمات التي أوصى بها مجتمع Godot وبعضها من البرامج التعليمية

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

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

مرحبًا ، لدينا سؤال واحد فقط.

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

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

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

مع وجود 50.000 من أي شيء ، تجاوزت منذ فترة طويلة النقطة التي يكون فيها الاستعارة القائمة على الكائنات في Godot's SceneTree-Nodes مفيدة.

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

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

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

تجعل الوحدة بعضًا من هذا الأمر أسهل مع البنية التحتية الجديدة لـ ECS. لست متأكدا من UE4. في النهاية ، في هذا المستوى المتقدم ، سيتعين عليك القيام بمعظم الرفع الثقيل بنفسك (أو توظيف شخص متمرس للقيام بذلك نيابة عنك).

تعتبر UE4 و Unity فقط أسهل من حيث أنها أكبر سنًا وأكثر رسوخًا ، وبالتالي هناك عدد أكبر من الأشخاص الذين واجهوا مشاكل التوسع هذه ، مما يعني توفر المزيد من المعرفة (والموهبة القابلة للاستئجار) لحلها.

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

ما يحتاجه مطورو ألعاب Godot من مطوري المحرك هو إبطاء واضح لسير العمل الرسمي لصنع كائنات وأنظمة معقدة.

هذا يعتمد إلى حد كبير على لعبتك. لا توجد إجابة مباشرة لهذا في أي محرك كبير.
هل يجب عليك استخدام النهج القائم على المشهد في لعبة الكائنات في الوحدة؟ أو الهجين ECS؟ نظام ECS الجديد بالكامل؟ ما هو خط الأنابيب الذي تستخدمه؟
هل ستستخدم Blueprint أو C ++ في مشروع UE4 الخاص بك؟

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

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

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

لا يمكنني إلا أن أتفق مع Groud:

جميع الحلول لها مقايضات ، لذلك ليس هناك فائدة من إجراء سير عمل "رسمي".

mhilbrunner مجرد لعب الشياطين هو مناصرة هنا ولكن تصميم محرك أفضل (مثل ECS المناسب في معظم الحالات التي يكون فيها الأداء مهمًا) يجعل العديد من هذه الحدود أعلى بكثير مما قد تواجهه أي لعبة تقريبًا (هذه هي الطريقة الجديدة Rust Amethyst بناء محرك اللعبة للتركيز عليه على سبيل المثال).

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

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

يمكنني التحدث عن نفسي فقط ، وليس عن مطوري Godot الآخرين ، ولدي خبرة فقط مع UE و Unity و Godot ، لذلك لا أعرف شيئًا عن Rust Amethyst.

يمكن القيام بذلك ، ولكن بشكل مؤلم قليلاً لأن Godot يفتقر إلى بعض العناصر الأولية المفيدة لذلك.

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

لكن يجب أن نجمع هذه التعليقات بطريقة ما.

وأنا أوافق على أن هناك حدودًا مختلفة اعتمادًا على المحرك ، لكن مرة أخرى ، رأيت أشخاصًا يواجهون حواجز مماثلة في Unity و UE4 أيضًا. ربما لاحقًا ، ربما كانت تلك أعلى - لكن في النهاية ، ستحتاج إلى أن تكون قادرًا على حل المشكلات التي تواجهها في أي محرك. :)

MysteryGM هل تقول أنك لا تريد عقدًا تمثل المبنى والمياه ، أو أنك لا تريد نصوصًا مرفقة بها؟

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

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

سؤالي إذا صاغته على أنه تصميم OOP هو: كيف يصل نصان إلى واجهات بعضهما البعض؟

المشكلة هي أن GDscript لا يبدو أن لديها أي طريقة للوصول إلى البرامج النصية الأخرى مباشرة.
إذا أردت أن تحرق النار الخشب ، فإما أن يكون لدي خشب-> ممتد-> نار أو نار-> ممتد-> خشب.

MysteryGM : نصيحة واحدة: الإشارات. يمكن أن يكون للنار إشارة حرق (هدف) حيث يكون الهدف هو الخشب الخاص بك.

كيف يصل نصان إلى واجهات أخرى؟

$NodeWithScript.do_function() ؟

_ / أنا ما زلت ألعب دور محامي الشياطين ، لا تأخذ هذا كأي مقياس لما "يجب" فعله في جودو ، في أحسن الأحوال إنه أعراس بالدراجات_

يمكنني التحدث عن نفسي فقط ، وليس عن مطوري Godot الآخرين ، ولدي خبرة فقط مع UE و Unity و Godot ، لذلك لا أعرف شيئًا عن Rust Amethyst.

يستخدم UE نموذج Actor SceneTree. استخدمت Unity نموذج EC (على الرغم من أنهم قاموا مؤخرًا ببناء ECS وإهمال نموذج EC القديم ، إلا أنه لم يكتمل بعد ولكنه يبدو واعدًا). ويستخدم Godot نموذج SceneTree المكون. ECS هي مجموعة فرعية من نمط تدفق البيانات (على وجه التحديد هو تعميم له).

ملخص سريع عن ECS:

  • إن ' E ntity' هو مجرد معرف عدد صحيح ، على الرغم من أن معظم المحركات تحزم فهرس جيل وكيان في int32 واحد (8 بت توليد وفهرس 24 بت) أو int64 (32 بت لكل منهما ، int64 أكثر شيوعًا بشكل ملحوظ لأن ECS يسمح لك بالفعل لتوسيع نطاق هذه الكميات الكبيرة من الكيانات).

  • A ' C omponent' هي بنية POD في مصطلحات C / C ++ ، ويجب ألا تحتوي مطلقًا على وظائف. بشكل عام يجب أن يكون memcpy'able تافه.

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

    • مصفوفة قابلة لتغيير الحجم: غالبًا ما تُستخدم عندما يكون أحد المكونات شائعًا للغاية ، مثل الموضع.
    • مصفوفة متفرقة: غالبًا ما تستخدم عندما يميل أحد المكونات إلى الاستخدام في مجموعات من الكيانات في وقت واحد.
    • التعيين: ربما خريطة مجزأة أو خريطة متفرعة أو ما شابه بناءً على خصائص الأداء التي تتوقعها ، ولكنها تستخدم عمومًا للمكونات الأقل شيوعًا.
    • Bitsets: تستخدم فقط لتعريف ما إذا كان المكون موجودًا في كيان على الإطلاق ولكنه لا يخزن شيئًا ، والمعروف عمومًا باسم مكون العلم.
    • Octree أو رسم SceneGraph آخر (يمكن أن يتلاءم عارض Godot هنا): تخطيط شجرة المشهد الذي يتظاهر بأنه مكون.
    • إلخ ...: تعتمد العديد من الأنواع الأخرى على خصائص الوصول والأداء المتوقعة للمكون.
  • إن ' S ystem' هي في الأساس وظيفة تأخذ مجموعة متصلة من المكونات ، على الرغم من أن معظم المكتبات تحتوي على فئة أو وحدة نمطية غير افتراضية أو نحو ذلك ، فهي تعمل على مجموعة المكونات المرتبطة للقيام بشيء ما ، والتي يمكن أن تتضمن تغيير القيم في المكونات ، إضافة أو إزالة المكونات ، إلخ ... بعض الأمثلة:

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

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

إذا كنت ترغب في رؤية مكتبة C ++ ECS مكتوبة جيدًا ، فراجع https://github.com/skypjack/entt من جميع مكتبات C ++ ECS التي رأيتها ولم أقم بإنشائها ، يبدو أنها الأفضل بشكل عام (على الرغم من أن المواصفات لا تزال تتفوق عليها في اختباراتي البسيطة ، ولكن ليس كثيرًا ، وهو أمر مثير للإعجاب بالنظر إلى أن المواصفات تتفوق في الأداء على كل شيء قارنته بهوامش كبيرة).

الاستخدام العام لـ ECS هو أن لديك "كيان" (مجرد عدد صحيح ، لا توجد بيانات) ، ولديك مجموعة من الجداول التي تعين المكونات للكيانات ، والأنظمة لأداء العمل بالفعل. في GDScript pseudo-code ، أتخيل أنها واجهة برمجة تطبيقات بسيطة ، على الرغم من وجود القليل من الاصطلاح الغريب لـ "الدمج" في شجرة مشهد Godot نظرًا لأن شجرة المشهد لم يتم تصميمها مع وضع ذلك في الاعتبار.

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

# Create a new entity
var e = createEntity()

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

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

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

# Once at startup:

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

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

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

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

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

MysteryGM : نصيحة واحدة: الإشارات. يمكن أن يكون للنار إشارة حرق (هدف) حيث يكون الهدف هو الخشب الخاص بك.

آسف قصدت البرامج النصية وليس الأمثلة. أريد أن تتفاعل البرامج النصية دون الحاجة إلى عقدة في شجرة Godot.

آسف قصدت البرامج النصية وليس الأمثلة. أريد أن تتفاعل البرامج النصية دون الحاجة إلى عقدة في شجرة Godot.

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

أيضا ، هل جربت C #؟ إذا كنت تحاول إنشاء نظام معقد يحتوي على برامج نصية تتفاعل وتتحكم في العقد عبر شيء آخر غير إرفاق البرامج النصية بالعقد ، فمن المحتمل أن يكون لديك وقت أفضل مع C # مقارنة مع GDScript لمثل هذا النظام.

MysteryGM يعني الحصول على البرامج النصية للتفاعل مع بعضها البعض دون استخدام عقدة في المشهد أنه يجب عليك الحصول على نسخة محملة من مورد البرنامج النصي ، كحد أدنى. الطريقة الوحيدة للقيام بذلك في 3.0 هي إلى preload / load البرنامج النصي حسب مسار الملف. 3.1 يضيف ميزة "فئة البرنامج النصي" لـ GDScript و NativeScript حيث يتم تسجيل الأسماء المعطاة للنصوص بشكل عام. يقوم GDScript من يدويًا بتحويل هذه التسجيلات العمومية في المحرك إلى متغيرات عامة في اللغة.

بعد ذلك ، إذا كان لديك المورد Script ، يمكنك استدعاء الأساليب الثابتة في البرنامج النصي أو استدعاء .new() للحصول على ScriptInstance ثم استدعاء وظائف الأعضاء / متغيرات عضو الوصول. إذا كان Script يشتق كائنًا أو مرجعًا أو موردًا أو أي نوع آخر غير عقدة ، فكل ما تحتاج إليه هو إنشاء مثيل لـ Script / ScriptInstance المحتوى الثابت / غير الساكن. إذا كانت عقدة ، فإن الأمر نفسه ينطبق باستثناء الأشياء التي تتطلب الوصول إلى SceneTree (مثل get_node ) وفي هذه الحالة سيتعين عليك استخدام add_child لإضافته إلى SceneTree أولاً.

كل ما سبق ينطبق على أي لغة برمجة نصية مستخدمة مع Godot (على الرغم من أن التحميل المسبق هو عملية خاصة بلغات معينة أعتقد ...).

البرنامج النصي حسب مسار الملف. 3.1 يضيف ميزة "فئة البرنامج النصي" لـ GDScript

متى سيتم إصدار 3.1 رسميًا؟

MysteryGM عندما تكون النسبة المئوية لإكمال الإنجاز عالية بما فيه الكفاية / عندما يرى المطورون الأساسيون أن التقدم بعيد بما يكفي لدرجة أنهم يعتبرون البناء "مستقرًا".

معلم: https://github.com/godotengine/godot/milestone/7

للمقارنة ، 2.1 و 3.0 يقفان حاليًا عند 99 ٪. لست متأكدًا تمامًا مما إذا كانت هذه هي الحالة التي كانوا عليها عندما بدأوا البث المباشر.

في الأساس ، الإجابة هي "عندما تكون جاهزة".

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

إذا أردت أن تحرق النار الخشب ، فإما أن يكون لدي خشب-> ممتد-> نار أو نار-> ممتد-> خشب.

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

في C # يمكنني القول أن Wood يطبق IBurnable الذي يستخدمه Fire .

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

نظرًا لأنه لا يزال أمامنا 10 أيام لتحديد المحرك الذي سنستخدمه ، فقد حاولنا المزيد مع Godot.
كنا نبحث في مشاكل سير العمل وأعتقد أن مبرمجنا قال ذلك بشكل أفضل:

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

نص "النظام" الذي يتحكم في التفاعلات بين الحرائق والأخشاب. هذا العرض يركز على المكونات

نعم هذا ما نريده ، كيف نفعل ذلك في GDscript؟

في C # يمكنني القول أن الخشب يستخدم IBurnable الذي يستخدمه Fire.

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

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

في C # ، سنعلن عن Burning كفئة خاصة به. العامة حرق الطبقة وتم حل مشكلتنا.
في لغة ++ C ، سنقوم بتضمين الحرق وحل المشكلة.

نعم هذا ما نريده ، كيف نفعل ذلك في GDscript؟

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

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

لجعل الأمور أسرع ، قد يقوم المرء فقط بإجراء فحوصات للكائنات التي اصطدمت بالفعل (على سبيل المثال ، عن طريق إرسال signal من كائن إلى النظام عند حدوث التصادم).

بعض الأمثلة الخاصة بـ GDScript للإحالة المرجعية إلى البرنامج النصي (للإصدار 3.0):

هنا يعمل Enemy كنوع / واجهة ، يمكن للمرء التحقق منها باستخدام عامل التشغيل is :

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

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

هنا runnerGame يشير إلى مشهد _autoload_ (المعروف أيضًا باسم مفرد) مع مسار / جذر / عداء:

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

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

هنا نقوم بتوصيل signal "تم الضغط عليه" من الزر بالمعامل (والذي قد يكون في كائن ونص مختلف ، نحن نستخدم self للإشارة إلى نفس الزر):

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

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

انظر أيضًا المستندات هنا ، هناك بعض الميزات الإضافية المتاحة: http://docs.godotengine.org/en/3.0/getting_started/scripting/gdscript/gdscript_basics.html#inheritance

انظر أيضًا المستندات هنا ، هناك بعض الميزات الأخرى المتاحة:

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

هنا مثال:

الخطوة أ.
MeshInstance + HomingScript = HomingMissile .
لكن الآن إذا أردت لغم أرضي صاروخ موجه لدي مشكلة.
(MeshInstance + ProximityScript) = لغم أرضي.
(MeshInstance + ProximityScript) + HomingScript = خطأ في أكثر من برنامج نصي
(MeshInstance + ProximityScript) + (childNode + HomingScript) = فشل نظرًا لتحرك العقدة غير المرئية فقط.
(MeshInstance + ProximityScript) + (childNode + ExtendedHomingScript) = نجاح لأننا نوسع الآن فئة Homing بحيث يمكن أن تمتلك عقدًا من العقدة الفرعية. نحصل على HomingLandmine .

ماعدا الآن يمكن القول أن كلا من صاروخ موجه والألغام الأرضية يجب أن يمتد من صاروخ صاروخ موجه.

الخطوة ب.
HomingMissile [من Homing]
HomingLandmine [من Homing] [+ ProximityScript] يتم الآن نسخ النص ولصقه في اللغم الأرضي.

في وقت لاحق في الإنتاج ، يحدث نفس الشيء مع البرامج النصية الأخرى التي لدينا.
ستيب سي.
لغم أرضي [من القرب]
ProximityAlarm [من Proximity] [+ AlarmScript]
// HomingLandmine [من Proximity] [+ HommingScript] // الآن يمكن أيضًا أن يصلح لغمنا الأرضي هنا.

لذلك علينا الاستمرار في المرور عبر StepA للعثور على الميراث المناسب لـ StepB. يستمر في تكرار هذا النمط بما يتجاوز StepF وما إلى ذلك.

لقد وجدنا طريقة لإطالة StepA ، نتجنب فقط إضافة برنامج نصي إلى العقدة العليا ، ونجعل ذلك دائمًا عقدة مكانية أو عقدة أولية.
(مكاني + MeshInstance + Proximity) + HomingScript = HomingLandmine
باستثناء أن هذه هي نفس المشكلة ولكن مع ParentSpatial أكثر تكلفة ؛ بدلا من childNode.

أعتذر عن المدة التي يستغرقها هذا.

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

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

ما عليك أن تفهمه هو أن Godot لا يعمل بشكل مختلف في هذه الحالة. في حين أن حل go-to هو إنشاء عقدة فرعية بالنص البرمجي الخاص بها (لـ "Burning" في هذه الحالة) ، يمكنك فقط تعريف Burning كفئة خاصة به وتضمينه / استخدامه عبر وظائف ثابتة (أو مثيله ثم استخدام الخصائص / الطرق)

  • سي ++

    • حرق فئة {}؛

    • تشمل "burn.h" ؛

    • حرق :: تطبيق (خشب ، نار) ؛

    • Burning * b = Burning :: get_singleton () ؛ ب-> تطبيق (خشب ، نار) ؛

  • C # (تم تعديله لتغييرات التصميم)

    • حرق الطبقة العامة {}

    • باستخدام Game.Burning.

    • Burning.apply (خشب ، نار) ؛

    • حرق ب = حرق. ب. تطبيق (خشب ، نار) ؛

  • GDScript (3.1)

    • يمتد المورد # burn.gd

    • const Burning = التحميل المسبق ("res: //burning.gd")



      • في الإصدار 3.0 ، يمكن استخدام برنامج نصي شائع لتحميل الثوابت لجميع المحفزات شائعة الاستخدام.


        يمتد المرجع


        const Burning = التحميل المسبق ("res: //burning.gd")


        ترطيب const = تحميل مسبق ("الدقة: //wetting.gd")


        يمتد المرجع


        const Stimuli = التحميل المسبق ("res: //stimuli.gd")


        # استخدم المنبهات ، الحرق أو المنبهات ، الترطيب


      • في الإصدار 3.1 ، يمكن فقط استخدام فئات البرنامج النصي. الاحتراق والترطيب لا يتطلبان "شمولية" لأنهما عالميان.


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



    • Burning.apply (خشب ، نار)

    • var b = Burning.new ()

      ب. تطبيق (خشب ، نار)

بالنسبة لمقاربة Unity / ScriptableObject ، يمكن للمرء استخدام البرامج النصية لمورد Godot للغرض نفسه.

  • يمكن تكوين الإعدادات في المفتش.
  • يمكن حفظ "إنشاءات" الميزة في ملف بحيث يمكن تبديل إعدادات معينة بسهولة حسب الحاجة ، حتى في وقت التشغيل.
  • يقوم المحرر تلقائيًا بإنشاء مثيل للمصدر على العقدة باستخدام إعلان المشهد ، لذلك لا يلزم إجراء تحديث يدوي. يمكن أن تعمل مجموعة من هذه الموارد بشكل جيد بشكل معقول ، على الرغم من تعطل نظام تلميح نوع المصفوفة في 3.1 (حتى نأمل 3.2) ، يجب عليك كتابة EditorInspectorPlugin لإنشاء محتوى المفتش بشكل صحيح (وهو في الواقع ما أعمل عليه قيد التشغيل في قائمة FileSystemItemList الخاصة بمستودع godot-next (تحذير ، إنها عملية ويب مبكرة) ، لاستخدامها في مستودع Godot-Builder الخاص بي لمصفوفات الملفات / الأدلة.

نص "النظام" الذي يتحكم في التفاعلات بين الحرائق والأخشاب. هذا العرض يركز على المكونات

نعم هذا ما نريده ، كيف نفعل ذلك في GDscript؟

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

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

راجع للشغل ، إذا كنت تريد الدردشة في الوقت الفعلي حول هذا الموضوع ، فلا تتردد في مراسلتي على Reddit / Discord / Twitter حيث أستخدم نفس اسم المستخدم.

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

MeshInstance + HomingScript = _HomingMissile_.
لكن الآن إذا أردت لغم أرضي صاروخ موجه لدي مشكلة.
(MeshInstance + ProximityScript) = _ Landmine_.
(MeshInstance + ProximityScript) + HomingScript = خطأ في أكثر من برنامج نصي
(MeshInstance + ProximityScript) + (childNode + HomingScript) = فشل نظرًا لتحرك العقدة غير المرئية فقط.
(MeshInstance + ProximityScript) + (childNode + ExtendedHomingScript) = نجاح لأننا نوسع الآن فئة Homing بحيث يمكن أن تمتلك عقدًا من العقدة الفرعية. نحصل على _HomingLandmine_.

ماعدا الآن يمكن القول أن كلا من صاروخ موجه والألغام الأرضية يجب أن يمتد من صاروخ صاروخ موجه.

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

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

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

بعض التصحيحات:

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

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

neikeq شكرا. أنا بعيد جدًا عن الممارسة مع C # ، لول.

أما بالنسبة لنهج "البرامج النصية العالمية" ، فأنا ضد ذلك بشدة. سيشجع المطورين على برمجة لعبتهم بطرق سيئة. السؤال الشائع عن مطوري ألعاب C ++ و Java السابقة ، عندما يحاولون Unity / Unreal / Godot / إلخ ، هو "أين حلقة اللعبة الرئيسية التي يمكنني كتابة الكود فيها؟". ستسمح إضافة مثل هذا النظام لهؤلاء المطورين بالقيام بذلك ، لذلك قد ينتهي بهم الأمر بكتابة تعليمات برمجية في نصوص برمجية عالمية تشير إلى الكائنات التي يريدون تعديلها بدلاً من مجرد استخدام برنامج نصي على كائن.

ربما بدلاً من ذلك ، يمكننا تحسين أداء العقدة المجردة Node بحيث لا تقدم حملًا "لمكونات" الكائن التي تحتوي على نصوص برمجية بحتة. أو ربما عقدة منفصلة بسيطة من نوع "Only-Hold-scripts".

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

أما بالنسبة لنهج "البرامج النصية العالمية" ، فأنا ضد ذلك بشدة. سيشجع المطورين على برمجة لعبتهم بطرق سيئة. السؤال الشائع عن مطوري ألعاب C ++ و Java السابقة ، عندما يحاولون Unity / Unreal / Godot / إلخ ، هو "أين حلقة اللعبة الرئيسية التي يمكنني كتابة الكود فيها؟".

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

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

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

ربما بدلاً من ذلك يمكننا تحسين أداء العقدة المجردة بحيث لا تقدم حمل "مكونات" الكائن التي تحتوي على نصوص برمجية بحتة.

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

أو ربما عقدة منفصلة بسيطة من نوع "Only-Hold-scripts".

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

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

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

يمتد المورد # burn.gd

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

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

FileSystemItemList (تحذير ، إنه عمل قيد التقدم مبكرًا)

بالتأكيد سوف تضطر إلى إلقاء نظرة على هذا.

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

لا أعتقد أن أيًا منا كان يعرف أنه يمكننا إنشاء موارد مخصصة.

نعم! لقد أضفت مؤخرًا قسمًا إلى المستندات يوضح العملية. :-د

يمكنك تمديد أي نوع محرك باستخدام برنامج نصي ، بما في ذلك الكائن والمرجع والمورد وبالطبع العقدة (أو أي من اشتقاقات هذه الفئات). الأشياء الوحيدة التي لا يمكن تمديدها هي المحرك والمحرر الفرديين (مثل OS أو Engine أو EditorFileSystem).

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

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

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

بالنظر إلى أن التحميل المسبق للمورد يحل مشكلة تضمين البرامج النصية. يمكن أيضًا استخدامه كبديل لكل من Unity's MultiScript و ScriptableObject عن طريق تصدير متغير مورد في GDscript.
بالإضافة إلى حقيقة أنه تم تحديث المستندات لشرح الموارد بمزيد من التفصيل.
ناهيك عن أن Godot 3.1 سيحتوي أيضًا على فئات نصية من المفترض أن تسمح بمزيد من سير العمل.

أعتقد أنه قد تم حل الهدف الأصلي من هذه المشكلة ، ويمكن الآن إغلاق هذه المشكلة؟

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

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

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

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

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

pgruenbacherMysteryGM على الرغم من أنني لست على نفس المنوال من تجربة ما قبل / بعد مع Godot ، فقد دفعني هذا العدد وبعض الأسئلة المتكررة ذات الصلة لبدء العمل على مقال عن أفضل ممارسات تصميم المشهد / السيناريو لـ godot-docs. لديّ فرع على مفترقتي ، لكن من المبكر جدًا إجراء عمليات صراف آلي في العمل قيد التنفيذ.

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

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

يوم الأربعاء ، 14 نوفمبر 2018 ، Aaron-Fleisher [email protected]
كتب:

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

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

@ آرون فليشر

... يجعلني أخمن مرة أخرى إذا اخترنا المحرك المناسب

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

أنت من يعرف مشاكلك ، وأنت الذي سيتعين عليك القيام بهذا العمل. تجنب أن تصاب بالشلل بسبب ما كان من شأنه أن يشتري لك إنتاجية أخرى بنسبة 10٪ -20٪. احفظه للمباراة القادمة. أو لا تفعل ذلك ، نظرًا لأنك استثمرت الكثير بالفعل في تعلم الأدوات التي تعرفها بالفعل. اختيارك :)

لا أعرف ، أشعر نوعًا ما بأن مطوري Godot لا يعرفون ماذا يفعلون.

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

لدي شعور بأن كلمة "مستقر" هنا تعني "ستفشل بشكل موثوق في كل مرة."

تحدث عن الانطباع الأول المخيب للآمال.

dejayc هذا غريب. لم أواجه مطلقًا مشكلات مع مدير المشروع بنفسي (مع 3.0.6 مستقر أو حتى الفرع الرئيسي) على نظام التشغيل Windows 10 أو جهاز Linux Mint الخاص بي. أود أن أوصيك بإنشاء عدد جديد حول مشاكلك هنا (حيث أن هذه ليست المشكلة الصحيحة لمثل هذا الموضوع) ، وآمل أن يتمكن أحدهم من تقديم مساعدة أفضل.

تضمين التغريدة
إذا تبرعنا جميعًا لـ Patreon ، فسيكون مشروع Godot قادرًا على توظيف رجل قابلية الاستخدام بدوام كامل .

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

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

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

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

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