上周突然发现,对于一些简易的AI,使用FSM+FuSM那一套,明显过于复杂了,对于一个很简单的AI来说,似乎只需要定义哪些情况下做哪些事情就足够了,比较粗鲁的写法就是:
if
then
else if
then
else if
then
.................
在AI的体系结构又被叫做Author Control (作者控制)。也可以叫做RBS——Rule Based System。
我们要写比较清晰的框架,首先要做的就是把 if部分和then部分隔离成两部分,各成为一个接口,且两者用一个string联系。
由于这部分是比较简单,我们直接上代码:
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:UEntity { 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); } } } };这里注意到,还有一个SimpleAI的Manager一样的类,申明为了单例,可以很容易的管理SimpleAI的移除和添加。