当前位置: 代码网 > it编程>软件设计>设计模式 > 【Unity3D日常开发】Unity3D中实现单例模式详解

【Unity3D日常开发】Unity3D中实现单例模式详解

2024年08月03日 设计模式 我要评论
首先,说一下,什么是单例模式(Singleton)。单例模式是设计模式中常见的一种设计模式,目的是为了让一个类在程序运行期间有且只有一个实例,方便全局访问。应用在Unity里面,可以用来作为数据类、工具类、实现类,方便脚本调用。下面,就在Unity中实现单例模式。

大家好,我是佛系工程师☆恬静的小魔龙☆,不定时更新unity开发技巧,觉得有用记得一键三连哦。

一、前言

首先,说一下,什么是单例模式(singleton)

单例模式是设计模式中常见的一种设计模式,目的是为了让一个类在程序运行期间有且只有一个实例,方便全局访问。

应用在unity里面,可以用来作为数据类、工具类、实现类,方便脚本调用。

下面,就在unity中实现单例模式。

二、实现单例模式

2-1、如何实现单例模式

首先,来看一下单例模式的uml图:
在这里插入图片描述
实现流程:
1、私有的构造函数,也就是用static静态字段。

2、私有静态对象,用于实例化当前类。
3、公有静态函数或属性,方便其他对象获取这个单例类。

实现方式:
1、饿汉式
2、懒汉式
3、通用类

2-2、实现饿汉式单例模式

参考代码:

/// <summary>
/// 饿汉式单例模式通用父类
/// </summary>
public class singleton
{
    //私有构造函数
    private singleton() { }
    //私有对象
    private static singleton instance;
    //公有对象
    public static singleton instance 
    {
        get
        {
            if (instance == null)
            {
                instance = new singleton();
            }
            return instance;
        }
    }
}

饿汉式的单例,是在程序开始的时候对static属性的instance进行初始化,饿汉式的特征:

  • 线程安全,static构造函数只可能运行一次
  • 存在空引用的风险,可能运行顺序关系两个类同时引用此单例,就会报空引用错误

2-3、实现懒汉式单例模式

参考代码:

/// <summary>
/// 懒汉式单例模式通用父类
/// </summary>
public class singletonlazy
{
    //私有构造函数
    private singletonlazy() { }
    //私有对象
    private static volatile singletonlazy instance;
    private static object locker = new object();
    //公有对象
    public static singletonlazy instance
    {
        get
        {
            if (instance == null)
            {
                lock (locker)
                {
                    if (instance == null)
                    {
                        //确保只调用一次
                        instance = new singletonlazy();
                    }
                }
            }
            return instance;
        }
    }
}

懒汉式单例,确保只创建一个实例,只需要实例时创建,懒汉式的特征:

  • 变量用volatile声明,确保在访问实例变量之前完成对实例变量的赋值
  • 使用locker实例来上锁,而不是锁住类型本身,避免死锁

懒汉式是在饿汉式的基础上优化而来,是为了避免多个对象同时访问实例对象的时候报空引用。

而且懒汉式还可以延迟实例化,直到对象被第一次访问。

多数情况下用饿汉式单例模式实现就可以。

2-4、实现通用类单例模式

上述例子,只是实现单个类的单例模式,在实际开发中会出使用更多的单例,就可以使用一个通用单例父类进行单例实现,子类继承单例父类,就可以继承单例模式,提高代码简洁度。

实现通用单例类可以使用泛型,参考代码:

namespace common
{
public class singleton<t> where t : class, new()
{
    private static t _instance;
    private static readonly object syslock = new object();

    public static t instance
    {
        get
        {
            if (_instance == null)
            {
                lock (syslock)
                {
                    if (_instance == null)
                    {
                        _instance = new t();
                    }
                }
            }
            return _instance;
        }
    }
}
}

使用方式:

public class usesingleton : singleton<usesingleton>
{
    public string name;
    public int age;
}

单例类继承实现单例模式的父类singleton

using unityengine;

public class callsingleton : monobehaviour
{
    void start()
    {
        // 修改单例类的变量值
        usesingleton.instance.name = "张三";
    }
}

脚本去调用或修改单例类中变量的值。

2-5、实现mono通用类单例模式

参考代码:

using unityengine;

namespace common
{
    public class monosingleton<t> : monobehaviour where t : monobehaviour
    {

        private static t _instance;

        public static t instance
        {
            get
            {
                return _instance;
            }
        }

        protected virtual void awake()
        {
            _instance = this as t;
        }
    }
}

mono脚本的单例相比较于普通c#单例有一些变化点:

  • 不能用new实例化,需要挂载到场景中的对象上
  • 在脚本生命周期的awake函数中初始化
  • 无需担心因awake等调用顺序造成的空指针异常

使用方式:

public class usesingleton : monosingleton<usesingleton>
{
    public string name;
    public int age;
}

调用:

using unityengine;

public class callsingleton : monobehaviour
{
    void start()
    {
        // 修改单例类的变量值
        usesingleton.instance.name = "张三";
    }
}

需要将usesingleton.cs脚本挂载到场景中的对象上,如果不继承mono就不用挂载到场景中的对象上。

三、后记

本篇文章介绍了什么是单例模式,以及如何实现单例模式。

以及单例模式的饿汉式和懒汉式的区别。

以及在unity中如何使用单例模式。

最后修改代码制作通用单例模式父类,其他子类继承后就可以实现单例模式。

通用单例模式有两种类型:

  • 不继承mono的单例模式
  • 继承mono的单例模式

你的点赞就是对博主的支持,有问题记得留言:

博主主页有联系方式。

博主还有跟多宝藏文章等待你的发掘哦:

专栏方向简介
unity3d开发小游戏小游戏开发教程分享一些使用unity3d引擎开发的小游戏,分享一些制作小游戏的教程。
unity3d从入门到进阶入门从自学unity中获取灵感,总结从零开始学习unity的路线,有c#和unity的知识。
unity3d之uguiuguiunity的ui系统ugui全解析,从ugui的基础控件开始讲起,然后将ugui的原理,ugui的使用全面教学。
unity3d之读取数据文件读取使用unity3d读取txt文档、json文档、xml文档、csv文档、excel文档。
unity3d之数据集合数据集合数组集合:数组、list、字典、堆栈、链表等数据集合知识分享。
unity3d之vr/ar(虚拟仿真)开发虚拟仿真总结博主工作常见的虚拟仿真需求进行案例讲解。
unity3d之插件插件主要分享在unity开发中用到的一些插件使用方法,插件介绍等
unity3d之日常开发日常记录主要是博主日常开发中用到的,用到的方法技巧,开发思路,代码分享等
unity3d之日常bug日常记录记录在使用unity3d编辑器开发项目过程中,遇到的bug和坑,让后来人可以有些参考。
(0)

相关文章:

版权声明:本文内容由互联网用户贡献,该文观点仅代表作者本人。本站仅提供信息存储服务,不拥有所有权,不承担相关法律责任。 如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 2386932994@qq.com 举报,一经查实将立刻删除。

发表评论

验证码:
Copyright © 2017-2025  代码网 保留所有权利. 粤ICP备2024248653号
站长QQ:2386932994 | 联系邮箱:2386932994@qq.com