[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的操作。

猜你喜欢

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