【Unity3D游戏开发】之全局管理类的几种方式 (十六)
如何在Unity中实现全局管理类?由于Unity脚本的运行机制和面向组件编程(COP)的思想,实现起来和普通的方式略有差别。
第一种方式是使用静态类。适合存储一些全局的变量,如游戏当前关卡、玩家得分等。
实现方式和普通的C#静态类没有差别。注意使用静态类就没有必要继承MonoBehaviour了。
如果要实现复杂一些的全局控制,如切换游戏关卡等操作,更常用的方式是使用单例类。
单例类的实现又分为两种:
- 继承自MonoBehaviour的单例类
 - 纯C#的单例类
 
前者的优点是:
- 可以在Inspector中显示,便于赋值和查看变量等;
 - 可以利用MonoBehaviour的接口;
 - 可以使用Coroutine。
 - 等等。
 
缺点也很多,主流的观点是能不继承MonoBehaviour就不要继承。
纯C#的单例类
实现起来简洁,易于理解。
普通的写法,不考虑多线程
public class MyClass
{
private static readonly MyClass _instance = new MyClass();
public static Class Instance {
get {
return _instance;
}
} private MyClass() {}
}
线程安全的写法
检查两次。C#中使用lock关键字。
public class MyClass
{
private static volatile MyClass _instance;
private static object _lock = new object(); public static MyClass Instance
{
get
{
if (_instance == null)
{
lock(_lock)
{
if (_instance == null)
_instance = new MyClass();
}
}
return _instance;
}
} private MyClass() {}
}
基于MonoBehaviour的单例类
普通的写法
利用了Unity的运行机制,从Awake处获取Unity创建的对象作为单例。
注意在Unity中不要使用new来创建MonoBehaviour实例。
public class MyClass : MonoBehaviour
{
static MyClass _instance; void Awake () {
_instance = this;
} public static MyClass Instance {
get {
// 不需要再检查变量是否为null
return _instance;
}
}
}
持久化的写法
在多个场景中保存单例。又有两种方法。
第一种是使用DontDestroyOnLoad方法,告诉Unity不要销毁实例所在的对象,然后将脚本挂到某个GameObject上:
public class MyClass : MonoBehaviour
{
static MyClass _instance; void Awake () {
_instance = this;
// 防止载入新场景时被销毁
DontDestroyOnLoad(_instance.gameObject);
} public static MyClass Instance {
get {
return _instance;
}
}
}
上面这个方法有个弊端,必须要从挂载了这个单例的GameObject所在的场景启动,否则会找不到GameObject对象。但是开发和测试时我们经常会单独启动一个场景。
另一种方法会创建一个GameObject,然后将单例挂载到其上:
 public class MyClass : MonoBehaviour {
     static MyClass _instance;
     static public MyClass Instance
     {
         get
         {
             if (_instance == null)
             {
                 // 尝试寻找该类的实例。此处不能用GameObject.Find,因为MonoBehaviour继承自Component。
                 _instance = Object.FindObjectOfType(typeof(MyClass)) as MyClass;
                 if (_instance == null)  // 如果没有找到
                 {
                     GameObject go = new GameObject("_MyClass"); // 创建一个新的GameObject
                     DontDestroyOnLoad(go);  // 防止被销毁
                     _instance = go.AddComponent<MyClass>(); // 将实例挂载到GameObject上
                 }
             }
             return _instance;
         }
     }
 }
原文链接:http://segmentfault.com/a/1190000000645262
【Unity3D游戏开发】之全局管理类的几种方式 (十六)的更多相关文章
- 【转】【Unity】实现全局管理类的几种方式
		
本文原作者未知,转载自:http://blog.csdn.net/ycl295644/article/details/42458477 如何在Unity中实现全局管理类?由于Unity脚本的运行机制和 ...
 - Unity中实现全局管理类的几种方式
		
(搬运自我在SegmentFault的博客) 如何在Unity中实现全局管理类?由于Unity脚本的运行机制和面向组件编程(COP)的思想,实现起来和普通的方式略有差别. 第一种方式是使用静态类.适合 ...
 - Unity3D 游戏开发构架篇 ——角色类的设计与持久化
		
在游戏开发中,游戏角色占了很大的篇幅,可以说游戏中所有的内容都是由主角所带动.这里就介绍一下角色类的设计和持久化. 一.角色类应用场景和设计思想 游戏中的角色类型不一而足,有不同的技能,有不同的属性等 ...
 - Unity3D游戏开发从零单排(四) - 制作一个iOS游戏
		
提要 此篇是一个国外教程的翻译,尽管有点老,可是适合新手入门. 自己去写代码.debug,布置场景,能够收获到非常多.游戏邦上已经有前面两部分的译文,这里翻译的是游戏的最后一个部分. 欢迎回来 在第一 ...
 - Unity3D游戏开发初探—2.初步了解3D模型基础
		
一.什么是3D模型? 1.1 3D模型概述 简而言之,3D模型就是三维的.立体的模型,D是英文Dimensions的缩写. 3D模型也可以说是用3Ds MAX建造的立体模型,包括各种建筑.人物.植被. ...
 - [Unity3D]Unity3D游戏开发之飞机大战项目解说
		
大家好,我是秦元培,欢迎大家继续关注我的博客,我的博客地址是blog.csdn.net/qinyuanpei. 首先感谢大家对我博客的关注,今天我想和大家分享的是一个飞机大战的项目.这是一个比較综合的 ...
 - [Unity3D]Unity3D游戏开发《反对》说到游戏(上)——目标跟踪
		
朋友,大家好.我是秦培,欢迎关注我的博客.我的博客地址blog.csdn.net/qinyuanpei. 首先博主要自我反省,过了这么久才来更新博客,这段时间主要是在忙着写期末的作业,所以博主基本上没 ...
 - [Unity3D]Unity3D游戏开发之跑酷游戏项目解说
		
大家好,我是秦元培.我參加了CSDN2014博客之星的评选,欢迎大家为我投票,同一时候希望在新的一年里大家能继续支持我的博客. 大家晚上好.我是秦元培,欢迎大家关注我的博客,我的博客地址是blog.c ...
 - [Unity3D]Unity3D游戏开发之异步记载场景并实现进度条读取效果
		
大家好,我是秦元培.欢迎大家关注我的博客,我的博客地址是:blog.csdn.net/qinyuanpei.终于在各种无语的论文作业中解脱了,所以立即抓紧时间来这里更新博客.博主本来计划在Unity3 ...
 
随机推荐
- php课程---JavaScript与Jquery的区别
			
使用Jquery必须在页面内引入一个Jquery包 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" ...
 - Ajax 无刷新上传文件插件 uploadify 的使用
			
在表单中无法直接使用 Ajax 上传文件,解决的思路可以是使用插件无刷新地上传文件,返回文件上传后的地址,然后把该地址作为 Ajax 的参数传递给服务器端进行数据库处理.可以使用 uploadify ...
 - 【No.5 Ionic】修改 应用名,icon,启动界面
			
修改 应用名 直接 修改 config.xml中的name 修改icon 和 启动界面 在resources目录有个 icon.png 和 splash.png 文件,直接把文件覆盖执行重新生成命令 ...
 - asp.net mvc 控制器中操作方法重载问题 解决
			
Controllers: public ActionResult Index() { return View(db.GuestBooks.ToList()); } // // GET: /Guest2 ...
 - C#编程之委托与事件四(一)【转】
			
C#编程之委托与事件(一) 本文试图在.net Framework环境下,使用C#语言来描述委托.事件的概貌.希望本文能有助于大家理解委托.事件的概念,理解委托.事件的用途,理解它的C#实现方 ...
 - Sql Server批量删除指定表
			
--批量删除以test的表开头的表 declare @name varchar(50) while(exists(select * from sysobjects where name like te ...
 - php的spl_autoload_register函数的一点个人见解
			
这是一篇对spl_autoload_register()函数的个人简单介绍,有需要的同学可以参考,主要是讨论spl_autoload_register()函数所注册的函数的参数的个人一点迷惑. 废话不 ...
 - df 命令(转)
			
linux中df命令的功能是用来检查linux服务器的文件系统的磁盘空间占用情况.可以利用该命令来获取硬盘被占用了多少空间,目前还剩下多少空间等信息. 1.命令格式: df [选项] [文件] 2.命 ...
 - Adding Swagger to Web API project
			
Adding Swagger to Web API project. All source code for this series can be found here. When you creat ...
 - Velocity(10)——指令的转义
			
引用的转义使用"\",指令的转义也是使用"\".但是,指令的转义要比引用的转义复杂很多.例如: #if($foo) Go! #end $foo为true,输出G ...