Unity:创建新类实例时为空 [英] Unity: Null while making new class instance

查看:94
本文介绍了Unity:创建新类实例时为空的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我陷入了非常愚蠢的情况:我正在创建泛型类的新实例,但它返回奇怪的"null.

I got stuck in pretty dumb situation: I'm making new instance of the generic class but it returns "weird" null.

    Rule rule2 = new Rule(); // initiate the class
    Debug.Log(rule2); //1st debug
    rule2.RuleSetup(r: "CaughtEnough", li: 0); //setting up the parameters
    Debug.Log(rule2.rule); //2nd debug

第一次调试给了我

    null
    UnityEngine.Debug:Log(Object)

同时设置参数有效,第二次调试给了我

at the same time setting up the parameters works, and 2nd debug gives me

   CaughtEnough
   UnityEngine.Debug:Log(Object)

这应该在正确的类实例中.

which is what supposed to be in the proper class instance.

它给我带来的一个(到目前为止)问题是,如果我调用这个 Rule 类实例

One (only so far) issue that it is bringing to me is that if whitin this Rule class instance I call

   Invoke(rule, 0f);

它给了我 NullReferenceException 错误.但同时实际功能

it gives me the NullReferenceException error. But at the same time the actual function

   CaughtEnough();

工作正常且符合预期.

任何想法可能是问题的根源以及如何克服它?

Any ideas what could be the source of the problem and how to overcome it?

UPD 也按要求发布了 Rule 类的设置部分,尽管它很简单

UPD also posting setup part of Rule class, as asked, though it is straightforward

public class Rule : MonoBehaviour {

public string rule;

public int leftInt;
public Dictionary<string, int> leftDict;
public float countdown;

public int outcome;

public CatchManager catchMan;
public Net net;

// Use this for initialization
void Start () {
    RuleSetup();   
}

public void RuleSetup(string r = "NoRule", int li = 0, Dictionary<string, int> ld = null,  float cd = float.PositiveInfinity) {
    rule = r;
    leftInt = li;
    leftDict = ld;
    countdown = cd;
}
.....

推荐答案

public class Rule : MonoBehaviour{}
Rule rule2 = new Rule();

如果您从 MonoBehaviour 继承,则不能使用 new 关键字创建新实例.

You can't use new keyword to create new instance if you are inheriting from MonoBehaviour.

你应该得到这样的异常:

您正在尝试使用new"关键字创建 MonoBehaviour.这是不允许的.MonoBehaviours 只能使用添加组件().或者,您的脚本可以继承自ScriptableObject 或根本没有基类

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

如果您有 public class Rule {} 但您有 public class Rule : MonoBehaviour {},那么您的代码会起作用.

Your code would have worked if you had public class Rule {} but you have public class Rule : MonoBehaviour {}.

创建从 MonoBehaviour 派生的类的新实例:

Creating new instance of class that derives from MonoBehaviour:

示例类:

public class Rule : MonoBehaviour
{
    public Rule(int i)
    {

    }
}

如果你从 MonoBehaviour 继承,你应该使用 GameObject.AddComponentInstantiate 来创建它的新实例.

If you inherit from MonoBehaviour, you should either use GameObject.AddComponent or Instantiate to create new instance of it.

Rule rule2 = null;
void Start()
{
  rule2 = gameObject.AddComponent<Rule>();
}

OR

public Rule rulePrefab;
Rule rule2;
void Start()
{
    rule2 = Instantiate(rulePrefab) as Rule;
}

如果 Rule 脚本已经存在并附加到游戏对象,则您不需要创建/添加/实例化该脚本的新实例.只需使用 GetComponent 函数从它附加到的游戏对象中获取脚本实例.

If the Rule script already exist and is attached to the GameObject, you don't need to create/add/instantiate new instance of that script. Just use GetComponent function to get the script instance from the GameObject it is attached to.

Rule rule2;
void Start()
{
    rule2 = GameObject.Find("NameObjectScriptIsAttachedTo").GetComponent<Rule>();
}

当您从 MonoBehaviour 派生脚本时,您会注意到不能在构造函数中使用参数.

You will notice that you cannot use the parameter in the constructor when you derive your script from MonoBehaviour.

创建不是从 MonoBehaviour 派生的类的新实例:

Creating new instance of class that does NOT derives from MonoBehaviour:

示例类:(注意它不是从MonoBehaviour"

public class Rule
{
    public Rule(int i)
    {

    }
}

如果你继承MonoBehaviour,你应该使用new关键字来创建它的新实例.现在,如果需要,您可以在构造函数中使用参数.

If you don't inherit from MonoBehaviour, you should use the new keyword to create new instance of it. Now, you can use the parameter in the constructor if you want.

Rule rule2 = null;

void Start()
{
    rule2 = new Rule(3);
}

编辑:

在最新版本的 Unity 中,使用 new 关键字创建继承自 MonoBehaviour 的脚本的新实例可能不会给您错误,并且可能不是 null也是但是所有的回调函数都不会执行.其中包括AwakeStartUpdate 等功能.因此,您仍然必须按照本答案顶部的说明正确执行此操作.

In the latest version of Unity, creating new instance of a script that inherits from MonoBehaviour with the new keyword may not give you error and may not be null too but all the callback functions will not execute. These includes the Awake, Start, Update functions and others. So, you still have to do it properly as mentioned at the top of this answer.

这篇关于Unity:创建新类实例时为空的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆