对于普通C#脚本类,不必挂载在游戏场景内的物体上,也就不会出现在Inspector面板上,不继承MonoBehavior类。
单例模式
整个游戏内全局只持有一份实例。
public abstract class Singleton<T> where T : Singleton<T>, new()
{
private static T instance;
private T(){}
public static T Instance
{
get
{
if (instance == null)
{
instance = new T();
}
return instance;
}
}
}
使用泛型T来指定实例类型,同时使用无参构造函数约束new和基类约束,new确保在类内可以对T进行实例化,基类约束的意义是限定传进来的泛型参数为SingleTon的子类,写的时候把自己传进去,套娃。
由于全局唯一,故使用静态属性Instance并在获取属性时判断属性是否为空,为空new一个,不为空直接返回。
使用时需要运用单例模式的C#类直接继承SingleTion即可,示例如下。
构造函数私有化,外部不能new,不写这个构造函数则会默认有一个公有的构造函数,外部就可以new,这样不符合单例模式,我们希望new发生在第一次调用属性Get对象时自动执行。
加断点调试可以发现,第一次进入SingleTon时instance为空,会先去new一次对象。
这里需要额外说明的是:
以上通过属性实现在get时才真正实例化对象的Lazy Loading模式避免了资源浪费,被称作为懒汉式单例。但懒汉式也存在线程不安全的问题,当多个线程进入if(instance == null)逻辑时,对象的创建就可能会产生多个实例,Unity中由于一般不采用多线程的开发方式,所以懒汉式一般可满足要求,如果有必要可以使用双重校验的懒汉式单例,可参考。
与懒汉式相对的另一种单例模式是饿汉式,其会在类加载时就new好对象,线程安全。缺点就是有可能会造成资源浪费,在我没用到这个单例的时候就对单例进行了实例化,如果以后一直不用会产生内存浪费。
public abstract class Singleton<T> where T : Singleton<T>, new()
{
private static T instance = new T();
private T(){}
public static T Instance
{
get
{
return instance;
}
}
}