[FreedomAI] Week 4 - GroupBehaviour

In order to make AI with group behavior, I embarked on a journey again. Group behaviors and strategies are very similar to the structure of individual behaviors, but what is more complicated is that there must be a mechanism at the bottom of our automatic auxiliary system to obtain which AI should be formed into a group. In order to solve this problem, we establish Initiator and Responder.

The initiator will detect the responders in the surrounding range, add them to the responder queue, and finally detect the corresponding group in this queue, assign numbers to the members of this group, and then activate the group behavior of all entities in this group.

In addition, the forms of behavior nodes and behavior transformation nodes are also very different, which are defined as follows:

	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);

In a group behavior, you must know who the initiator is, who is in the same group, and the number of the role you play in this group, so that you can fully understand all the information of this group behavior, so I wanted to integrate it in The plan in FSM was completely ruined, and only one more system could be created independently. Here are some codes for this system:

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] = fixed;
			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;
		}
	}

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=325767298&siteId=291194637