1、目的
使用单例模式创建角色对象,保证整个游戏中只有一个角色,并且让游戏对象具有全局可访问性。
2、流程
(1)创建SingletonMonobehaviour脚本
Assets下创建Scripts目录用于存放所有的脚本,再创建Misk子目录,创建SingletonMonobehaviour脚本。
public abstract class SingletonMonobehaviour<T> : MonoBehaviour where T: MonoBehaviour
{
private static T instance;
public static T Instance { get { return instance; } }
protected virtual void Awake()
{
if (instance == null)
{
instance = this as T;
}
else
{
Destroy(gameObject);
}
}
}
(2)创建Player脚本
public class Player : SingletonMonobehaviour<Player>
{
}
(3)挂载Player脚本并执行程序
将Player脚本挂载到Prefabs -> Player对象上。
然后通过Player预设体创建两个对象,执行程序后发现只剩下一个对象。
3、代码解读
这段代码实现了一个Unity中的单例模式,专门用于MonoBehaviour类。
在Unity游戏开发中,单例模式是一种常用的设计模式,,用于确保一个类只有一个实例,并提供一个全局访问点。
这个实现方式利用了Unity的生命周期方法Awake来确保实例的唯一性。
(1)SingletonMonobehaviour<T> 类
泛型类,其中T被约束继承自MonoBehaviour。这意味着这个单例模式只能用于MonoBehaviour的子类。
- private static T instance;
instance是一个静态字段,用于存储类的唯一实例。由于是静态的,它将在类的所有实例之间共享。
- public static T Instance
提供了一个公共的静态属性Instance,用于访问类的唯一实例。上面提到过,单例模式提供了一个全局访问点,而Instance属性就是这个全局访问点。
- protected virtual void Awake()
重写了Unity的Awake方法。Awake在对象被加载时自动调用,这使得它成为初始化单例实例的理想位置。
在Awake方法中,首先检查instance是否为null。如果是,表示这是第一个被创建的实例,因此将当前实例(通过this as T)赋值给instance.
如果instance不为null,表示已经存在一个实例。在这种情况下,为了避免多个实例同时存在,当前的游戏对象(gameObject)会被销毁。
(2)Player类
Player 类继承自SingletonMonobehaviour<Player>。通过这样做,Player 类自动获得了单例模式的特性。
由于SingletonMonobehaviour<T>是一个泛型类,Player 指定了T为Player自身,这意味着instance字段将特定于Player类,确保Player类在场景中只有一个实例。
后续假设在游戏管理类GameManager类中访问该游戏对象,可以通过Player.Instance获取该实例。
单例模式不负责创建对象,它只是确保只有一个实例存在并提供访问它的方式。
在本例中,第一个Player被创建的时候,当前的gameObject会被存放到Player单例的instance变量中。当第二个Player被创建的时候,发现instance变量已经有值了,就通过Destory(gameObject)把当前对象删除掉。