以前一直没有注意过关于在Unity中C#对象初始化的问题,今天遇到了一个问题一定要记录一下。
通常我们写一个MonoBehavior,你只需要声明一个Unity的组件而不需要立刻实例化,你就可以在函数中使用它。如下,不会出错,如果你只是把他拖到场景中使用而不是用脚本new它。
public class EntityTest : MonoBehaviour
{
public AnimationCurve _Curve;
void Start()
{
_Curve = new AnimationCurve();
Add();
}
public void Add()
{
_Curve.AddKey (1.0f, 1.0f);
}
}
但是如果你这样写,就会出错。这其实好理解,因为new新对象的时候没有写构造函数,初始化之后,_UnityCurve._Cureve 是null,可以理解。
[Serializable]
public class UnityCurve
{
public AnimationCurve _Curve;
public void Add()
{
_Curve.AddKey (1.0f, 1.0f);
}
}
public class EntityTest : MonoBehaviour
{
public AnimationCurve _Curve;
public UnityCurve _UnityCurve;
void Start()
{
_Curve = new AnimationCurve();
Add();
_UnityCurve = new UnityCurve();
_UnityCurve.Add();//这里报未实例化Object reference not set to an instance of an object
}
public void Add()
{
_Curve.AddKey (1.0f, 1.0f);
}
}
但是,最妙的一点来了,如果你在声明这个类的时候new了它,那么它惊奇的可以运行。
我尝试了几次发现,这个如UnityCurve的类必须是带有[Serializable]标签的。
总结一下,就是,如果你在声明的时候实例化一个含有unity组件的同时需要序列化的类,即使你没有为他的成员变量初始化,unity也会神奇的帮你自动初始化。
可以这样理解,[Serializable]的对象会在Unity界面中展示,为了可以展示出来unity自动帮你实例化了需要展示的组件。
[Serializable]
public class UnityCurve
{
public AnimationCurve _Curve;
public void Add()
{
_Curve.AddKey (1.0f, 1.0f);
}
}
public class EntityTest : MonoBehaviour
{
public AnimationCurve _Curve;
public UnityCurve _UnityCurve = new UnityCurve();
void Start()
{
_Curve = new AnimationCurve();
Add();
// _UnityCurve = new UnityCurve();
_UnityCurve.Add();
}
public void Add()
{
_Curve.AddKey (1.0f, 1.0f);
}
}
但是如果你在声明new之后,有new了一次,那么不好意思他等同于第二个脚本,Unity不会自动帮你初始化,_UnityCurve._Cureve 是null。只有在初始化的同时new一个对象才可以。
public class EntityTest : MonoBehaviour
{
public AnimationCurve _Curve;
public UnityCurve _UnityCurve = new UnityCurve();
void Start()
{
_Curve = new AnimationCurve();
Add();
_UnityCurve = new UnityCurve();
_UnityCurve.Add();
}
public void Add()
{
_Curve.AddKey (1.0f, 1.0f);
}
}
我不太清楚为什么又这种现象,希望大佬可以指点一二。