其他分享
首页 > 其他分享> > 《Unity3D动作游戏开发实战》笔记及扩展2.1

《Unity3D动作游戏开发实战》笔记及扩展2.1

作者:互联网

2.1.1. 使用协程分解复杂逻辑

//一个表示村民的类
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;
	}
}

2.1.2. 自定义的插值公式

2.1.3. 消息模块的设计

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);
		}
	}
}

2.1.4. 模块间的管理与协调

参考资料:《Unity3D动作游戏开发实战》- 周尚宣

标签:Unity3D,缓存,协程,message,currentCoroutine,动作游戏,2.1,null,public
来源: https://blog.csdn.net/qq_44671773/article/details/117419406