كيف تصبح خبيرًا في أتمتة مهام محرك Unreal Engine
أتمتة سير العمل بـ Blueprints و C++ و Python في Unreal Engine
في كل وظيفة، توجد مهام وعمليات متكررة يمكن أتمتتها. هذه المهام قد تستغرق جزءًا كبيرًا من وقتك الثمين. يمكن لشخص لديه معرفة أساسية بالبرمجة النصية (scripting) أن يبني سكريبتًا يقلل من وقت تنفيذ هذه المهام إلى الحد الأدنى. على المدى الطويل، يتراكم هذا التوفير في الوقت ليتحول إلى ساعات إضافية يمكن استغلالها في عمل أكثر إنتاجية.
لذلك، يعد تعلم كيفية أتمتة الأشياء مهارة لا تقدر بثمن، وهي مهارة يمكن اكتسابها في قطاعات محددة ثم تطبيقها على قطاعات أخرى أكثر عمومية. خاصة في ظل الظروف الحالية الصعبة، يعد تعلم مهارة جديدة سيكون لها تأثير كبير على قابليتك للتوظيف أمرًا حيويًا. في هذا المقال، نهدف إلى تسليط الضوء على أهمية الأتمتة عند العمل ببرمجيات الوقت الفعلي مثل محرك Unreal Engine.
لماذا يحظى محرك Unreal Engine باهتمام كبير؟
يُعد محرك Unreal Engine من شركة Epic Games أحد أشهر تطبيقات الألعاب والرسوم ثلاثية الأبعاد في الوقت الفعلي المتوفرة حاليًا. يُستخدم هذا المحرك لإنشاء محتوى ترفيهي مثل الألعاب والإعدادات التفاعلية. تتطلب تخصصات مثل الواقع الافتراضي (VR) والواقع المعزز (AR) استخدام عمليات معقدة، والتي، مثل أي خط أنابيب (pipeline) آخر، يمكن تحسينها من خلال الأتمتة. بالإضافة إلى ذلك، يشهد سوق الألعاب والرسوم ثلاثية الأبعاد في الوقت الفعلي نموًا مستمرًا، مما يزيد من الطلب على المواهب.
وفقًا لدراسة أجرتها شركة Burning Glass Technologies، وهي شركة لتحليلات سوق العمل، ارتفعت متوسط رواتب مطوري Unreal Engine بنسبة 22% العام الماضي، بينما ارتفعت أجور الفنانين بنسبة 51%.

المصدر: Unreal Engine Blog
لماذا نستخدم Blueprints في سير العمل وحتى برمجة الألعاب؟
بالإضافة إلى واجهة البرمجة العامة C++، يوفر محرك Unreal Engine نظام برمجة رسوميًا يُعرف باسم Blueprints. تكشف هذه المخططات عن الوظائف الكاملة لكود C++، مما يعني أنه يمكن برمجة كل شيء، بما في ذلك الميزات داخل اللعبة، دون عوائق كبيرة في الأداء. تسمح لنا الواجهة الرسومية بتركيب الكيانات بسرعة في تدفق لإنشاء وظائف معينة. بالنظر إلى مثال يقوم بتعيين مادة (material) لممثل شبكي ثابت (static mesh actor)، يمكننا أن نرى أن Blueprint سهل القراءة بشكل واضح.

سكريبت Blueprints لتعيين مادة لممثل شبكي ثابت.
لماذا نستخدم C++ في سير العمل وبرمجة الألعاب؟
يُعد C++ هو النهج “الأصلي” للبرمجة في محرك Unreal Engine. يُستخدم لإنشاء منطق اللعبة (in-game logic)، وتبسيط إنشاء المستويات وسير العمل، وتحسين خط أنابيب التطوير. إنه أكثر تعقيدًا وصعوبة في التعلم من Blueprints، ولكنه يمكن أن يضيف دفعة إضافية في وقت التشغيل والأداء. ميزته في الأداء تجعله لغة الاختيار للعمليات الأساسية والمنخفضة المستوى مثل العرض (rendering) والفيزياء في تطوير الألعاب. بالنسبة للمطورين الذين يتقنون بالفعل C++، فإنه إضافة مريحة أن يكونوا قادرين على أتمتة العمليات دون تعلم لغة إضافية مباشرة.
لماذا نستخدم Python لتحسين سير العمل؟
مقارنة بـ Blueprints أو C++، تُعد Python واحدة من اللغات القياسية الفعلية المستخدمة لأتمتة المهام. إنها سهلة التعلم، ومفهومة، ومتعددة الاستخدامات للغاية حيث يمكن تشغيلها على أي منصة تقريبًا دون جهد إضافي. تدرج Epic Games لغة Python كواحدة من المهارات المطلوبة، على سبيل المثال، لمهندسي خطوط بيانات (Data Pipeliners) في دليلهم الميداني للمبدعين للوظائف الناشئة في 3D التفاعلي.

المصدر: Epic Games Creator’s Field Guide
يدعم محرك Unreal Engine البرمجة النصية الكاملة بلغة Python. لسوء الحظ، إنها ليست مناسبة للبرمجة النصية في الوقت الفعلي أو داخل اللعبة، ولكن يمكن استخدامها فقط لبرمجة محرر Unreal Editor. ومع ذلك، فإن بساطة Python تجعلها خيارًا رائعًا للنماذج الأولية السريعة لأتمتة خطوط الأنابيب (pipeline automation). تحاول Epic نفسها الترويج لاستخدام Python من خلال التوثيقات (documentation)، ووثائق API، وحتى ندوة عبر الويب مسجلة حول البرمجة النصية بـ Python لمحرك Unreal Engine.
كتابة سكريبت خاص بنا لتنظيف المشروع تلقائيًا باستخدام Python
يمكن للمشاريع الكبيرة أن تصبح فوضوية بسرعة. وجود سكريبت في متناول اليد يمكنه إجراء عملية تنظيف من خلال فحص جميع الأصول (assets) المحددة لدينا ونقلها تلقائيًا إلى مجلدات مناسبة يساعدنا بشكل كبير على تحسين سير عملنا. يوضح الرسم التخطيطي أدناه الفكرة وراء السكريبت.

حتى الآن، الإصدار الافتراضي من Python المحدد في Unreal هو Python 2.7. إذا كنت ترغب في استخدام Python 3، يمكنك اتباع العملية الموضحة هنا للتبديل إلى Python 3.
للبدء، نحتاج أولاً إلى استيراد مكتبة unreal إلى نطاق عملنا. بمجرد الانتهاء من ذلك، يمكننا إنشاء مثيلات فئة (class instances) من الفئات الأولية. في الوقت الحالي، نحتاج فقط إلى الفئة EditorUtilityLibrary التي تمكننا من الحصول على قائمة بجميع الأصول المحددة. يمكننا الحصول على عدد الأصول المحددة باستخدام دالة len() في Python واستخدام دالة التسجيل unreal.log() للحصول على مخرجات في سجل التصحيح (Debug Log) في محرك Unreal Engine.
import unreal # create unreal class instances editor_util = unreal.EditorUtilityLibrary() # get the selected assets selected_assets = editor_util.get_selected_assets() num_assets = len(selected_assets) unreal.log(num_assets)
سيقوم مقتطف الكود أعلاه بطباعة رقم واحد إلى سجل Debug Log. لكل من الأصول المحددة، نريد الآن الحصول على بعض المعلومات مثل اسم الأصل وفئته. يحتوي كائن unreal.ObjectBase على العديد من الدوال المساعدة للحصول على الاسم والفئة والسمات الأخرى. سنستخدم الدالتين get_fname() و get_class().
for assets in selected_assets: # get the class instance and the clear text name asset_name = asset.get_fname() asset_class = asset.get_class() unreal.log( "{} - {}" .format(asset_name, asset_class))
ومع ذلك، سيعطينا هذا تعريف الفئة فقط وليس الاسم النصي الواضح للفئة نفسها، وهو ما نريد استخدامه لإنشاء المجلدات. للحصول على اسم العرض (display name) بدلاً من تعريف الفئة، نحتاج إلى إنشاء مثيل من الفئة SystemLibrary. تأخذ دالة get_class_display_name() الخاصة بها تعريف الفئة وتعيد اسم الفئة كسلسلة نصية (String).
# create unreal class instances editor_util = unreal.EditorUtilityLibrary() system_lib = unreal.SystemLibrary() ... for assets in selected_assets: # get the class instance and the clear text name asset_name = asset.get_fname() asset_class = asset.get_class() class_name = system_lib.get_class_display_name(asset_class) unreal.log( "Name: {} - Class: {}" .format(asset_name, class_name))
الآن يمكننا أن نرى شيئًا مثل "Name: NewMaterial - Class: Material" مطبوعًا في سجلنا. هذا هو بالضبط نوع المعلومات التي احتجناها. الخطوة الأخيرة هي "إعادة تسمية" أصولنا إلى موقع معين. على سبيل المثال، سيتم إعادة تسمية كل مادة (Material) إلى "/Material/<Name of Material Asset>" مما سيؤدي إلى نقلها إلى المجلدات المناسبة. لإعادة تسمية الأصول، نحتاج إلى فئة إضافية. دالة rename_loaded_asset() هي جزء من الفئة EditorAssetLibrary، لذلك نحتاج إلى إنشاء مثيل من هذه الفئة أولاً. بالإضافة إلى ذلك، يجب علينا إنشاء موقع جديد سيتم نقل الأصل إليه. للحفاظ على هذا أكثر استقلالية عن المنصة، سنستخدم وحدة os ودالة path.join() الخاصة بها. بمجرد إنشاء المتغير new_path، يمكننا استخدامه في استدعاء الدالة rename_loaded_asset() لنقل أصلنا الحالي.
import os import unreal # create unreal class instances editor_util = unreal.EditorUtilityLibrary() system_lib = unreal.SystemLibrary() editor_asset_lib = unreal.EditorAssetLibrary() ... for assets in selected_assets: # get the class instance and the clear text name asset_name = asset.get_fname() asset_class = asset.get_class() class_name = system_lib.get_class_display_name(asset_class) # assemble new path and relocate asset new_path = os.path.join( "/Game" , class_name, asset_name) editor_asset_lib.rename_loaded_asset(asset_name, new_path) unreal.log( "Moved {} to {}" .format(asset_name, new_path))
عند تنفيذ هذا السكريبت في محرك Unreal Engine، سيزودك السجل برسالة مثل: "Moved NewMaterial to /Game/Material/NewMaterial". بمراقبة مشروعنا، يمكننا الآن رؤية أن جميع الأصول المحددة قد تم تنظيفها ووضعها في مجلدات سميت وفقًا لفئاتها. كما ترى، فإن إنشاء سكريبت أساسي بسيط للغاية. بالطبع، نحتاج إلى الاهتمام بمعالجة الأخطاء، والتسجيل المناسب، وواجهة مستخدم سهلة الاستخدام لأدوات أكثر تعقيدًا، ولكن حتى السكريبتات البسيطة يمكن أن توفر الكثير من الوقت.
هل تعود الأتمتة بالفائدة المرجوة؟
لإظهار مدى حجم الطلب على الأتمتة في هذا القطاع، إليك لقطة شاشة للمبيعات الشهرية لأداة تحتوي على وظائف مشابهة للسكريبت الذي أنشأناه في هذا المقال.

بالطبع، من الضروري فهم احتياجات المستخدمين والفنانين العاملين في Unreal Engine لمعرفة المهام المناسبة للأتمتة.
تعلم كيفية أتمتة وتحسين سير العمل بالبرمجة النصية على Udemy
للمساعدة في سد الفجوة في موارد البرمجة النصية لـ Unreal، قمنا بإنشاء دورة تدريبية شاملة عند الطلب على Udemy لتعلم البرمجة النصية لمحرر Unreal Engine من الصفر. يمكنك استخدام الرمز الترويجي AUTOMATEUNREAL20. يمكنك الحصول على الدورة الآن مقابل 10 دولارات فقط. هذا أقل من سعر ثلاثة أكواب Frappuccinos من Starbucks!

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