统一:在创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();
如果您从MonoBehaviour
inheritance, 则不能使用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.AddComponent
或Instantiate
来创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从MonoBehaviour
inheritance的脚本的新实例可能不会给您带来错误,也可能不为null
但所有callback函数都不会执行 。 这些包括Awake
, Start
, Update
function和其他function。 所以,你仍然必须正确地做这个答案的顶部提到。
只是一个跟进,我怎么最终这样做,为什么:
-
我不再inheritance
MonoBehaviour
的Rule
类,以避免跟踪gameObjects的创build和删除,这似乎是痛苦。 -
由于
Invoke
方法在generics类中不存在,所以我将其replace为reflection,如此处所述