Unity:创建新类实例时为Null



我陷入了一个非常愚蠢的境地:我正在创建泛型类的新实例,但它返回了"怪异"的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)

同时设置参数工作,第二次调试给了我

CaughtEnough
UnityEngine.Debug:Log(Object)

这是在适当的类实例中应该有的。

它给我带来的一个(迄今为止唯一的)问题是,如果在这个Rule类实例中,我调用

Invoke(rule, 0f);

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

CaughtEnough();

工作得很好,正如预期的那样。

有什么想法吗?问题的根源是什么?如何克服它?

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

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关键字创建新实例。

你应该得到一个异常,说

您正试图使用"new"关键字创建MonoBehavior。这是不允许的。MonoBehaviours只能使用添加AddComponent()。或者,您的脚本可以从ScriptableObject或根本没有基类

如果您有public class Rule {}但有public class Rule : MonoBehaviour {},您的代码就会工作。

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

示例类:

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

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

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

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

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

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

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



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

示例类:(注意,它不是从"MonoBehaviour"派生的

public class Rule
{
public Rule(int i)
{
}
}

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

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

编辑

在最新版本的Unity中,使用new关键字创建从MonoBehaviour继承的脚本的新实例可能不会出错,也可能不是null,但所有回调函数都不会执行。其中包括AwakeStartUpdate等功能。所以,你仍然必须按照答案顶部提到的正确操作

只是一个后续,我是如何完成的以及为什么:

  1. 我不再从MonoBehaviour继承Rule类,以避免跟踪游戏对象的更改和删除,这似乎是一种痛苦。

  2. 由于Invoke方法在泛型类中不存在,我用反射代替了它,如所述

相关内容

  • 没有找到相关文章