//一个表示村民的类 public class Villager : MonoBehaviour { public float maxSatiation = 10f; //最大饱食度 public float maxFatigue = 10f; //最大困倦值 const float minSatiation = 0.2f; //最小饱食度 const float minFatigue = 0.2f; //最小困倦值 private float satiation; //当前饱食度 private float fatigue; //当前困倦值 Coroutine currentCoroutine; //当前的状态(协程) //OnEnable在脚本被激活时立即执行 void OnEnable() { satiation = maxSatiation; //初始化饱食度,设为最大值 fatigue = maxFatigue; //初始化困倦值,设为最大值 StartCoroutine(Tick()); //开始“游戏循环”的协程 } //模拟“游戏循环”,类似MonoBehaviour的Update方法 IEnumerator Tick() { //每帧进行一次循环 while(true) { DecrePerFrame(satiation); //减少饱食度 DecrePerFrame(fatigue); //减少困倦值 //如果饿死了且当前的状态为空,开始“吃”协程,并定“吃”为当前状态 if(satiation < minSatiation && currentCoroutine == null) { currentCoroutine = StartCoroutine(Eat()); } //如果困死了,不管现在在干啥,直接开始“睡”协程,并定“睡”为当前状态 if(fatigue < minFatigue) { currentCoroutine = StartCoroutine(Sleep()); } //停顿一帧 yield return null; } } IEnumerator Eat() { //每帧吃一点,吃到饱为止 while(satiation < maxSatiation) { IncrePerFrame(satiation); yield return null; } //吃饱了,当前状态改回空 currentCoroutine = null; } IEnumerator Sleep() { //立即停止当前正在干的事(例如"吃") StopCoroutine(currentCoroutine); //如果没睡够,继续睡 while(fatigue < maxFatigue) { IncrePerFrame(fatigue); yield return null; } //睡够了,当前状态改为空 currentCoroutine = null; } }
public class MessageManager { Dictionary<string, Action<object[]>> messageDict; //存储消息以及相关联的监听者的字典 Dictionary<string object[]> dispatchCacheDict; //缓存区 public void Subscribe(string messageKey, Action<object[]> action) { if(messageKey in messageDict.Keys) { //Set action as a new subscriber of messageDict[messageKey]; //如果已经存在这个消息,那么给他加一个订阅者(监听者) } else { //Add new messageKey and new action to messageDict //否则,加入新的消息 } } public void Unsubscribe(string message) { messageDict.Remove(message); } public void Dispatch(string message, object[] args = null, bool addToCache = false) { if(addToCache) { //add message and args into cache //如果选择加入缓存,就将传入的所有事件加入缓存 } else { //trigger all the co-related actions in this message //否则,触发所有与该信息关联的所有 } } public void ProcessDispatchCache(string message) { //如果message存在于缓存中 if(message in dispatchCacheDict.Keys) { //执行缓存中与该信息关联的所有事件,随后从缓存中移除message Dispatch(message, dispatchCacheDict[message]); dispatchCacheDicr.Remove(message); } } }
参考资料:《Unity3D动作游戏开发实战》- 周尚宣