上周突然发现,对于一些简易的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的移除和添加。