统一:在创build新的类实例时为空

我陷入了非常愚蠢的情况:我正在做generics类的新实例,但它返回“怪异”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 

第一次debugging给了我

  null UnityEngine.Debug:Log(Object) 

同时设置参数工作,第二次debugging给我

  CaughtEnough UnityEngine.Debug:Log(Object) 

这是什么应该是在适当的类实例。

它给我带来的一个(只是迄今为止)的问题是,如果白我这个规则类实例我打电话

  Invoke(rule, 0f); 

它给了我NullReferenceException错误。 但同时也是实际的function

  CaughtEnough(); 

工作正常,如预期。

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

UPD也发布规则类的设置部分,如问,虽然它很简单

 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(); 

如果您从MonoBehaviourinheritance, 则不能使用new关键字来创build新的实例。

你应该得到的exception说

您正尝试使用“新”关键字创buildMonoBehaviour。 这是不允许的。 MonoBehaviours只能使用AddComponent()添加。 或者,您的脚本可以inheritanceScriptableObject或根本没有基类

如果您有public class Rule {}但是您有public class Rule : MonoBehaviour {}那么您的代码就可以工作。

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

示例类:

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

如果您从MonoBehaviour ,则应使用GameObject.AddComponentInstantiate来创build它的新实例。

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

要么

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

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

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

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



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

示例类:(请注意,它不是从“ MonoBehaviour

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

如果您MonoBehaviour ,则应该使用new关键字来创build它的新实例。 现在,你可以在构造函数中使用参数。

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

编辑

在最新版本的Unity中,使用new关键字创build从MonoBehaviourinheritance的脚本的新实例可能不会给您带来错误,也可能不为null 但所有callback函数都不会执行 这些包括AwakeStartUpdatefunction和其他function。 所以,你仍然必须正确地做这个答案的顶部提到。

只是一个跟进,我怎么最终这样做,为什么:

  1. 我不再inheritanceMonoBehaviourRule类,以避免跟踪gameObjects的创build和删除,这似乎是痛苦。

  2. 由于Invoke方法在generics类中不存在,所以我将其replace为reflection,如此处所述