عام C# GOAP (تخطيط الإجراء الموجهة نحو الأهداف) مكتبة مع أمثلة Unity3D وفصول المساعدين.
هذه المكتبة عامة للغاية ، إذا لم تقم بتضمين مجلد الوحدة الذي يمكنك استخدامه في أي محرك لعبة.
ابدأ عن طريق التحقق من مثال Unity FSM هنا.
يستخدم هذا المثال مكتبة RegOap في الوحدة مع FSM البسيطة (آلة الحالة المحدودة) للتعامل مع السلوكيات الكلية (في معظم الألعاب يجب أن تكون ثلاث حالات FSM كافية: الخمول ، goto ، تحريك).
لاستخدامه إنشاء مشروع وحدة جديد ، افتح القشرة ، انتقل إلى دليل الأصول واستنساخ المستودع بأكمله هناك:
git clone https://github.com/luxkun/ReGoap.git(في Windows ، يمكنك القيام الشيء نفسه مع سطر الأوامر أو أي عميل GIT ، يمكنك أيضًا النقر على "استنساخ أو تنزيل" ثم "تنزيل Zip")
كما يمكنك فقط تنزيل حزمة الوحدة في الإصدار الأخير ، والتي ربما لن يكون لها أحدث التغييرات ، هنا أو على متجر Unity Asset.
(إذا كنت ترغب فقط في استخدام المكتبة وتريد مثالًا موضحًا ، فقد تخطي كيفية استخدام RegOap )
قبل شرح كيفية استخدام هذه المكتبة في لعبتك ، اسمحوا لي أن أشرح كيف يعمل نظام GOAP ، بدءًا من اقتباس من Jeff Orkin
Goal-Oriented Action Planning (aka GOAP, rhymes with soap) refers to a simplfied STRIPS-like planning architecture specifically designed for real-time control of autonomous character behavior in games.
كل ما تفعله في الأساس هو العثور على خطة (قائمة الإجراءات) التي من شأنها تحقيق أهداف الهدف المختار.
المفهوم الرئيسي الذي تحتاج إلى فهمه هو: الحالات والعمل والهدف والذاكرة وأجهزة الاستشعار
هو تعريف للعالم ، في هذه المكتبة يتم التعامل معهم كقاموس للسلسلة إلى كائن (القاموس <سلسلة ، كائن>).
تحقق من فئة regoapstate في هذا الملف: https://github.com/luxkun/regoap/blob/master/regoap/core/regoapstate.cs
مثال: "isat": "العدو" ، "Iswarned": True ، "Hasweapon": True
يمكن تعريفها على أنها قائمة بالشروط المسبقة والتأثيرات ، فهذه هي الإجراءات التي يمكن أن يطلق عليها الوكيل (AI Pawn ، وكيلًا من الآن فصاعدًا).
الشروط المسبقة هي الشرط الذي يتطلب الإجراء أن يتم تشغيله ، الموصوف كدولة ، والآثار ، كما يوحي الاسم ، هي آثار الإجراء ، كما هو موصوف على أنها حالة.
أمثلة:
هام : الشروط المسبقة الخاطئة غير مدعومة مهمة : لا يتم كتابة تأثيرات الإجراء في الذاكرة عند الانتهاء من الإجراء ، وهذا سلوك مطلوب لأنه في معظم الألعاب سترغب في تعيين هذه المتغيرات من الذاكرة أو من المستشعرات . إذا كنت تريد أن تتمكن من تجاوز الخروج في regoapaction الخاص بك وتعيين التأثيرات على الذاكرة ، على سبيل المثال التالي.
يمكن تعريفها على أنها قائمة بالمتطلبات ، الموصوفة كدولة ، وهذا هو ما يجب على الوكيل فعله.
أمثلة:
هي ذكرى الوكيل ، كل ما يعرفه الوكيل ويشعر أنه ينبغي إدراج هنا. يمكن أن تحتوي الذاكرة أيضًا على العديد من أجهزة الاستشعار ، في هذه المكتبة ، وهي مساعد للذاكرة. في الأساس ، تتمثل مهمة الذاكرة في إنشاء حالة "العالم" والحفاظ عليها.
هو مساعد الذاكرة ، يجب أن يتعامل مع نطاق معين.
مثال:
الآن يجب أن تفهم ما هي مكتبة GOAP وما يجب أن تستخدمه ، إذا كان لا يزال لديك أسئلة أو تريد معرفة المزيد عن هذا الحقل ، أنصحك بقراءة أوراق Jeff Orkin هنا: http://alumni.media.mit. EDU/~ Jorkin/
git clone https://github.com/luxkun/ReGoap.gitما هو أكثر؟ لا شيء حقًا ، ستتعامل المكتبة مع كل التخطيط ، واختيار الإجراءات لإكمال الهدف وتشغيل الأول حتى يتم ذلك ، ثم الثانية وما إلى ذلك ، كل ما عليك فعله هو تنفيذ أفعالك وأهدافك.
في الفقرات التالية ، سأشرح كيفية إنشاء الفصول الدراسية الخاصة بك (ولكن بالنسبة لمعظم السلوكيات ، كل ما تحتاج إلى تنفيذه هو goapaction و goapgoal).
تحقق من الإجراءات الواردة في هذا المثال: https://github.com/luxkun/regoap/tree/master/regoap/unity/fsmexample/actions
تحقق من تطبيق RegOapaction ، لمعرفة الوظائف التي يمكنك تجاوزها: https://github.com/luxkun/regoap/blob/master/regoap/unity/regoapaction.cs
يجب عليك تنفيذ regoapaction الخاص بك عن طريق تنفيذ واجهة IregoApaction أو ورث RegOapaction. اختر بحكمة الأنواع العامة ، يجب أن تكون هي نفسها في جميع فئات الوكيل. عادة ما يكون السلسلة ، الكائن هو الأكثر عامة ، وأيضًا int/enum ، يكون الكائن عامًا عامًا ولكنه أخف.
للتنفيذ البسيط ، كل ما عليك فعله هو:
public class MyGoapAction : ReGoapAction < string , object >
{
protected override void Awake ( )
{
base . Awake ( ) ;
preconditions . Set ( " myPrecondition " , myValue ) ;
effects . Set ( " myEffects " , myValue ) ;
}
public override void Run ( IReGoapAction < string , object > previous , IReGoapAction < string , object > next , ReGoapState < string , object > settings , ReGoapState < string , object > goalState , Action < IReGoapAction < string , object > > done , Action < IReGoapAction < string , object > > fail )
{
base . Run ( previous , next , goalState , done , fail ) ;
// do your own game logic here
// when done, in this function or outside this function, call the done or fail callback, automatically saved to doneCallback and failCallback by ReGoapAction
doneCallback ( this ) ; // this will tell the ReGoapAgent that the action is succerfully done and go ahead in the action plan
// if the action has failed then run failCallback(this), the ReGoapAgent will automatically invalidate the whole plan and ask the ReGoapPlannerManager to create a new plan
}
}كما هو مكتوب قبل أن لا يتم ، بشكل افتراضي ، اكتب التأثيرات على الذاكرة ، ولكن يجب أن تتحقق الذاكرة ما إذا كانت التأثيرات قد تم بشكل فعال ، إذا كنت ترغب في تعيين التأثيرات في نهاية الإجراء لأي سبب من الأسباب هذا الرمز إلى تطبيق RegOapaction الخاص بك:
public override void Exit ( IReGoapAction < string , object > next )
{
base . Exit ( next ) ;
var worldState = agent . GetMemory ( ) . GetWorldState ( ) ;
foreach ( var pair in effects ) {
worldState . Set ( pair . Key , pair . Value ) ;
}
}يمكنك أيضًا أن يكون لديك شروط مسبقة وتأثيرات يتم تغييرها ديناميكيًا بناءً على الشروط/التأثيرات المسبقة للإجراء التالي ، على سبيل المثال ، هذا كيف يمكنك التعامل مع إجراء GOTO في وكيلك.
تحقق من fsmexample لمعرفة كيفية القيام بذلك: https://github.com/luxkun/regoap/blob/master/regoap/unity/fsmexample/actions/genericgotoaction.cs
هذا أقل صعوبة ، فإن معظم الهدف لن يتجاوز سوى وظيفة الاستيقاظ لإضافة حالة الهدف الخاصة بك (الأهداف).
على أي حال ، تحقق من RegOapgoal ، مثل كل ما عليك تنفيذ الفصل الخاص بك من نقطة الصفر من خلال تطبيق واجهة IregoApgoal أو ورث RegOapgoal: https://github.com/luxkun/regoap/blob/master/regoap/unity/regoapgoal.cs
تحقق أيضًا من الأهداف في هذا المثال: https://github.com/luxkun/regoap/tree/master/regoap/unity/fsmexample/goals
public class MyGoapGoal : ReGoapGoal < string , object >
{
protected override void Awake ( )
{
base . Awake ( ) ;
goal . Set ( " myRequirement " , myValue ) ;
}
}ملاحظة : تأكد من استخدام REGOAPGOARVANCED إذا كنت ترغب في تحذير الوكيل تلقائيًا من أن الهدف/غير متوفر.
تحقق من Goapsensor الفئة الأساسية هنا: https://github.com/luxkun/regoap/blob/master/regoap/unity/goapsensor.cs
تحقق من الأمثلة هنا: https://github.com/luxkun/regoap/tree/master/regoap/unity/fsmexample/sensors
كما هو الحال دائمًا ، يجب عليك تنفيذ الفصل الخاص بك عن طريق وراثة REGOAPSENSOR أو تنفيذ واجهة IREGOAPSENSOR.
public class MySensor : ReGoapSensor < string , object >
{
void FixedUpdate ( )
{
var worldState = memory . GetWorldState ( ) ;
worldState . Set ( " mySensorValue " , myValue ) ; // like always myValue can be anything... it's a GoapState :)
}
}ملاحظة : تأكد من استخدام REGOAPMemoryadvanced عند العمل مع أجهزة الاستشعار ، نظرًا لأن الفئة الأساسية لا تتحقق من المستشعرات وتحديثها.
لتصحيح الوكيل الخاص بك ، بالطبع ، يمكنك التصحيح بمفردك ، مع المحرر المفضل لديك.
لكن Regoap لديها مصحح أخطاء مفيد للغاية للوكلاء في الوحدة (https://github.com/luxkun/regoap/blob/master/regoap/unity/editor/regoapnodeeditor.cs blob/master/regoap/unity/editor/regoapnodebaseeditor.cs).
لاستخدامه ، فقط انقر فوق نافذة قائمة الوحدة ، ثم تصحيح الأخطاء Regoap ، سيتم فتح نافذة الوحدة ، وهذا هو DELSECTER DEBUGGER.
الآن إذا قمت بالنقر فوق أي وكيل في المشهد الخاص بك (أثناء اللعب ، يعمل فقط على الوكلاء الجريين) ، فسيتم تحديث النافذة تلقائيًا مما يتيح لك معرفة "أفكار" الوكل ما الذي يمكن فعله وما لا ، جربه!).
يتم تقدير أي طلب سحب ، فقط تأكد من التحقق من اختبارات الوحدة ( نافذة القائمة -> اختبار المحرر عداء -> تشغيل الكل ) قبل الالتزام والحفاظ على نفس النمط من التعليمات البرمجية.