Unity 角色的状态管理

学习南梦宫的开发实例 状态管理的 一种写法笔记

一、状态管理的流程

       状态管理主要有以下三个工作

             (1) 迁移 :决定了状态该如何变化;

             (2)初始化 :仅在每次状态迁移时执行一次;

             (3)执行:是每帧都会对各个状态进行的处理;

               Unity 角色的状态管理_第1张图片 重点在于一开始执行“迁移检测”。

二、实际游戏中使用的状态管理的代码示例如下

public enum STATUS {
	NONE = -1,

	STAND = 0, // 站立

	DECLINE, //下降

	ACCELERATE, //加速

	ROTATE, //旋转

	LEFT, //左

	RIGHT, //右

}

public STATUS status = STATUS.NONE; //现在的状态

public STATUS next_status = STATUS.NONE; //下一次迁移的状态

public float step_timer = 0.0f; //统计迁移经过时间

public void Start () {

	//初始化
	this.next_status = STATUS.STAND;
}

public void Update () {

	// (a)统计迁移到当前状态后经过的时间
	this.step_timer += Time.deltaTime;

	// ---------------------------------------------------------------- //
	// (b)判断检测是否迁移到下一个状态
	if (this.next_status == STATUS.NONE) {

		switch (this.status) {

			case STATUS.NONE:
				{
					this.next_status = STATUS.STAND;
				}
				break;

			case STATUS.STAND:
				{
					//按下左  Shift 键 开始下落
					if (Input.GetKeyDown (KeyCode.LeftShift)) {
						this.next_status = STATUS.DECLINE;
					}

				}
				break;

			case STATUS.DECLINE:
				{
					//下落状态下,可以迁移的状态
					if (Input.GetKeyDown (KeyCode.W)) {
						this.next_status = STATUS.ROTATE;
					}

					if (Input.GetKeyDown (KeyCode.S)) {
						this.next_status = STATUS.ACCELERATE;
					}

					if (Input.GetKeyDown (KeyCode.A)) {
						this.next_status = STATUS.LEFT;
					}

					if (Input.GetKeyDown (KeyCode.D)) {
						this.next_status = STATUS.RIGHT;
					}
				}
				break;

			case STATUS.ACCELERATE:
				{

				}
				break;

			case STATUS.ROTATE:
				{

				}
				break;

			case STATUS.LEFT:
				{

				}
				break;

			case STATUS.RIGHT:
				{

				}
				break;

		}
	}

	// ---------------------------------------------------------------- //
	//(c)状态迁移时的初始化
	if (this.next_status != STATUS.NONE) {

		switch (this.next_status) {

			case STATUS.STAND:
				{
					Debug.Log ("播放站立动画");
				}
				break;

			case STATUS.DECLINE:
				{

				}
				break;

			case STATUS.ACCELERATE:
				{

				}
				break;

			case STATUS.ROTATE:
				{

				}
				break;

			case STATUS.LEFT:
				{

				}
				break;

			case STATUS.RIGHT:
				{

				}
				break;

		}

		//(d)更新 现在的状态
		this.status = this.next_status;
		this.next_status = STATUS.NONE;
		this.step_timer = 0.0f;

	}

	// ---------------------------------------------------------------- //
	//(e)各个状态的执行处理
	switch (this.status) {

		case STATUS.STAND:
			{

			}
			break;

		case STATUS.DECLINE:
			{

			}
			break;

		case STATUS.ACCELERATE:
			{

			}
			break;

		case STATUS.LEFT:
			{

			}
			break;

		case STATUS.RIGHT:
			{

			}
			break;

		case STATUS.ROTATE:
			{

			}
			break;

	}

}

       上述代码中说明大致流程 : this.status 指现在的状态,  this.next_status 表示下一次迁移的状态。当  this.next_status 的值 为 STATUS.NONE时,将不发生迁移。

             (a)首先,更新迁移到当前状态后已经经过的时间。比如在“经过一定的时间后再迁移到其他状态”等情况下,会用到这个值。

             (b)然后执行状态迁移判断,之所以要判断 this.next_status 是否等于STATUS.NONE,是为了能让外部对状态的迁移进行控制。

             (c)状态发生迁移后,开始新状态的初始化处理。

             (d)在初始化的最后,更新当前状态的  this.status 的值,清空 this.next_status 的值。注意这里如果没有把  this.next_status 清空成 STATUS.NONE ,将导致下一帧继续发生迁移。最后将状态前后经过的时间设置为0.

             (e)最后,执行各个状态。

 

三、小结

       通过这个例子,我们可以很好的理解“状态管理”的基本思路。如果读者向更一步了解状态的相关运用,可以试着 敲一下代码,并添加动能,比如 旋转:

(1) 旋转结构

	//旋转状态的数据结构
	public struct ActionRotate {
		public STATUS prevoius_status; //旋转前的状态

		public bool is_key_released; //旋转后,是否松开w键?

	}

	public ActionRotate action_rotate; //旋转行为

(2) 初始化

	case STATUS.ROTATE:
		{
			this.action_rotate.is_key_released = false;
			this.action_rotate.prevoius_status = this.status;
	
			Debug.Log ("初始化 旋转  比如:调用协程旋转方法 或者 播放旋转动画");
		}
		break;

(3) 执行处理

	case STATUS.ROTATE:
		{
	            // 旋转中松开按键处理
			do {

				if (Input.GetKeyUp (KeyCode.W)) {
					this.action_rotate.is_key_released = true;
					Debug.Log ("停止 旋转或者 动画");
					break;
					}

				if (this.action_rotate.is_key_released) {
					this.status = STATUS.DECLINE;
					break;
					}
			} while (false);
		}
		break;

 

你可能感兴趣的:(Unity日常笔记)