先总结一下今天的收获:在一个脚本类中对其成员变量进行初始化时,什么时候在Awake()中,什么时候在Start()中是有讲究的。
1)当成员变量会被外部脚本引用时,尤其是该成员变量是一个自己定义的非脚本类必须用构造函数初始化的时候。并且,被外部脚本引用指的是 “引用该变量的内部成员函数或属性被外部函数调用的时候”,该成员变量应该在Awake函数中进行初始化。
2)如果该成员变量只在自身所在的脚本类被引用时,则应该在Start函数中进行初始化。
今天遇到的第一个坑就是因为没有注意以上两点。我在Start函数中使用构造函数初始化了一个Poker类,但是这个类的实例在自身的公有方法中,被外部其他脚本调用了。这倒不是最重要的,因为之前我遇到过一次。重要的是:在Update()函数中拷贝预设体,其Awake()函数在当前帧的Update中就会被立即调用,但是Start()函数则会在在下一帧执行。
第二个坑是这样的:我将一个共有函数绑定到NGUI的UIButton脚本里的OnClick事件中作为事件处理函数,在这个共有函数中使用了两个if语句,则当事件触发时函数不会被执行,但是我改为 if(){} else if(){}就可以执行,明明相同的逻辑却又不一样的结果,让人匪夷所思呀。
第三个坑是:在NGUI中有一个大坑,就是创建NGUI中的游戏对象时,如果你使用Instantiate()函数,创建的控件会非常的大,但是使用NGUITools.AddChild()函数时生成的控件大小就会正好合适。【原因还不祥】
一下我将之前遇到的问题说一下,也是空引用异常的问题,和第一个坑差不多,其实也不能说是坑,而是自己对自己的逻辑没有考虑清楚,将各种类的相互引用考虑进来就会发生问题的。
之前已经实现了跑道的动态生成,今天要是实现的是在动态生成的跑道上的路点处随机产生提前准备好的陷阱预设体。
遇到的问题:因为之前在动态生成跑道时,顺便实现了另一个类,路点管理器类。我们的陷阱就要在路点附近生成,所以,利用之前跑道上自带的路点是很好的选择。但是,将道具生成器脚本类顺利加入到之前的代码还是比较繁琐的。因为封装的函数太依赖于动态生成跑道和记录游戏角色附近的路点这两个逻辑,所以必须再次明白之前是如何设计生成跑道和如何计算路点的,并且这还不是最重要的。
最重要的问题是:在ElementsGenerator脚本类中维护一个List<Transform> waypointList来负责在当前跑道上所有路点处生成障碍物、陷阱。由于是脚本类,所以并不存在构造函数这个概念,所以我就在 Awake()这个函数中创建waypointList,但是我明明已经创建了该列表,但是总是报空引用这样的错误。我百思不得其解,最后,我明白了为什么???
主要问题是:我在PlayMove这个脚本类中的Awake()函数中对作为单例出现在整个游戏场景中的跑道生成器进行了初始化:raceTrackGenerator.Init () 这里这个函数的初始化是在 waypointList之前执行的【不同脚本中的Awake函数执行顺序我不知道如何确定】。主要问题的产生就是因为跑道生成器初始化时需要调用ElementsGenerator脚本类的GetWaypointList()函数,但是此时该函数必须的waypointList还没有创建出来。