Unity:在创建新的类实例

时间:2016-05-23 18:59:14

标签: c# unity3d 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)

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

它给我带来的一个(只是到目前为止)的问题是,如果在这个规则类实例中我打电话

   Invoke(rule, 0f);

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

   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;
}
.....

2 个答案:

答案 0 :(得分:18)

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

如果您继承自new无法使用MonoBehaviour关键字来创建新实例。

你应该得到

的异常
  

您正尝试使用&#39; new&#39;创建MonoBehaviour。关键词。   这是不允许的。 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的新类实例:

示例类:(请注意,它不是来自&#34; MonoBehaviour&#34;

public class Rule
{
    public Rule(int i)
    {

    }
}

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

Rule rule2 = null;

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

修改

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

答案 1 :(得分:2)

只是一个跟进,我最终如何做到这一点以及为什么:

  1. 我不再继承Rule中的MonoBehaviour类,以避免跟踪游戏对象的创建和删除,这似乎很痛苦。

  2. 由于Invoke方法在泛型类中不存在,我将其替换为反射,如所述here