本文原作者未知,转载自:http://blog.csdn.net/ycl295644/article/details/42458477


如何在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中实现全局管理类的几种方式

    (搬运自我在SegmentFault的博客) 如何在Unity中实现全局管理类?由于Unity脚本的运行机制和面向组件编程(COP)的思想,实现起来和普通的方式略有差别. 第一种方式是使用静态类.适合 ...

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

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

  3. javascript创建类的6种方式

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

  4. 干货分享:小技巧大用处之Bean管理类工厂多种实现方式

    前言:最近几个月很忙,都没有时间写文章了,今天周末刚好忙完下班相对早点(20:00下班)就在家把之前想总结的知识点写出来,于是就有了这篇文章.虽无很高深的技术,但小技巧有大用处. 有时我们经常需要将实 ...

  5. JavaScript定义类的几种方式

    提起面向对象我们就能想到类,对象,封装,继承,多态.在<javaScript高级程序设计>(人民邮电出版社,曹力.张欣译.英文名字是:Professional JavaScript for ...

  6. Python 实现接口类的两种方式+邮件提醒+动态导入模块+反射(参考Django中间件源码)

    实现接口类的两种方式 方式一 from abc import ABCMeta from abc import abstractmethod class BaseMessage(metaclass=AB ...

  7. xml转json和实体类的两种方式

    本文为博主原创,未经允许不得转载: xml在http通信中具有较高的安全性和传输速度,所以应用比较广泛, 在项目中往往需要对xml,json和实体类进行相互转换,在这里总结一下自己所用到的一些方法: ...

  8. java创建类的5种方式

    1.使用new关键字 } → 调用了构造函数 这种方式,我们可以调用任意的构造函数(无参的和带参数的). 2.使用Class类的newInstance方法 } → 调用了构造函数 使用Class类的n ...

  9. python_106_创建类的两种方式

    class Foo(object): def __init__(self, name): self.name = name f = Foo("alex") print(type(f ...

随机推荐

  1. PHP-多域名单点登陆方案

    1.只是二级域名不同(比如a.xx.com, b.xx.com) 利用cookie, 设置domain为".xx.com"即可 2.多个本域名都不相同(比如www.a.com, w ...

  2. 直线的中点Bresenham算法的实现

    一.实验目的 1.掌握在MFC中搭建图形绘制的基本框架的方法: 2.将直线的中点Bresenham算法转化成可执行代码. 二.实验内容 1. 通过分析具体数据在中点Bresenham算法上的执行过程, ...

  3. 【LeetCode】135. Candy

    Candy There are N children standing in a line. Each child is assigned a rating value. You are giving ...

  4. 【LeetCode】51. N-Queens

    N-Queens The n-queens puzzle is the problem of placing n queens on an n×n chessboard such that no tw ...

  5. 【LeetCode】39. Combination Sum (2 solutions)

    Combination Sum Given a set of candidate numbers (C) and a target number (T), find all unique combin ...

  6. Device trees, Overlays and Parameters of Raspberry Pi

    Raspberry Pi's latest kernels and firmware, including Raspbian and NOOBS releases, now by default us ...

  7. 关于centos7中使用rpm方式安装mysql5.7版本后无法使用root登录的问题

    最近在centos7中通过rpm方式安装了最新版本的mysql-server 5.7 (mysql57-community-release-el7-7.noarch.rpm) ,发现安装成功后无法使用 ...

  8. C#--类之隐藏基类的成员

    using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.T ...

  9. tomcat多域名配置(转)

    TOMCAT的域名配置 现在很多的公司的网站都是用tomcat作为应用服务区的,可是对于初学者,8080端口号是如何去掉的,这些网站是如何和域名绑定到一起的呢?一个 tomcat是如何绑定多域名?并且 ...

  10. webservice快速入门-使用wsimport生成ws服务端(二)

    上个例子演示的是在当前项目下发布的Webservice Server,而实际应用中和Client是分离的,本文介绍两种客户端开发方式: 1.导出WebService服务端服务接口到jar包,客户端引入 ...