首先你应该明确这个规定的限制范围:只是针对MonoBehaviour的派生类,为什么,因为其他的类就是正常的C#类,你在里面写Awake方法,就是个普通的叫Awake的方法,并不会被自动调用。
原因也很简单,MonoBehaviour代表的是一个组件,在Unity3D里面组件是必须依附于GameObject存在的,对于这种类你永远都不会使用new来创建一个实例,而是使用AddComponent或GetComponent方法来获取。Unity3D的开发人员并不想让你知道这个类是具体什么时候new出来的,你只要关心我想要的时候能够拿到一个引用就可以了。
你引用的这条限制,在我理解来看实际是说:“MonoBehaviour的生命周期并不是从构造函数开始的,而是从Awake开始的”。在构造函数中初始化变量,一般来说目的是将类的状态设置到一个“初始状态”,对于MonoBehaviour来说,你相当于在这个类的生命周期之外设定了它的状态,此时这个代码就是不严谨的,而应该放在Awake里面去。
因此,在我的理解来看,你应该避免做的是在构造函数里设定任何跟类的内部状态有关的事情。举例来说,如果我在做一个计数器,有一个count变量,这个变量就明显是内部状态,count=0这句话就应该放在Awake中。另外,程序不是一个类组成的,在实际工程中,有时候一个类的状态依赖于其他类的状态,你举例的GUI.Button方法可以看做设定了GUI类的内部状态,这个代码也不应该放在构造函数中(这个例子不好之处在于GUI类的方法只能在onGUI中调用,不能在任何其他地方,包括Awake中使用,如果换用一个其它全局变量可能更能说明问题)
另一方面,我们可以做一些不牵扯到类的内部状态的事情,举个例子:
class A{
public int count;
public int price;
public string name;
}
class AComponent : MonoBehaviour{
A inner;
public int Count {get{return inner.count;} set{ inner.count = value;}}
public int Price {...}
public String Name {...}