(搬运自我在SegmentFault的博客)

如何在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;
}
}
}

Unity中实现全局管理类的几种方式的更多相关文章

  1. 【转】【Unity】实现全局管理类的几种方式

    本文原作者未知,转载自:http://blog.csdn.net/ycl295644/article/details/42458477 如何在Unity中实现全局管理类?由于Unity脚本的运行机制和 ...

  2. 【Unity3D游戏开发】之全局管理类的几种方式 (十六)

    如何在Unity中实现全局管理类?由于Unity脚本的运行机制和面向组件编程(COP)的思想,实现起来和普通的方式略有差别. 第一种方式是使用静态类.适合存储一些全局的变量,如游戏当前关卡.玩家得分等 ...

  3. Unity中资源动态加载的几种方式比较

    http://blog.csdn.net/leonwei/article/details/18406103 初学Unity的过程中,会发现打包发布程序后,unity会自动将场景需要引用到的资源打包到安 ...

  4. Unity协程(Coroutine)管理类——TaskManager工具分享

    博客分类: Unity3D插件学习,工具分享 源码分析   Unity协程(Coroutine)管理类——TaskManager工具分享 By D.S.Qiu 尊重他人的劳动,支持原创,转载请注明出处 ...

  5. Mybatis中使用association进行关联的几种方式

    这里以一对一单向关联为例.对使用或不使用association的配置进行举例.  实体类: @Data @ToString @NoArgsConstructor public class IdCard ...

  6. Struts2中获取HttpServletRequest,HttpSession等的几种方式

    转自:http://www.kaifajie.cn/struts/8944.html package com.log; import java.io.IOException; import java. ...

  7. javascript创建类的6种方式

    javascript创建类的7种方式 一 使用字面量创建 1.1 示例 var obj={}; 1.2 使用场景 比较适用于临时构建一个对象,且不关注该对象的类型,只用于临时封装一次数据,且不适合代码 ...

  8. 聊聊业务系统中投递消息到mq的几种方式

    背景 电商中有这样的一个场景: 下单成功之后送积分的操作,我们使用mq来实现 下单成功之后,投递一条消息到mq,积分系统消费消息,给用户增加积分 我们主要讨论一下,下单及投递消息到mq的操作,如何实现 ...

  9. 【Java8新特性】面试官问我:Java8中创建Stream流有哪几种方式?

    写在前面 先说点题外话:不少读者工作几年后,仍然在使用Java7之前版本的方法,对于Java8版本的新特性,甚至是Java7的新特性几乎没有接触过.真心想对这些读者说:你真的需要了解下Java8甚至以 ...

随机推荐

  1. 选择Netty的理由

    摘自:http://blog.csdn.net/u010154380/article/details/64443762 <Netty 权威指南>—— 选择Netty的理由 声明:本文是&l ...

  2. LIS与LCS的nlogn解法

    LIS(nlogn) #include<iostream> #include<cstdio> using namespace std; ; int a[maxn]; int n ...

  3. .Net HttpWebRequest 爬虫核心爬取

    1 爬虫,爬虫攻防 2 下载html 3 xpath解析html,获取数据和深度抓取(和正则匹配) 4 多线程抓取 熟悉http协议 提供两个方法Post和Get public static stri ...

  4. Python:asyncio模块学习

    python asyncio 网络模型有很多中,为了实现高并发也有很多方案,多线程,多进程.无论多线程和多进程,IO的调度更多取决于系统,而协程的方式,调度来自用户,用户可以在函数中yield一个状态 ...

  5. Unity学习(十三)场景优化之四叉树

    http://blog.sina.com.cn/s/blog_89d90b7c0102wyfw.html 四叉树是在二维图片中定位像素的唯一适合的算法.因为二维空间(图经常被描述的方式)中,平面像素可 ...

  6. Python 获取脚本路径以及脚本所在文件夹路径

    import os script_path = os.path.realpath(__file__) script_dir = os.path.dirname(script_path)

  7. 为产品接入微信支付解决方案(公司&个人)

    微信支付个人及公司的区别 H5支付:主要实现的效果是在非微信内网页中点击支付,拉起微信APP内的微信支付进行付款. APP支付:主要实现的效果是在APP内部点击支付,拉起微信APP内的微信支付进行付款 ...

  8. 外网连接Mysql云数据库

    购买好Mysql云数据库,这里是腾讯云 在管理中把外网地址开通,然后可以看到本云数据库的外网地址 注意:外网地址com到前面才是连接地址,冒号后面的10057是连接的端口号,可以看下面的连接语句 cm ...

  9. Maven项目已启动但是报异常访问webapp下所有资源都404

  10. PostgreSQL - raise函数打印字符串

    raise函数 在PostgreSQL中,该函数用于打印字符串,类似于Java中的System.out.println(),Oracle中的dbms_output.put_line(). 用法如下: ...