在做战斗的时候,为了避免相互引用造成代码混乱,需要使用消息系统(Messenger)来broadcast掉血的消息,而listener是在awake中增加的。
奇怪的事出现了,直接加载运行这个场景的时候很正常,但是一旦从另一个场景 进入的时候,问题就出现了,一大片的
“BroadcastException: Broadcasting message "barbarian_03_01LoseHealth" but no listener found. Try marking the message with Messenger.MarkAsPermanent.”
也就是说消息没有了,找不到了。但我明明在awake中添加了listener,执行到update中broadcast的时候肯定有啊。
不管,先 MarkAsPermanent 。能用,但是这些永久消息,设为永久以后会造成混乱啊。
再看messenger 代码:
public void OnLevelWasLoaded(int level) { Messenger.Cleanup(); }
每次load一个新level 的时候,都会清理Messenger,删除不是永久的部分。
如果是删除了的话,那么OnlevelWasLoaded 就是执行在Awake之后了。
把add listener放到 start中,运行,可以诶。
那么猜测 执行顺序 awake -> onlevelwasloaded -> start
google自杀一记,结果
http://forum.unity3d.com/threads/onlevelwasloaded-before-or-after-awake-start.57409/
http://answers.unity3d.com/questions/59873/onlevelwasloaded-called-before-awake.html
结果全部是说 onlevelwasloaded -> awake -> start 。
于是自己做了个验证:
scene1:
using UnityEngine; using System.Collections; public class Loadlevel : MonoBehaviour { void Awake() { DontDestroyOnLoad(this.gameObject); //!!! Debug.Log(Application.loadedLevel + " awake"); } void Start() { Debug.Log(Application.loadedLevel + " start"); Application.LoadLevel("Scene2"); } void Update() { Debug.Log(Application.loadedLevel+" update"); } public void OnLevelWasLoaded(int level) { Debug.Log("On level was loaded " + level); } }
scene2:
using UnityEngine; using System.Collections; public class Loadlevel1 : MonoBehaviour { void Awake() { Debug.Log(Application.loadedLevel + " awake"); } void Start() { Debug.Log(Application.loadedLevel + " start"); } void Update() { Debug.Log(Application.loadedLevel+" update"); } void OnLevelWasLoaded(int level) { Debug.Log("OnLevelWasLoaded "+ level); } }
执行结果:
显而易见了。
后来想想,google到的那些结果不是最新的,可能是以前版本和现在版本的执行顺序不一样所致。