推荐阅读

  • CSDN主页
  • GitHub开源地址
  • Unity3D插件分享
  • 简书地址
  • 我的个人博客
  • QQ群:1040082875

❤ 一、前言

最近,有粉丝问我:

粉丝:“怎么用单例模式呀?”
我:“https://blog.csdn.net/weixin_43430200/article/details/107459447”
粉丝:“我知道咋写,就是不知道怎么用”
我:“好家伙,那我就给你演示一下怎么用吧”

❤ 二、单例模式介绍

首先要了解,单例模式是一种常用的软件设计模式,定义是单例对象的类只能允许一个实例存在,在许多时候整个系统只需要拥有一个全局对象,有利于协调系统整体的行为。

比如,服务器程序,将配置信息存放到一个文件中,然后使用一个单例对象进行读取,其他服务进程中的其他对象再通过这个单例去获取这些配置信息,简化了配置管理。

单例模式的结构图如下图所示:

那么,单例模式在Unity中又有那些应用场景呢:

1、在使用Unity开发项目的时候,经常会遇到需要一个管理类来管理一些全局的变量和方法,比如GameManager用于记录各种需要在整个游戏中用到数据。

2、一些需要从外部文档读取的数据,在其他脚本对象也需要用到的使用,也可以使用单例对象进行读取,其他对象再通过这个单例对象去获取数据。

假设有以下需求:

1、整个项目中有且只有一个DataManager单例对象
2、在DataManager单例对象中,需要去读取文档的数据,并且保存下载
3、在切换场景的时候DataManager对象不能被销毁
4、在不同的脚本中可以读取到DataManager单例对象读取的值

下面我们就来一步步实现单例对象下的DataManager。

❤ 三、实现单例模式的DataManager

❤ 3-1、定义单例对象

我们定义一个DataManager对象,继承于MonoBehaviour,具体代码如下:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;public class DataManager : MonoBehaviour
{public static DataManager Instance;private void Awake(){Instance = this;DontDestroyOnLoad(gameObject);}
}

1、使用静态的DataManager属性Instance保证了它可以通过类进行访问,而不是通过实例化访问
2、继承MonoBehaviour类的实例是由Unity进行创建,不能通过构造函数创建
3、在Awake函数里面对Instance进行赋值,保证了这个属性可以第一时间初始化
4、使用DontDestroyOnLoad可以使这个挂载脚本的游戏对象在切换场景中也不会被销毁
5、DontDestroyOnLoad的参数使用(gameObject),这样切换场景中游戏对象不会被销毁,使用this只能保证当前脚本不会被销毁,但是对象销毁了,这个脚本也没有了。

创建完这个对象,在场景中也新建一个DataManager对象,将这个脚本拖到这个对象上:

❤ 3-2、单例对象去读取数据保存下来

代码如下:

using System.Collections;
using System.Collections.Generic;
using System.IO;
using UnityEngine;public class DataManager : MonoBehaviour
{public static DataManager Instance;string m_JsonContent;//临时文档数据RootData m_JsonData;//临时接收JSON解析数据//数据保存到这个List里面,其他脚本就可以调用到了public List<StationAllInfo> m_StationsAllInfo = new List<StationAllInfo>();private void Awake(){Instance = this;DontDestroyOnLoad(gameObject);}private void Start(){ReadJSONData();}void ReadJSONData(){string pathstations = Application.streamingAssetsPath + "/地铁站.json";using (StreamReader SR = new StreamReader(pathstations)){m_JsonContent = SR.ReadToEnd();Debug.Log(m_JsonContent);SR.Close();SR.Dispose();//保存JSON数据m_JsonData = JsonUtility.FromJson<RootData>(m_JsonContent);}for (int i = 0; i < m_JsonData.GisJosnDatas.Count; i++){if (m_JsonData.GisJosnDatas[i].properties.LINE_ID != "")//剔除无用的信息,保存有用的信息{StationAllInfo item = new StationAllInfo();item.X = m_JsonData.GisJosnDatas[i].properties.X;item.Y = m_JsonData.GisJosnDatas[i].properties.Y;item.STACODE = m_JsonData.GisJosnDatas[i].properties.STACODE;item.S_NAME = m_JsonData.GisJosnDatas[i].properties.S_NAME;item.LINE_ID = m_JsonData.GisJosnDatas[i].properties.LINE_ID;//05 换成 5 (比如05号线 换成5号线)if (m_JsonData.GisJosnDatas[i].properties.LINE_ID.Substring(0, 1) == "0"){item.LINE_NAME = m_JsonData.GisJosnDatas[i].properties.LINE_ID.Substring(1, 1) + "号线";}else{switch (m_JsonData.GisJosnDatas[i].properties.LINE_ID)//对字母缩写的站名进行处理{case "fs":item.LINE_NAME = "房山线";break;case "bt":item.LINE_NAME = "八通线";break;case "yz":item.LINE_NAME = "亦庄线";break;case "cp":item.LINE_NAME = "昌平线";break;case "jc":item.LINE_NAME = "机场线";break;default:item.LINE_NAME = m_JsonData.GisJosnDatas[i].properties.LINE_ID + "号线";break;}}item.STYPE = m_JsonData.GisJosnDatas[i].properties.STYPE;m_StationsAllInfo.Add(item);}}}
}

❤ 3-3、在其他脚本中使用数据

我们新建一个UseData.cs脚本去使用数据:

using UnityEngine;public class UseData : MonoBehaviour
{private void Update(){//点击键盘W 显示数据if (Input.GetKeyDown(KeyCode.W)){ShowData();}}private void ShowData(){for (int i = 0; i < DataManager.Instance.m_StationsAllInfo.Count; i++){Debug.Log(DataManager.Instance.m_StationsAllInfo[i].X + " "+DataManager.Instance.m_StationsAllInfo[i].Y + " "+ DataManager.Instance.m_StationsAllInfo[i].STACODE + " "+ DataManager.Instance.m_StationsAllInfo[i].S_NAME + " "+ DataManager.Instance.m_StationsAllInfo[i].LINE_ID + " "+ DataManager.Instance.m_StationsAllInfo[i].LINE_NAME + " "+ DataManager.Instance.m_StationsAllInfo[i].STYPE + " ");}}
}

将这个脚本拖到场景中的对象上:

运行程序,敲击键盘W:

所有的值,都从单例对象DataManager的InStance的m_StationsAllInfo数组中读取出来了。

❤ 3-4、切换场景读取数据

我们新建两个场景:Index和Next,然后Index场景中的对象上挂载脚本ChangeScenes.cs脚本,代码如下:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.SceneManagement;public class ChangeScenes : MonoBehaviour
{// Start is called before the first frame updatevoid Start(){}// Update is called once per framevoid Update(){if (Input.GetKeyDown(KeyCode.Q)){SceneManager.LoadScene(1);}}
}

也就是切换场景,然后在Index场景中新建一个DataManager对象,将DataManager脚本拖上去。

然后Next场景中随便找一个对象挂载UseData脚本,场景中不需要创建DataManager对象

然后将两个场景加到Build Setting中:

运行程序:

切换到Next场景,DataManager对象也存在:

敲击键盘W:

所有的值,都从上一个场景中的DataManager对象的挂载脚本的单例对象DataManager.cs的InStance的m_StationsAllInfo数组中读取出来了。

❤ 四、后言

这是Unity使用单例的简单应用,最主要的几个知识点是;

1、对象切换场景不销毁
2、单例对象的静态属性
3、数据的保存
4、其他脚本用单例对象的数据的方法

结束,好好学习加油吧!

【Unity3D日常开发】应粉丝邀约,写一篇单例模式在Unity的实际应用,记得一键三连哦相关推荐

  1. 【Unity3D日常开发】Unity3D中实现计时器工具类-正计时、倒计时、暂停计时、加速计时

    推荐阅读 CSDN主页 GitHub开源地址 Unity3D插件分享 简书地址 我的个人博客 QQ群:1040082875 大家好,我是佛系工程师☆恬静的小魔龙☆,不定时更新Unity开发技巧,觉得有 ...

  2. 【Unity3D日常开发】Unity3D中打包WEBGL后读取本地文件数据

    推荐阅读 CSDN主页 GitHub开源地址 Unity3D插件分享 简书地址 我的个人博客 QQ群:1040082875 大家好,我是佛系工程师☆恬静的小魔龙☆,不定时更新Unity开发技巧,觉得有 ...

  3. 【Unity3D日常开发】Unity中的资源加载与文件路径

    推荐阅读 CSDN主页 GitHub开源地址 Unity3D插件分享 简书地址 我的个人博客 QQ群:1040082875 大家好,我是佛系工程师☆恬静的小魔龙☆,不定时更新Unity开发技巧,觉得有 ...

  4. 【Unity3D日常开发】时间类Time和DateTime的使用

    推荐阅读 CSDN主页 GitHub开源地址 Unity3D插件分享 简书地址 我的个人博客 QQ群:1040082875   大家好,我是佛系工程师☆恬静的小魔龙☆,不定时更新Unity开发技巧,觉 ...

  5. 【Unity3D日常开发】获取天气信息以及地方位置

    推荐阅读 CSDN主页 GitHub开源地址 Unity3D插件分享 简书地址 我的个人博客 QQ群:1040082875 大家好,我是佛系工程师☆恬静的小魔龙☆,不定时更新Unity开发技巧,觉得有 ...

  6. 【Unity3d日常开发】Unity3D中实现热力图、风向图、温度图效果

    推荐阅读 CSDN主页 GitHub开源地址 Unity3D插件分享 简书地址 我的个人博客 QQ群:1040082875 大家好,我是佛系工程师☆恬静的小魔龙☆,不定时更新Unity开发技巧,觉得有 ...

  7. 【Unity3D日常开发】Unity3D打包PC窗口化打包设置

    推荐阅读 CSDN主页 GitHub开源地址 Unity3D插件分享 简书地址 我的个人博客 QQ群:1040082875 大家好,我是佛系工程师☆恬静的小魔龙☆,不定时更新Unity开发技巧,觉得有 ...

  8. 【Unity3D日常开发】Unity3D项目的加密、激活思路分享

    推荐阅读 CSDN主页 GitHub开源地址 Unity3D插件分享 简书地址 我的个人博客 QQ群:1040082875 大家好,我是佛系工程师☆恬静的小魔龙☆,不定时更新Unity开发技巧,觉得有 ...

  9. 【Unity3D日常开发】更改Unity默认的脚本编辑器

    推荐阅读 CSDN主页 GitHub开源地址 Unity3D插件分享 简书地址 我的个人博客 QQ群:1040082875 大家好,我是佛系工程师☆恬静的小魔龙☆,不定时更新Unity开发技巧,觉得有 ...

  10. 【Unity3D日常开发】Unity3D中实现屏幕坐标和3维空间坐标的转化

    推荐阅读 CSDN主页 GitHub开源地址 Unity3D插件分享 简书地址 我的个人博客 QQ群:1040082875 大家好,我是佛系工程师☆恬静的小魔龙☆,不定时更新Unity开发技巧,觉得有 ...

最新文章

  1. R语言使用hexSticker包将lattice包可视化的结果转换为六角图(六角贴、六角形贴纸、lattice plot to hex sticker)
  2. 计算机专业知识考试 一,计算机专业知识试题(事业单位计算机专业知识考试试卷)(1)...
  3. C#-利用ZPL语言完毕条形码的生成和打印
  4. 【每日SQL打卡】​​​​​​​​​​​​​​​DAY 19丨行转列【难度中等】​
  5. 通过脚本设置Windows系统ip地址
  6. 一天一个小算法的学习之选择排序
  7. 嵌入式cc2530单片机ZigBee-题2控制led交替闪烁
  8. NX文件名与工程图名自动关联
  9. Visio 2013最新产品密钥分享,在安装时可以使用以下密钥:
  10. 谷歌浏览器网页打不开怎么办
  11. 售后服务场景智能调度解决方案
  12. AHCI,SATA,NVME
  13. 计算机毕设-学籍管理系统
  14. 八、码元、波特、速率和带宽
  15. python 源代码 macd双底 高 低_macd双底选股公式
  16. SQLite3 dll加载失败问题解决
  17. 1、MyBatis框架入门学习CRUD
  18. Qt通讯录(语音输入+发邮件+发短信+头像)
  19. app内嵌h5分享到小程序分享功能
  20. 用AutoHotkey写电脑屏幕监控软件

热门文章

  1. 经济适用型北京生活经验分享,80后北漂看过来
  2. 计算机网络和internet选项,详细教你电脑ie的internet选项在哪
  3. selenium中文文档_基于selenium的大麦网演唱会抢票程序
  4. python自动化:uiautomation、pyautogui操作会计记账系统(2)处理收支明细表
  5. luogu P1510 精卫填海
  6. 前馈神经网络初步了解
  7. Rayson API 框架分析系列之6: 客户端动态代理原理
  8. linux 内核rps,Linux内核软RPS实现网络接收软中断的负载均衡分发
  9. 用matlab求系统幅度频率响应,matlab频率响应
  10. php简单答题系统,念做个简易php选择题答题系统