可能习惯了写单例的朋友,或者常规的单例模式 会这样做

private static Single instance;
public static Single Instance(){
if (instance == null) {
instance = new Single();
}
return instance;
}  

但是当你继承了MonoBehaviour 你就要小心了如果你这样写

 public class Single : MonoBehaviour {
private static Single instance;
public static Single Instance(){
if (instance == null) {
instance = new Single();
} return instance;
} }

你会发现instance 永远为空的(即使走了这一步的instance = new Single();) 而且你回收到如下的警告

You are trying to create a MonoBehaviour using the 'new' keyword.  This is not allowed.  MonoBehaviours can only be added using AddComponent().  Alternatively, your script can inherit from ScriptableObject or no base class at all

那么问题来了,第一个我们应该如何使用继承了MonoBehaviour 的单例,第二个为何new了 instance 却等于 null

第一个问题很简单,对MonoBehaviour 生命周期有了解的都知道应该如下做

 public class Single : MonoBehaviour {

 private static Single instance;

 void Awake(){
instance = this;
} public static Single Instance(){
return instance;
}
}

之所以放在Awake 是因为Awake是所有mono 调用start方法之前都会被调用的,这样可以避免某些调用的时候instance=null的情况

第二个查了一通untiy的文档得出的结论是

因为所有从MonoBehaviour继承过来的类,unity都会自动创建实例,并且调用被重载的方法,如我们经常用到的Awake, Start, Update等。

Unity does not allow you to instantiate anything inheriting from the MonoBehaviour class using the new keyword. This seems a bit odd, until you consider what the MonoBehaviour class is.

MonoBehaviours are scripts that are attached to an object in the scene, and run in the scene as long as the object they are attached to is active. MonoBehaviours HAVE to be attached to something, or they won't be able to function properly. When you use new, you are basically saying: "Please make one of these, store it somewhere, and give me a link to it". What you don't tell it is: "Also attach it to the place I'm calling it from". The reason this isn't done is because the concept of attaching things to objects is Unity specific, while the keyword new is general to C#, and so has no concept of Unity constructions - it can't physically do this.

So how DO you specify what to attach it to? Well, Unity provides it's own method for this - namely GameObject.AddComponent(). What this does is create a new script, of type T, and add it to the specified GameObject. So, if you have a GameObject called obj and a script called MyScript, you can dynamically add the script to your object by, instead of doing this:

  1. MyScript script = new Script();

Which would, hypothetically, give you a script floating in space, not attached to anything, you can do this:

  1. MyScript script = obj.AddComponent<MyScript>();

This will add a new MyScript component to obj, and then will set the variable script to that component, so you can then access it.

Hopefully, you can see why this issue occurs, and what you can do to solve it, now.

总结一下就是: 这是unity的规则,如果你继承了MonoBehaviour 请使用unity的规则来进行实例化这个类,至于想通过c# 的new 去实例化mono 的类是不被允许的。

好吧~~规则如此我也无法解释了,就跟你无法解释很多的公式一个道理。也许有朋友理解比较深,可以教我一下,还有一点就是为何当我们去new了以后unity只是给了一个警告而已,却并没有给出error级别的log,这也变相的告诉我们开发者,要把所有的warn级别的也清掉了。否则可能导致意想不到的bug

unity3d - new 不出的单例的更多相关文章

  1. Swift百万线程攻破单例(Singleton)模式

    一.不安全的单例实现 在上一篇文章我们给出了单例的设计模式,直接给出了线程安全的实现方法.单例的实现有多种方法,如下面: class SwiftSingleton { class var shared ...

  2. 【Spring源码分析】非懒加载的单例Bean初始化过程(上篇)

    代码入口 上文[Spring源码分析]Bean加载流程概览,比较详细地分析了Spring上下文加载的代码入口,并且在AbstractApplicationContext的refresh方法中,点出了f ...

  3. Spring源码分析:非懒加载的单例Bean初始化过程(上)

    上文[Spring源码分析]Bean加载流程概览,比较详细地分析了Spring上下文加载的代码入口,并且在AbstractApplicationContext的refresh方法中,点出了finish ...

  4. Unity3D中可中途释放的单例

    Unity3D中可中途释放的单例 使用静态类,静态变量的坏处是从程序加载后就一直占用内存,想要释放比较麻烦,可是之前使用的单例,没有提供释放的方法,那是不是也同静态的一样直到程序结束菜释放?那单例的好 ...

  5. unity3d中设计模式的学习<一>:泛型单例

    单例是游戏开发中比较常见的设计模式,虽然针对的功能不同,但是有一些功能还是共有的,代码也不少,如果能放在一个基类里面是最好不过了,但是单例里需要有个instance功能来返回当前对象,所以这个功能必须 ...

  6. 【转】Unity3d的单例及场景间的数据传递

    http://blog.csdn.net/zy19940906/article/details/47724387  单例是场景间切换时传递数据的最常见的方式之一,在unity中,很多方法被封装,有时候 ...

  7. [Android面试题-7] 写出一个Java的Singleton类(即单例类)

    1.首先明确单例的概念和特点: a>单例类只能有一个实例 b>单例类必须自己创建一个自己的唯一实例 c>单例类必须为其他所有对象提供这个实例 2.单例具有几种模式,最简单的两种分别是 ...

  8. 如何写出面试官欣赏的Java单例

    单例模式是一种常用的软件设计模式.在它的核心结构中只包含一个被称为单例的特殊类.通过单例模式可以保证系统中一个类只有一个实例. 今天我们不谈单例模式的用途,只说一说如果在面试的时候面试官让你敲一段代码 ...

  9. Unity Singleton 单例类(Unity3D开发之二十)

    猴子原创,欢迎转载.转载请注明: 转载自Cocos2Der-CSDN,谢谢! 原文地址: http://blog.csdn.net/cocos2der/article/details/47335197 ...

随机推荐

  1. TTS多音字问题

    今天在CSDN上找到了解决方案,终于解决了多音字问题.   Text1.Text = "<pron sym='jia 3'> 贾</pron>宝玉,商<pron ...

  2. docker swarm compose

    swarm docker run swarm --help compose curl -L https://github.com/docker/compose/releases/download/1. ...

  3. linux shell 使用总结

    为什么执行脚本要使用./ +脚本名来执行脚本理解:因为如果直接使用脚本名,那么linux 系统会去path 路径查找如去/bin usr/bin 等查找,这个时候会找不到这个脚本名字,就会报错.使用. ...

  4. MSClass 和setInterval 的并发,ajax定时有采集信息滚动显示

    setTimeout 用于延时器,只执行一次. setInterval:用于多次执行. //****************************************** 项目中引用到jquer ...

  5. Spring学习 Ioc篇(二 )

    5.spring依赖注入的方式 方法一:使用构造器方式进行注入 1.dao的类和接口 package com.cvicse.dao.impl; import com.cvicse.dao.Person ...

  6. My Package

    一.新建一文件夹,名称为MyBase,存放Java的基本类. 二.在MyBase包中创建基本类Base.java. package MyBase; public class Base { public ...

  7. oracle控制文件丢失恢复

    在学习群里有个同学误删除了控制文件,于是我也把自己数据库的控制文件删除了,看看能不能进行恢复,以下是整个实验的过程~~在做之前,先看看控制文件的备份方式:1.生成可以重建控制文件的脚本.2.备份二进制 ...

  8. Windows下PHP版本选取

    1. 下载地址 http://windows.php.net/download/ 2. PHP大版本 PHP4:由于太古老.对OO支持不力已基本被淘汰. PHP5:分为三个分支——PHP5.2之前的版 ...

  9. Blackfin DSP(四):BF533 EBIU之SDRAM

    BF533的SDRAM控制器最大支持128M bytes的SDRAM空间:总线宽度可以配置为4位.8位.16位.处理器与SDRAM的连线包括数据总线D[0:15].地址总线A[1:19].SDRAM刷 ...

  10. 48. Remove Duplicates from Sorted List && Remove Duplicates from Sorted List II

    Remove Duplicates from Sorted List Given a sorted linked list, delete all duplicates such that each ...