Unity3D 单例模式

Unity3D 泛型单例

单例模式

单例模式是一种创建型设计模式,能够保证一个类只有一个实例,提供访问实例的全局节点。

通常会把一些管理类设置成单例,例如 GameManagerUIManager 等,可以很方便地使用这些管理类单例,存储变量和调用接口。

手动挂载的泛型单例

创建 SingletonMono.cs 脚本,在类名后面添加泛型和约束,定义泛型变量,并且在 Awake 方法中对变量进行赋值。

这里的 Awake 方法是虚方法,当有管理类继承这个 SingletonMono 时,可以重写 Awake 方法进行额外的操作。

csharp 复制代码
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class SingletonMono<T> : MonoBehaviour where T : MonoBehaviour
{
    static T instance;  // 私有静态实例
    public static T Instance { get { return instance; } }  // 公开实例属性

    protected virtual void Awake()
    {
        if (instance == null)
        {
            instance = this as T;
            // 切换场景时不销毁这个游戏物体
            DontDestroyOnLoad(gameObject);
        }
        else
        {
            // 切换场景时,如果场景里有单例游戏物体,在已经创建单例的情况下,销毁多余的游戏物体
            Destroy(gameObject);
        }
    }
}

创建 GameManager.cs 脚本,继承 SingletonMono 这个类。

csharp 复制代码
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class GameManager : SingletonMono<GameManager>
{
    public int score;

    protected override void Awake()
    {
        // 调用基类的 Awake 方法
        base.Awake();
        // 可以进行额外的初始化操作
        score = 0;
    }

    void Start()
    {
        
    }

    void Update()
    {
        
    }
}

在场景中创建游戏物体,把 GameManager 脚本手动挂载到游戏物体上。

创建 SingletonTest.cs 脚本,简单使用一下 GameManager.Instance 单例的变量。

csharp 复制代码
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class SingletonTest : MonoBehaviour
{
    void Start()
    {
        int score = GameManager.Instance.score;
        Debug.Log($"score = {score}");
    }
}

运行游戏,可以看到 GameManagerDontDestroyOnLoad 场景中,可以获取到 score 变量进行打印。

自动挂载的泛型单例

创建 SingletonMonoAuto.cs 脚本,在类名后面添加泛型和约束,定义泛型变量。

因为它并不需要在场景中手动创建游戏物体,也不会通过 Awake 方法对变量进行赋值。

所以在获取 Instance 属性时,如果属性为空,就通过代码创建一个不会销毁的游戏物体,并自动挂载单例组件。

csharp 复制代码
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class SingletonMonoAuto<T> : MonoBehaviour where T : MonoBehaviour
{
    static T instance;  // 私有静态实例

    // 公开实例属性
    public static T Instance
    {
        get
        {
            if (instance == null)
            {
                // 创建一个新的游戏物体
                GameObject obj = new GameObject();
                // 根据类型进行重命名
                obj.name = typeof(T).ToString();
                // 自动挂载单例组件
                instance = obj.AddComponent<T>();
                // 不可销毁
                DontDestroyOnLoad(obj);
            }
            // 返回实例
            return instance;
        }
    }
}

创建一个 UIManager.cs 脚本,继承 SingletonMonoAuto 这个类。

csharp 复制代码
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class UIManager : SingletonMonoAuto<UIManager>
{
    void Awake()
    {
        Debug.Log("初始化 UIManager");
    }

    void Start()
    {
        
    }

    void Update()
    {
        
    }
}

SingletonTest.cs 脚本,简单使用一下 UIManager.Instance 单例。

csharp 复制代码
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class SingletonTest : MonoBehaviour
{
    void Start()
    {
        int score = GameManager.Instance.score;
        Debug.Log($"score = {score}");

        UIManager uiManager = UIManager.Instance;
    }
}

运行游戏,可以看到 UIManagerDontDestroyOnLoad 场景中自动创建。

相关推荐
魔士于安9 小时前
unity 音乐会场景 unity2022
游戏·unity·游戏引擎·贴图·模型
Mediary11 小时前
Unity is running with Administrator privileges, which isnot supported...
unity
游乐码13 小时前
Unity基础(十四)场景异步加载
unity·游戏引擎
mxwin14 小时前
Unity Shader URP:法线在空间变换上的特殊性
unity·游戏引擎·shader
nnsix14 小时前
Unity 动态批处理、静态批处理、GPU Instaning、SRP Batcher 笔记
笔记·unity·单一职责原则
charlee4415 小时前
Unity在安卓端如何调试输出信息
android·unity·adb·游戏引擎·真机调试
_Athie16 小时前
【开发工具】自动创建项目文件夹结构
unity·编辑器
auccy1 天前
Unity Sprite 添加法线贴图
unity·贴图·normal
mxwin2 天前
次世代角色 PBR 贴图制作 + Unity URP 接入 极简流程图
unity·流程图·贴图·shader