单例模式
单例模式(Singleton Pattern)是一种创建型设计模式,确保一个类只有一个实例,并提供一个全局访问点来访问这个实例。在Unity中,单例模式常用于管理游戏状态、配置设置、全局事件系统等需要在整个应用程序生命周期内保持单一实例的情况。
实现单例模式的基本步骤
- 私有化构造函数:防止其他类通过构造函数实例化该类。
- 静态私有成员变量:保存类的唯一实例。
- 公开静态方法:提供获取该实例的方法。
- 线程安全考虑(可选):如果在多线程环境下使用,需确保线程安全。
Unity中的单例模式示例
下面是一个适用于Unity环境下的简单单例模式实现
using UnityEngine;
public class SingletonExample : MonoBehaviour
{
// 静态成员保存实例
private static SingletonExample _instance;
// 公开属性提供访问实例的方法
public static SingletonExample Instance
{
get
{
if (_instance == null)
{
// 尝试查找现有实例,如果没有则创建新的实例
_instance = FindObjectOfType<SingletonExample>();
if (_instance == null)
{
// 如果找不到任何实例,则创建一个新的对象并添加当前脚本组件
GameObject singletonObject = new GameObject(typeof(SingletonExample).Name);
_instance = singletonObject.AddComponent<SingletonExample>();
}
}
return _instance;
}
}
// 私有化构造函数以防止外部实例化
protected SingletonExample()
{
}
private void Awake()
{
// 确保只有一个实例存在
if (_instance != null && _instance != this)
{
Destroy(gameObject);
}
else
{
_instance = this;
// 如果希望该对象不被销毁当切换场景时,可以取消下面这行注释
// DontDestroyOnLoad(gameObject);
}
}
}
关键点解释
Instance 属性:提供了全局访问点来获取单例实例。首次调用时会检查是否已存在实例,若不存在则尝试从场景中查找或创建一个新的实例。
Awake() 方法:确保在同一时刻只有一个实例存在。如果有多个实例试图同时存在,将销毁新创建的实例,保留原有的那个。
DontDestroyOnLoad(gameObject):根据需求决定是否保留该单例实例跨场景。如果你的游戏需要在场景切换过程中保持某些数据或状态,可以使用此功能。
注意事项
延迟初始化 vs 立即初始化:上述例子采用了延迟初始化的方式(第一次访问 Instance 时才创建对象)。另一种方式是立即初始化,在加载时就创建实例,这种方式适合于那些必须在游戏开始前就存在的对象。
线程安全:对于大多数Unity应用而言,不需要特别处理线程安全问题,但如果涉及到后台任务或异步操作,可能需要额外的同步机制保证线程安全。
单例模式虽然方便,但应谨慎使用,因为它可能导致代码难以测试和维护。通常建议仅在确实需要全局唯一实例的情况下采用。