[FreedomAI]第五週——池化技術

這項優化方法又是從別的領域借鑑來的, 最開始瞭解的一個東西是線程池,內存池。

其實不論是線程池還是內存池,都在遊戲引擎中非常常見,首先我們先介紹一下他們的應用場景,因爲在遊戲引擎裏我們常常遇到這樣一個問題,那就是內存(線程)的申請和釋放非常頻繁,雖然這塊線程或者說內存的申請的數目或者大小不多,但是不論是內存的申請、釋放或者是線程的申請、釋放,都會導致要讓操作系統在用戶態和核心態之間還會切換,這是一項很耗時的操作。

所以前輩們就想到一種以空間換時間的方式,就是可以提前預申請一大塊內存,一大堆線程,然後先不用,不喚醒,用一個管理系統去存儲他們,於是在用戶申請內存或者線程的時候,就不是向操作系統提出申請,而是向這個我們自己的管理系統提出申請。往往這就是一個移動指針的時間——雖然這種方式實際用掉了很多待機的空間。

在我們做AI的時候,同樣面臨着這個問題,有一些AI,是死亡和生成非常頻繁,比如Boss召喚的自爆兵,偏偏這些東西數量還可能很大。而Instantiate和Destroy,偏偏又是兩個很耗時的操作,所以我們同樣使用了AI池的技術。

public class AIPoorComponent:UComponent
	{
		public GameObject mAI_Template;
		public AIEntity[] mAIPoor = new AIEntity[3000];
		public int mMaxCount = 3000;
		private int mTempCount = 0;


		public override void Init ()
		{
			for (int i = 0; i < mMaxCount; i++) 
			{
				mAIPoor [i].mAI = mAI_Template;
				mAIPoor [i].Init ();
				mAIPoor [i].GetComponent<BaseAIComponent> ().mPoorID = i;
			}
		}

		public override void Release ()
		{
			for (int i = 0; i < mMaxCount; i++) 
			{
				mAIPoor [i].Release ();
			}
		}



		public void DestroyEntity(int id)
		{
			mUEntity.mWorld.deleteEntity (mAIPoor[id]);
			mAIPoor [id].GetComponent<BaseAIComponent> ().mAIRT.SetActive (false);
			AIEntity temp = mAIPoor [id];
			mAIPoor [id] = mAIPoor[mTempCount-1];
			mAIPoor [mTempCount - 1] = temp;
			mAIPoor [id].GetComponent<BaseAIComponent> ().mPoorID = id;
			mAIPoor [mTempCount - 1].GetComponent<BaseAIComponent> ().mPoorID = mTempCount - 1;
			mTempCount--;
		}



		public AIEntity InstantiateEntity()
		{
			mAIPoor [mTempCount].mAllBitBunch.SetCount ((int)mUEntity.mWorld.mComponentCount);
			mUEntity.mWorld.registerEntity (mAIPoor[mTempCount]);
			mAIPoor [mTempCount].GetComponent<BaseAIComponent> ().mAIRT.SetActive (true);
			mTempCount++;
			return mAIPoor [mTempCount - 1];
		}

	}

首先這個管理器會有一個模板,也就是這些AI的Prefab,然後在遊戲一開始,我們就生成了一大堆這個玩意,然後都不激活他。

然後我們可以看到,Instantiate和Destroy在這裏,僅僅只是移動一下數組指針,和激活一下GameObject的操作。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章