[FreedomAI]第四周——GroupBehaviour

为了制作具有群体性行为的AI,又一次踏上了征途。群体性行为和策略,同个体行为的结构是很像的,但更复杂的是,我们的底层必要有一个机制自动的辅助系统能获得哪些AI应该被形成一个组,为了解决这个问题,我们确立了发起者和响应者。

发起者会检测四周范围响应者,并加入到响应者队列里,最后在这个队列中检测出相应的组,并为这个组的成员分配编号,然后激活这个组所有实体的组行为。

另外,行为节点,行为转化节点的形式也大有不同,定义如下:

	public delegate void GroupStateRT(AIEntity pSponsor,AIEntity[] pResponses,int pid);

	public delegate void GroupStateEnter(AIEntity pSponsor,AIEntity[] pResponses,int pid);

	public delegate void GroupStateExit(AIEntity pSponsor,AIEntity[] pResponses,int pid);

	public delegate float GroupStateTransfer(AIEntity pSponsor,AIEntity[] pResponses,int pid);

在一个组行为中,你必须知道,发起者是谁,同组的有谁,以及在这个组中,你扮演的角色编号,你才能完全清楚这个组行为的全部信息,所以本来想要集成在FSM里计划完全泡汤,只能再独立出一个系统,现给出这个系统的一些代码:

public class GroupManager:UComponent
	{

		public List<List<GroupBehaviourNode>> mGroupLists;

		public SponsorNode[] mSponsors;

		public ResponseNode[] mResponses;

		public int mSponsorCount = 0;
		public int mResponseCount = 0;

		public Dictionary<string,List<int>> Dictionaryfortag2groupid;
		public Dictionary<int,GroupAllocation> Dictionaryforid2Allocation;
		public Dictionary<int,GroupStrategyRT> Dictionaryforid2Strategy;
		public Dictionary<int,GroupDissolve> Dictionaryforid2Dissolve;
		public Dictionary<EntityStrategyNode,GroupStrategyRT> DictionaryforStrategy;
		public Dictionary<EntityStrategyNode,AIGroupState> DictionaryforGroupState;
		//List<AIEntity> 

		private static GroupManager mGroupManagerSington;

		public static GroupManager getInstance()
		{
			if (mGroupManagerSington == null) 
			{
				mGroupManagerSington = new GroupManager ();
			}
			return mGroupManagerSington;
		}

		public GroupManager()
		{
			mGroupLists = new List<List<GroupBehaviourNode>> ();
			mSponsors = new SponsorNode[50];
			mResponses = new ResponseNode[500];
			Dictionaryfortag2groupid = new Dictionary<string, List<int>> ();
			Dictionaryforid2Allocation = new Dictionary<int, GroupAllocation> ();
			Dictionaryforid2Dissolve = new Dictionary<int, GroupDissolve> ();
			Dictionaryforid2Strategy = new Dictionary<int, GroupStrategyRT> ();
			DictionaryforStrategy = new Dictionary<EntityStrategyNode, GroupStrategyRT> ();
			DictionaryforGroupState = new Dictionary<EntityStrategyNode, AIGroupState> ();
		}

		public void AddGroupList(List<GroupBehaviourNode> pList,GroupDissolve pDissolve,GroupStrategyRT pStrategy,GroupAllocation pAllocation)
		{
			mGroupLists.Add (pList);
			int index = mGroupLists.IndexOf (pList);
			Dictionaryforid2Allocation.Add (index,pAllocation);
			Dictionaryforid2Dissolve.Add (index,pDissolve);
			Dictionaryforid2Strategy.Add (index,pStrategy);
		}

		public void AddSponsor(AIEntity pEntity)
		{
			SponsorNode tSponsor = new SponsorNode ();
			tSponsor.mSponsor = pEntity;
			tSponsor.mGroupListID = Dictionaryfortag2groupid [pEntity.tag];
			mSponsors [mSponsorCount] = tSponsor;
			mSponsorCount++;
		}

		public void AddResponse(AIEntity pEntity)
		{
			ResponseNode tResponseNode = new ResponseNode ();
			tResponseNode.mResponse = pEntity;
			mResponses [mResponseCount] = tResponseNode;
			mResponseCount++;
		}

		public void AddKey(string tag,List<int> pids)
		{
			Dictionaryfortag2groupid.Add (tag,pids);
		}

		public void AddStrategy(string tag,int id,GroupStrategyRT pStrategyRT,AIGroupState pStateRT)
		{
			EntityStrategyNode esn = new EntityStrategyNode ();
			esn.tagName = tag;
			esn.id = id;
			DictionaryforStrategy.Add (esn,pStrategyRT);
			DictionaryforGroupState.Add (esn,pStateRT);
		}

	}

	public class GroupBehaviourSystem:USystem
	{
		public override void Init ()
		{
			base.Init ();
			this.AddRequestComponent (typeof(GroupManager));
		}

		public override void Update (UEntity uEntity)
		{
			base.Update (uEntity);
			for (int i = 0; i < uEntity.GetComponent<GroupManager> ().mResponseCount; i++)
			{
				if (!uEntity.GetComponent<GroupManager> ().mResponses [i].mSucceedTeam)
					uEntity.GetComponent<GroupManager> ().mResponses [i].mLeader = null;
			}
			for (int i = 0; i < uEntity.GetComponent<GroupManager> ().mSponsorCount; i++)
			{
				if (uEntity.GetComponent<GroupManager> ().mSponsors [i].members [0].mSucceedTeam) 
				{
					if (uEntity.GetComponent<GroupManager> ().mSponsors [i].mDissloveTimer < 1.0f)
						uEntity.GetComponent<GroupManager> ().mSponsors [i].mDissloveTimer += Time.deltaTime;
					else
					{
						GroupDissolve tDissolve= uEntity.GetComponent<GroupManager> ().Dictionaryforid2Dissolve [uEntity.GetComponent<GroupManager> ().mSponsors [i].tempGroupID];
						AIEntity[] pEntitys = new AIEntity[uEntity.GetComponent<GroupManager> ().mSponsors[i].memebercount];
						for (int j = 0; j < uEntity.GetComponent<GroupManager> ().mSponsors [i].memebercount; j++)
							pEntitys [j] = uEntity.GetComponent<GroupManager> ().mSponsors [i].members [j].mResponse;
						float rate = tDissolve (uEntity.GetComponent<GroupManager>().mSponsors[i].mSponsor,pEntitys);
						if (Random.Range (0.0f, 1.0f) < rate)
						{
							for (int j = 0; j < uEntity.GetComponent<GroupManager> ().mSponsors [i].memebercount; j++)
							{
								uEntity.GetComponent<GroupManager> ().mSponsors [i].members [j].mResponse.isGrouping = false;
								uEntity.GetComponent<GroupManager> ().mSponsors [i].members [j].mSucceedTeam = false;
								uEntity.GetComponent<GroupManager> ().mSponsors [i].members [j].mLeader = null;
								uEntity.GetComponent<GroupManager> ().mSponsors [i].members [j].mGroupID = -1;
							}
							uEntity.GetComponent<GroupManager> ().mSponsors [i].memebercount = 0;
							uEntity.GetComponent<GroupManager> ().mSponsors [i].mDissloveTimer = 0.0f;
							uEntity.GetComponent<GroupManager> ().mSponsors [i].mSponsor.isGrouping= false;
							uEntity.GetComponent<GroupManager> ().mSponsors [i].tempGroupID = -1;
						}
					}
				} 
				else
				{
					uEntity.GetComponent<GroupManager> ().mSponsors [i].memebercount = 0;
					AIEntity[] mEntity = AIEntity.getAllEntityWithSphere (uEntity.GetComponent<GroupManager> ().mSponsors [i].mSponsor,10.0f);
					List<ResponseNode> mResponseList = new List<ResponseNode> ();
					for (int j = 0; j < mEntity.Length; j++)
					{
						for(int k=0;k<uEntity.GetComponent<GroupManager>().mResponseCount;k++)
						{
							ResponseNode rn = uEntity.GetComponent<GroupManager> ().mResponses [k];
							if (rn.mResponse == mEntity [j] && rn.mLeader == null) 
							{
								mResponseList.Add (rn);
								break;
							}
						}
					}

					int count = Mathf.Min (mResponseList.Count,uEntity.GetComponent<GroupManager>().mSponsors[i].members.Length);
					for(int j=0;j<count;j++)
					{
						uEntity.GetComponent<GroupManager> ().mSponsors [i].members [j] = mResponseList [j];
						uEntity.GetComponent<GroupManager> ().mSponsors [i].members [j].mLeader = uEntity.GetComponent<GroupManager> ().mSponsors [i].mSponsor;
					}

					GroupAllocation tAlloc = uEntity.GetComponent<GroupManager>().Dictionaryforid2Allocation[uEntity.GetComponent<GroupManager> ().mSponsors [i].tempGroupID];
					AIEntity[] pEntitys = new AIEntity[uEntity.GetComponent<GroupManager> ().mSponsors[i].memebercount];
					for (int j = 0; j < uEntity.GetComponent<GroupManager> ().mSponsors [i].memebercount; j++)
						pEntitys [j] = uEntity.GetComponent<GroupManager> ().mSponsors [i].members [j].mResponse;
					int[] ids = tAlloc (uEntity.GetComponent<GroupManager> ().mSponsors [i].mSponsor,pEntitys);
					uEntity.GetComponent<GroupManager> ().mSponsors [i].mSponsor.isGrouping = true;
					uEntity.GetComponent<GroupManager> ().mSponsors [i].mSponsor.GetComponent<AIGroupState> ().tempGroupID = 0;
					EntityStrategyNode esn = new EntityStrategyNode ();esn.id = uEntity.GetComponent<GroupManager> ().mSponsors [i].tempGroupID;
					esn.tagName = uEntity.GetComponent<GroupManager> ().mSponsors [i].mSponsor.tag;
					AIGroupState mStateRT = uEntity.GetComponent<GroupManager> ().DictionaryforGroupState[esn];
					uEntity.GetComponent<GroupManager> ().mSponsors [i].mSponsor.GetComponent<AIGroupState> ().SimpleClone (mStateRT);
					uEntity.GetComponent<GroupManager> ().mSponsors [i].mSponsor.GetComponent<AIGroupState> ().pLeader = uEntity.GetComponent<GroupManager> ().mSponsors [i].mSponsor;
					uEntity.GetComponent<GroupManager> ().mSponsors [i].mSponsor.GetComponent<AIGroupState> ().pMembers = pEntitys;
					for(int j=0;j<uEntity.GetComponent<GroupManager>().mSponsors[i].memebercount;j++)
					{
						uEntity.GetComponent<GroupManager> ().mSponsors [i].members [j].mGroupID = ids [j];
						uEntity.GetComponent<GroupManager> ().mSponsors [i].members [j].mResponse.isGrouping = true;
						uEntity.GetComponent<GroupManager> ().mSponsors [i].members [j].mResponse.GetComponent<AIGroupState> ().tempGroupID = ids [j];
						EntityStrategyNode esn1 = new EntityStrategyNode ();esn1.id =  uEntity.GetComponent<GroupManager> ().mSponsors [i].tempGroupID;
						esn1.tagName = uEntity.GetComponent<GroupManager> ().mSponsors [i].members [j].mResponse.tag;
						AIGroupState mStateRT1 = uEntity.GetComponent<GroupManager> ().DictionaryforGroupState[esn1];
						uEntity.GetComponent<GroupManager> ().mSponsors [i].members [j].mResponse.GetComponent<AIGroupState> ().SimpleClone (mStateRT1);
						uEntity.GetComponent<GroupManager> ().mSponsors [i].members [j].mResponse.GetComponent<AIGroupState> ().pLeader = uEntity.GetComponent<GroupManager> ().mSponsors [i].mSponsor;
						uEntity.GetComponent<GroupManager> ().mSponsors [i].members [j].mResponse.GetComponent<AIGroupState> ().pMembers = pEntitys;
					}
				}
			}
		}
	}

	public struct GroupStateTransferNode
	{
		public int id;
		public GroupStateTransfer mTransfer;
	}

	public class AIGroupState:UComponent
	{
		public int tempGroupID;

		public AIEntity pLeader;

		public AIEntity[] pMembers;

		public GroupStateRT[] mGroupStateRTs;
		public GroupStateEnter[] mGroupStateEnters;
		public GroupStateExit[] mGroupStateExits;
		public List<GroupStateTransferNode>[] mGroupStateTransfers;
		public List<GroupStateTransferNode> mGroupStateAnyTransfers;

		public Dictionary<int,string> mAnimationDic;

		public int tempID;

		public int GroupStateCount = 0;
		public int TransferCount = 0;

		public AIGroupState()
		{
			mGroupStateEnters = new GroupStateEnter[15];
			mGroupStateEnters = new GroupStateEnter[15];
			mGroupStateRTs = new GroupStateRT[15];
			mGroupStateTransfers = new List<GroupStateTransferNode>[30];
			for (int i = 0; i < 30; i++) 
			{
				mGroupStateTransfers [i] = new List<GroupStateTransferNode> ();
			}
			mAnimationDic = new Dictionary<int, string> ();
			mGroupStateAnyTransfers = new List<GroupStateTransferNode> ();
			isEnable = false;
		}

		public int AddGroupState(GroupStateRT prt,GroupStateEnter penter,GroupStateExit pexit)
		{
			mGroupStateRTs [GroupStateCount] = prt;
			mGroupStateEnters [GroupStateCount] = penter;
			mGroupStateExits [GroupStateCount] = pexit;
			GroupStateCount++;
			return GroupStateCount - 1;
		}

		public void AddTransfer (int id1,int id2,GroupStateTransfer pTransfer)
		{
			GroupStateTransferNode gstn = new GroupStateTransferNode ();
			gstn.id = id2;
			gstn.mTransfer = pTransfer;
			mGroupStateTransfers [id1].Add (gstn);
		}

		public void AddAnyTransfer(int id1,GroupStateTransfer pTransfer)
		{
			GroupStateTransferNode gstn = new GroupStateTransferNode ();
			gstn.id = id1;
			gstn.mTransfer = pTransfer;
			mGroupStateAnyTransfers.Add (gstn);
		}

		public void AddAnim(int id,string name)
		{
			mAnimationDic.Add (id,name);
		}

		public void SimpleClone(AIGroupState pGroupState)
		{
			Dictionary<int,string> mdic = new Dictionary<int, string> ();
			foreach(var item in pGroupState.mAnimationDic)
			{
				int ti = item.Key;
				string ts = item.Value;
				mdic.Add (ti,ts);
			}
			mAnimationDic = mdic;
			GroupStateCount = pGroupState.GroupStateCount;
			for (int i = 0; i < GroupStateCount; i++)
			{
				mGroupStateEnters [i] = pGroupState.mGroupStateEnters [i];
				mGroupStateExits [i] = pGroupState.mGroupStateExits [i];
				mGroupStateRTs [i] = pGroupState.mGroupStateRTs [i];
			}
			TransferCount = pGroupState.TransferCount;
			for (int i = 0; i < TransferCount; i++) 
			{
				mGroupStateTransfers [i] = pGroupState.mGroupStateTransfers [i];
			}
			tempID = pGroupState.tempID;
		}

	}


	public class GroupStateUpdateSystem:USystem
	{
		public override void Init ()
		{
			base.Init ();
			this.AddRequestComponent (typeof(AIGroupState));
		}

		public override void Update (UEntity uEntity)
		{
			base.Update (uEntity);
			if (!uEntity.GetComponent<AIGroupState> ().isEnable)
				return;
			AIEntity pLeader = uEntity.GetComponent<AIGroupState> ().pLeader;
			AIEntity[] pMembers = uEntity.GetComponent<AIGroupState> ().pMembers;
			int pid = uEntity.GetComponent<AIGroupState> ().tempGroupID; 

			foreach(GroupStateTransferNode gstn in uEntity.GetComponent<AIGroupState>().mGroupStateAnyTransfers)
			{
				int id = gstn.id;
				if (id == uEntity.GetComponent<AIGroupState> ().tempID)
				{
					continue;
				}
				GroupStateTransfer tTransfer = gstn.mTransfer;
				float rate = tTransfer (pLeader,pMembers,pid);
				if (rate * Time.deltaTime > Random.Range (0.0f, 1.0f))
				{
					GroupStateExit tExit = uEntity.GetComponent<AIGroupState>().mGroupStateExits[uEntity.GetComponent<AIGroupState>().tempID];
					tExit (pLeader,pMembers,pid);
					uEntity.GetComponent<AIGroupState> ().tempID = id;
					GroupStateEnter tEnter = uEntity.GetComponent<AIGroupState>().mGroupStateEnters[uEntity.GetComponent<AIGroupState>().tempID];
					tEnter (pLeader,pMembers,pid);
					GroupStateRT ttRT = uEntity.GetComponent<AIGroupState> ().mGroupStateRTs [uEntity.GetComponent<AIGroupState> ().tempID];
					ttRT (pLeader,pMembers,pid);
					string ttName = uEntity.GetComponent<AIGroupState>().mAnimationDic[uEntity.GetComponent<AIGroupState> ().tempID];
					uEntity.GetComponent<AIAnimation> ().tempAnim = ttName;
					return;
				}
			}
				
			foreach(GroupStateTransferNode gstn in uEntity.GetComponent<AIGroupState>().mGroupStateTransfers[uEntity.GetComponent<AIGroupState>().tempID])
			{
				int id = gstn.id;
				GroupStateTransfer tTransfer = gstn.mTransfer;
				float rate = tTransfer (pLeader,pMembers,pid);
				if (rate * Time.deltaTime > Random.Range (0.0f, 1.0f))
				{
					GroupStateExit tExit = uEntity.GetComponent<AIGroupState>().mGroupStateExits[uEntity.GetComponent<AIGroupState>().tempID];
					tExit (pLeader,pMembers,pid);
					uEntity.GetComponent<AIGroupState> ().tempID = id;
					GroupStateEnter tEnter = uEntity.GetComponent<AIGroupState>().mGroupStateEnters[uEntity.GetComponent<AIGroupState>().tempID];
					tEnter (pLeader,pMembers,pid);
					break;
				}
			}
			GroupStateRT tRT = uEntity.GetComponent<AIGroupState> ().mGroupStateRTs [uEntity.GetComponent<AIGroupState> ().tempID];
			tRT (pLeader,pMembers,pid);
			string tName = uEntity.GetComponent<AIGroupState>().mAnimationDic[uEntity.GetComponent<AIGroupState> ().tempID];
			uEntity.GetComponent<AIAnimation> ().tempAnim = tName;
		}
	}

猜你喜欢

转载自blog.csdn.net/qq_33999892/article/details/80148430