ห้องสมุดทั่วไป C# GOAP (การวางแผนการดำเนินการตามเป้าหมาย) พร้อมตัวอย่าง Unity3D และชั้นเรียนผู้ช่วย
ห้องสมุดนี้เป็นเรื่องธรรมดามากหากคุณไม่ได้รวมโฟลเดอร์ Unity คุณสามารถใช้มันในเอ็นจิ้นเกมใดก็ได้
เริ่มต้นด้วยการตรวจสอบตัวอย่าง Unity FSM ที่นี่
ตัวอย่างนี้ใช้ไลบรารี RegoAP ใน Unity ด้วย FSM อย่างง่าย (Finite State Machine) เพื่อจัดการกับพฤติกรรมแมโคร (ในเกมส่วนใหญ่สามรัฐ FSM ควรพอเพียง: ไม่ได้ใช้งาน, goto, เคลื่อนไหว)
หากต้องการใช้มันสร้างโครงการ Unity ใหม่เปิดเชลล์ไปที่ไดเรกทอรีสินทรัพย์และโคลนพื้นที่เก็บข้อมูลทั้งหมดในนั้น:
git clone https://github.com/luxkun/ReGoap.git(ใน Windows คุณสามารถทำเช่นเดียวกันกับบรรทัดคำสั่งหรือไคลเอนต์ Git ใด ๆ คุณสามารถคลิกที่ "โคลนหรือดาวน์โหลด" จากนั้น "ดาวน์โหลด zip")
นอกจากนี้คุณยังสามารถดาวน์โหลดแพ็คเกจ Unity ของรุ่นล่าสุดซึ่งอาจจะไม่มีการเปลี่ยนแปลงล่าสุดที่นี่หรือใน Unity Asset Store
(หากคุณต้องการใช้ไลบรารีและต้องการตัวอย่างที่อธิบายข้ามไปยัง วิธีการใช้ 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': จริง, 'hasweapon': จริง
สามารถกำหนดเป็นรายการของเงื่อนไขและผลกระทบเหล่านี้คือการกระทำที่ตัวแทน (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 จะไม่ได้เขียนเอฟเฟกต์บนหน่วยความจำโดยค่าเริ่มต้น แต่หน่วยความจำควรตรวจสอบว่าเอฟเฟกต์จะทำอย่างมีประสิทธิภาพหากด้วยเหตุผลใดก็ตามที่คุณต้องการตั้งค่าเอฟเฟกต์ในตอนท้ายของการกระทำที่คุณสามารถเพิ่มได้ รหัสนี้ไปยังการใช้งาน 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 ) ;
}
}หมายเหตุ : ตรวจสอบให้แน่ใจว่าใช้ regoapgoaladvanced หากคุณต้องการเตือนตัวแทนโดยอัตโนมัติว่าเป้าหมายคือ/ไม่พร้อมใช้งาน
ตรวจสอบคลาส Basic 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 :)
}
}หมายเหตุ : ตรวจสอบให้แน่ใจว่าใช้ regoapmemory advanced เมื่อทำงานกับเซ็นเซอร์เนื่องจากคลาสพื้นฐานไม่ได้ตรวจสอบและอัปเดตเซ็นเซอร์
ในการดีบักตัวแทนของคุณเองคุณสามารถดีบั๊กด้วยตัวคุณเองด้วยบรรณาธิการที่คุณชื่นชอบ
แต่ Regoap มีตัวดีบักผู้ใช้งานมากสำหรับตัวแทนใน Unity (https://github.com/luxkun/regoap/blob/master/regoap/unity/editor/regoapnodeeditor.cs และ https://github.com/luxkun/regoap/ blob/master/regoap/unity/editor/regoapnodeBaseeditor.cs)
หากต้องการใช้เพียงคลิกที่ หน้าต่าง เมนูของ Unity จากนั้น RegoAP Debugger หน้าต่าง Unity จะเปิดขึ้นนี่คือ Agent Debugger
ตอนนี้ถ้าคุณคลิกที่เอเจนต์ใด ๆ ในฉากของคุณ (ในขณะที่เล่นใช้งานได้เฉพาะกับตัวแทนที่รัน) หน้าต่างจะอัปเดตโดยอัตโนมัติเพื่อแจ้งให้คุณทราบว่า "ความคิด" ของเอเจนต์ (สถานะโลกปัจจุบันเลือกเป้าหมายและแผนปัจจุบันเป้าหมายเป็นไปได้การกระทำที่เป็นไปได้ สิ่งที่สามารถทำได้และสิ่งที่ไม่ลอง!)
คำขอดึงใด ๆ ได้รับการชื่นชมเพียงตรวจสอบให้แน่ใจว่าได้ตรวจสอบการทดสอบความสามัคคี ( หน้าต่าง เมนู -> การทดสอบตัวแก้ไขนักวิ่ง -> เรียกใช้ทั้งหมด ) ก่อนที่จะดำเนินการและรักษารูปแบบของรหัสเดียวกัน