在Unity场景中,经常有很多脚本需要引入,而这些脚本中,有很大一部分都是只需要引用一次,也只需要进行一次实例化,此时我们可以提供一个工具用于自动获取该脚本的实例对象,并保证全场景中只包含这一个实例,还能在脚本未被引入时实现自动引入脚本。这是一个非常实用的工具,几乎每个项目都会用到。
该工具的特点:
- 自动获取该脚本的实例对象。
- 保证全场景中只包含这一个实例。
- 在脚本未被引入时实现自动引入脚本。
具体代码如下:
/// <summary>
/// Mono脚本单例工具
/// 使用场景:所有在场景中只出现一次的脚本都应该使用此类获取实例。<br />
/// 作用:<br />
/// 1、如果脚本已经被引用到场景中,则在任何类中都可以直接使用该子类的实例。<br />
/// 2、如果脚本未被引用,可以直接使用此类进行引用,无需手动引用。<br />
/// 使用方法:<br />
/// 1、在继承此类时必须将子类类型作为泛型传递给父类。<br />
/// 2、在任意脚本生命周期中,通过子类类型访问Instance即可获取子类实例。<br />
/// </summary>
public class MonoSingleton<T> : MonoBehaviour where T : MonoSingleton<T>
{
/// <summary>
/// 实例对象,该对象不允许外部访问,在此类外部需要使用Instance的get方法来获取实例
/// </summary>
private static T instance;
/// <summary>
/// 用此方法来获取实例,当此方法第一次被调用时,会主动寻找子类的脚本,如果并未找到,则创建该脚本。
/// </summary>
public static T Instance
{
get
{
if (instance == null)
{
instance = FindObjectOfType<T>();
if (instance == null)
{
new GameObject("Singleton of " + typeof(T)).AddComponent<T>();
}
else
{
instance.Init();
}
}
return instance;
}
}
protected void Awake()
{
if (instance == null)
{
instance = this as T;
Init();
}
}
/// <summary>
/// 默认初始化方法,子类可以重写此方法进行初始化
/// </summary>
public virtual void Init()
{
}
}
// ****************下面为测试代码********************
// 这个类是我们需要实现单例的脚本,只需要继承MonoSingleton并提供泛型即可。
public class XXManager : MonoSingleton<XXManager>
{
public void Fun1()
{
print("我要做事了~");
}
}
// 这个类是用来测试调用的脚本,只需要使用调用类的Instance属性即可获取实例。
public class TestSingleton : MonoBehaviour
{
private void Awake()
{
XXManager.Instance.Fun1();
}
}