相信学习Unity3D基础到一定时候,都会主动或被动的涉及到一些设计模式了。其实Unity开发是基于组件的开发,虽然也是使用C#开发语言,但是我们会发现那些C#里的好多经典设计模式似乎用起来都不是太友好,下面几天,作者本人将对一些模式进行学习笔记整理,文章也就暂归类到所谓的项目架构这个大帽子底下吧,
一、U3D简单状态机模式
如果我们需实现一个2d或3d游戏中的人物控制,可以让Hero 走、跑,相信不少人会这么写:
- if (Input.GetKey(KeyCode.D))
- {
- …设置方向向右..
- if (Input.GetKey(KeyCode.LeftShift))
- {
- ..移动..播放跑步动画..
- }
- else
- {
- ..移动..播放走路动画..
- }
- }
- else if (Input.GetKey(KeyCode.A))
- {
- …设置方向向左..
- if (Input.GetKey(KeyCode.LeftShift))
- {
- ..移动..播放跑步动画..
- }
- else
- {
- ..移动..播放走路动画..
- }
- }
这时还想加上跳跃功能,怎么办呢,跳跃时肯定不能执行走路的操作播放走路的动画啊,加一个bool判断吧,然后代码变成了这样:
- bool isJump = false;
- if (Input.GetKeyDown(KeyCode.W))
- {
- isJump = true;
- }
- if (Input.GetKey(KeyCode.D))
- {
- …设置方向向右..
- if (Input.GetKey(KeyCode.LeftShift))
- {
- if(!isJump)
- ..移动..播放跑步动画..
- else
- ..移动..播放跳跃动画..
- }
- else
- {
- if(!isJump)
- ..移动..播放走路动画..
- else
- ..移动..播放跳跃动画..
- }
- }
- else if (Input.GetKey(KeyCode.A))
- {
- …设置方向向左..
- if(!isJump)
- ..移动..播放跑步动画..
- else
- ..移动..播放跳跃动画..
- }
- else
- {
- if(!isJump)
- ..移动..播放走路动画..
- else
- ..移动..播放跳跃动画..
- }
- }
吐血 几升,可工作还得做,再加一个bool,再加判断!
- bool isCrouch = false;
- if (Input.GetKeyDown(KeyCode.S))
- {
- isCrouch = true;
- }
- bool isJump = false;
- if (Input.GetKeyDown(KeyCode.W)&&! isCrouch)
- {
- isJump = true;
- }
- if (Input.GetKey(KeyCode.D))
- {
- …设置方向向右..
- if (Input.GetKey(KeyCode.LeftShift))
- {
- if(!isJump&&! isCrouch)
- ..移动..播放跑步动画..
- else if(!isCrouch)
- ..移动..播放跳跃动画..
- else
- ..移动..播放蹲走动画..
- }
- else
- {
- if(!isJump&&! isCrouch)
- ..移动..播放跑步动画..
- else if(!isCrouch)
- ..移动..播放跳跃动画..
- else
- ..移动..播放蹲走动画.. }
- }
- else if (Input.GetKey(KeyCode.A))
- {
- …设置方向向左..
- if(!isJump&&! isCrouch)
- ..移动..播放跑步动画..
- else if(!isCrouch)
- ..移动..播放跳跃动画..
- else
- ..移动..播放蹲走动画..
- }
- else
- {
- if(!isJump&&! isCrouch)
- ..移动..播放跑步动画..
- else if(!isCrouch)
- ..移动..播放跳跃动画..
- else
- ..移动..播放蹲走动画..
- }
- }
这时候,我们友好的Unity3D引擎其实早想到了,当然本文也不是复述整理怎么画状态机了,随便一本基础引擎教程里也有状态机介绍讲解了,
所以,(有限状态机内容)跳过
下面整理结合有限状态机的C#设计模式,
重点也就是enum&switch组合
实现Player的走、跑、跳、攻击、防御功能
- public enum CharacterState
- {
- Idling = 0,
- Walking = 1,
- Running = 2,
- Jumping = 3,
- acting= 4,
- defending= 5,
- }
- public CharacterState heroState = CharacterState. Idling;
- void InputManager()
- {
- switch(heroState)
- {
- case CharacterState. Idling:
- …播放空闲动画..
- if…Input.GetKey –A,D.
- this. heroState = CharacterState. Walking;
- else if…Input.GetKey –w.
- this. heroState = CharacterState. Jumping;
- else if…Input.GetKey –H.;
- this. heroState = CharacterState. Running;
- else if…Input.GetKey –J.
- this. heroState = CharacterState. acting;
- else if…Input.GetKey –I.
- this. heroState = CharacterState. defending;
- break;
- case CharacterState. Walking:
- if…Input.GetKey –A,D.
- …CharacterController移动操作..
- else…Input.GetKeyUp – A,D…
- this. heroState = CharacterState. Idling;
- break;
- case CharacterState. Jumping:
- if(Input.GetKeyUp(KeyCode.W))
- …CharacterController移动操作..
- if(CharacterController.isGrounded)
- {
- this. heroState = CharacterState. Idling;
- }
- break;
- case CharacterState. acting:
- …播放攻击动画.
- chargeTime += Time.timeScale / Time.deltaTime;
- if(chargeTime>maxTime)
- {
- this. heroState = CharacterState. Idling;
- chargeTime = 0;
- }
- break;
- case CharacterState. defending:
- …播放防御动画.
- if(Input.GetKeyUp(KeyCode.I))
- this. heroState = CharacterState. Idling;
- break;
- }
- }
这样可以实现一个简单的状态机,所有状态操作都被整合在一起,原理是轮询当前的状态,处理当前状态操作,接受玩家输入来转换状态。
当然,有明显缺点,所以姑且成为简单状态机模式,下回对此模式进行改进,升级为状态模式