Last week, I suddenly discovered that for some simple AIs, the use of FSM+FuSM is obviously too complicated. For a very simple AI, it seems that it is enough to define which things to do under which circumstances, which is rather rude. It is written as:
if
then
else if
then
else if
then
.................
The architecture in AI is also called Author Control. It can also be called RBS - Rule Based System.
If we want to write a clearer framework, the first thing to do is to separate the if part and the then part into two parts, each becoming an interface, and the two are connected by a string.
Since this part is relatively simple, we go directly to the code:
using System.Collections; using System.Collections.Generic; using UnityEngine; using UnityECS; using FreedomAI; namespace FreedomAI { public interface SimpleAIStateJudger { string DoJudge(SimpleAI sAI); }; public interface SimpleAIRunner { void DoRun (SimpleAI sAI,string statecode); }; public class SimpleAI:UEentity { public SimpleAIRunner mSimpleAIRunner; public SimpleAIStateJudger mSimpleAIStateJudger; public GameObject mAIRT; public GameObject mAITemplate; public GameObject mPlayer; public Vector3 GeneratePos; public void Init(SimpleAIRunner pSimpleAIRunner,SimpleAIStateJudger pSimpleAIStateJudger,GameObject pAITemplete,GameObject pPlayer,Vector3 pPos) { mSimpleAIRunner = pSimpleAIRunner; mSimpleAIStateJudger = pSimpleAIStateJudger; mAITemplate = pAITemplete; mPlayer = pPlayer; GeneratePos = pPos; mAIRT=GameObject.Instantiate (mAITemplate,GeneratePos,Quaternion.identity) as GameObject; SimpleAISetSingleton.getInstance ().GetComponent<SimpleAISet> ().mSimpleAIList.Add (this); this.AddComponent<AIMove> (new AIMove()); } } public class SimpleAISet:UComponent { public List<SimpleAI> mSimpleAIList = new List<SimpleAI>(); public List<SimpleAI> LastFrameRemove = new List<SimpleAI> (); public void Delete(SimpleAI pSimpleAI) { LastFrameRemove.Add (pSimpleAI); } public SimpleAI FindWithRiaus(Vector3 center,float maxdis,LayerMask layermask,string tag) { Collider[] myCollider = Physics.OverlapSphere (center,maxdis,layermask); GameObject fir = null; for (int i = 0; i < myCollider.Length; i++) { if (myCollider [i].gameObject.tag == tag) { fir = myCollider [i].gameObject; break; } } if (fir == null) { return null; } else { foreach (var v in mSimpleAIList) { if (v.mAIRT == fir) { return v; } } return null; } } } // Entity for all simple AI public class SimpleAISetSingleton:UEntity { private static SimpleAISetSingleton mSimpleAISetSingleton; public static SimpleAISetSingleton getInstance() { if (mSimpleAISetSingleton == null) mSimpleAISetSingleton = new SimpleAISetSingleton (); return mSimpleAISetSingleton; } public override void Init () { base.Init (); SimpleAISetSingleton.getInstance ().AddComponent<SimpleAISet> (new SimpleAISet ()); //Debug.Log ("aiInit"); } } // simpleAI compute system public class SimpleAIComputeSystem:USystem { public override void Init () { base.Init (); this.AddRequestComponent (typeof(SimpleAISet)); } public override void Update (UEntity uEntity) { base.Update (uEntity); List<SimpleAI> last = uEntity.GetComponent<SimpleAISet>().LastFrameRemove; foreach (var vAI in last) { uEntity.GetComponent<SimpleAISet>().mSimpleAIList.Remove(vAI); uEntity.mWorld.deleteEntity (VAI); // Debug.Log (uEntity.GetComponent<SimpleAISet> ().mSimpleAIList.Count); GameObject.Destroy (vAI.mAIRT); } last.Clear (); List<SimpleAI> tAIList = uEntity.GetComponent<SimpleAISet> ().mSimpleAIList; for (int i = 0; i < tAIList.Count; i++) { string code = tAIList [i].mSimpleAIStateJudger.DoJudge (tAIList[i]); tAIList [i].mSimpleAIRunner.DoRun (tAIList[i],code); } } } };Note here that there is also a class like SimpleAI's Manager, which declares that the removal and addition of SimpleAI can be easily managed for a singleton.