MonoBehaviour的实例池
Unity的开发中难免会遇到一些公共变量的共享,通常的做法就是在场景中放一个空GameObject,然后挂上若干个脚本,需要调用时,通过Find或者神马的得到这些脚本。
其实更简便的方式应该是用单例类(Singleton),在需要调用的时候再实例化这个类然后进行调用,不过众所周知,继承自MonoBehaviour的脚本都是不能new的,那么这也意味着单例类的“调用时再实例化”就不是那么直接就可以实现的了。
当然,世事无绝对,先上代码:
using System.Collections.Generic;
using UnityEngine;
abstract public class MonoInstancePool
{
private static Dictionary<string, Component> sInstancePool = new Dictionary<string, Component>();
public static T getInstance<T>(bool bDestroy = true, string sGameObjectName = null)
where T : Component
{
string sFullName;
if (sGameObjectName != null)
{
sFullName = sGameObjectName;
}
else
{
sFullName = typeof(T).FullName;
}
if (sInstancePool.ContainsKey(sFullName) && sInstancePool[sFullName] == null)
{
sInstancePool.Remove(sFullName);
}
if (!sInstancePool.ContainsKey(sFullName))
{
GameObject go = new GameObject();
go.name = sFullName;
sInstancePool.Add(sFullName,go.AddComponent<T>() as T);
if (bDestroy)
{
GameObject.DontDestroyOnLoad(go);
}
}
return sInstancePool[sFullName] as T;
}
}
通过在运行时创建GameObject,然后再AddComponent,这样就可以实现单例模式的“调用时实例化”了。
例如:
MonoInstancePool.getInstance<EventTicker>().startToTick();
当然这样做有一个小小的弊端,在编辑器里绑好的脚本可以预先拖放一些Prefab之类,而本文的上述方法就不太适用了(因为是在运行时实例化的),上述实例池适用的是UIManager之类的运行时的管理类。
>>相关产品