原创内容,转载请注明原文网址:http://homeqin.cn/a/wenzhangboke/jishutiandi/youxikaifa/2018/1014/79.html
常州游戏开发培训工作室今天我们讨论一下U3D中的单例,如果是开发人员,肯定对Unity中的单例再熟悉不过了,由于游戏项目功能模块繁多,很多独立的模块都有自己单独的唯一入口,基本上都是用单例实现的,就像:
public class UIManager : MonoBehaviour
{
private static UIManager _instance;
public static UIManager Instance
{
get
{
if (_instance == null)
{
_instance = new GameObject(typeof(UIManager).Name).AddComponent<UIManager>();
}
return _instance;
}
}
}
上面的UIManager就是一个单例类,当第一次访问UIManager.Instance的时候,我们就会在游戏内创建一个名叫“UIManager”的物体,它挂载了我们的单例脚本实例UIManager。
现在有一个问题,假如我有100个单例类要创建,每个类都要复制这段代码很麻烦很不精炼,有没有更简洁的方法可以使用。
答案是肯定的,我们把单例的实现封装到基类中去就不用各种复制代码了,可是基类并不知道子类的具体类型,怎么返回子类型的Instance?如果Instance是以基类类型返回的,那么这个基类的存在意义就不大了。但是幸好C#有泛型,我们可以把子类的具体类型以泛型参数T的形式通知给基类,这样基类就能返回子类型。下面是代码:
public class ManagerBase<T> : MonoBehaviour where T : ManagerBase<T>
{
private static T _instance;
public static T Instance
{
get
{
if (_instance == null)
{
_instance = new GameObject(typeof(T).Name).AddComponent<T>();
}
return _instance;
}
}
}
这个基类最重要的代码就是where T : ManagerBase<T>,它限定T必须是ManagerBase<T>的子类,虽然它长的着实有点奇怪。
这时我们再声明单例类UIManager的时候就可以一行代码搞定了:
public class UIManager : ManagerBase<UIManager>
{
}
这里子类把自己的类型作为泛型参数通知给了基类,基类便知道Instance应该是什么类型了。使用的时候直接访问UIManager.Instance即可。
这个ManagerBase我觉得有点复杂,同时创建了一个私有静态变量_instance和公有静态属性Instance,显得有点冗余,这里我们做个优化:
public class ManagerBase<T> : MonoBehaviour where T : ManagerBase<T>
{
public static readonly T Instance = new GameObject(typeof(T).Name).AddComponent<T>();
}
上篇:上一篇:A*算法实现自动寻路
下篇:下一篇:U3D场景切换时背景音乐不间断播放