unity3d - new 不出的单例

原创 2015年11月19日 11:16:51

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


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





MonoBehaviour的单例模式

我们有一个继承自MonoBehaviour的类是用来做对象交互动作的,想做成单例的,写成通用的方法报错。 private static Communication instance;     pu...

Untiy3D开发小贴士(一)OnEnabled与OnDisabled

设某个组件为NewBehaviour OnEnabled被调用的情况: 1、GameObject添加组件的时候,即AddComponetNewBehaviour> ; 2、包含NewBehaviou...

Unity编辑器类中的问题

今天写编辑器类遇见一个问题。 [CanEditMultipleObjects()] [CustomEditor(typeof(DialogueBox), true)] public cl...

Unity学习一之(初学脚本 MonoBehaviour类 )

在看到Unity界面的第一眼,突然感觉到无穷的压力.全英文界面对于我这种初学者而且英文渣得一#的人实在是有点吃不消.用了一天的时间了解了Unity的工具栏的使用以及各种按键的作用,同时刷完了我第一个U...
  • leo_wc
  • leo_wc
  • 2015年01月13日 13:00
  • 1042

游戏类实例为null

今天在开发的过程中出现了一个,就是游戏对象我初始化了,并且new了,但是查不来的时候对象是null,这是我遇到问题 查找到很多的地方,最后的原因是实例化的这个类继承了MonoBehavior类,通过...

Kinect V2深度数据用OpenCV显示

持续维护地址:http://guoming.me/kinect2-depth-opencv 这次带来深度数据的显示,

Unity3D C# List数据类型使用

List类是  ArrayList 类的泛型等效类。 该类使用大小可按需动态增加的数组实现  IList 泛型接口。  泛型的好处: 它为使用 c#语言编写面向对象程序增加了极大的效力和灵活性。不会...
  • merryken
  • merryken
  • 2014年03月31日 11:12
  • 11690

Unity3d 单例对象池

原创 单例模式 初学者很容易搞晕,为啥有2种写法,这里顺带着写一下,不是本章的要点。 首先,是继承自MonoBehaviour的单例,需要使用U3D组件和功能可以用这种单例。理解U3D本身单例...

unity3d学习笔记(六)--单例脚本和单例类

要写到英雄与怪物之间的攻击交互了,在这之前,有必要插播一下单例脚本和单例类,因为我的交互都是在单例脚本上交互的。这样有什么好处呢,降低耦合度,这是任何一个程序员都关注的事情,编程也是一门艺术吗,试想想...

unity3d学习笔记(七)--利用单例脚本实现英雄与怪物的攻击与受击

我们的世界有了怪物,那么你怎么忍心不去虐他们一下,勇士,挥舞你的大刀,去砍他们吧。呃,有点血腥,少儿不宜。 如上一篇所说,我这里的交互全是在单例脚本中实现的。单例脚本负责事件的分发和传递,Hero和M...
  • lzhq1982
  • lzhq1982
  • 2013年10月14日 10:52
  • 11499
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:unity3d - new 不出的单例
举报原因:
原因补充:

(最多只允许输入30个字)