笔者介绍:姜雪伟,IT公司技术合伙人,IT高级讲师,CSDN社区专家,特邀编辑,畅销书作者,国家专利发明人;已出版书籍:《手把手教你架构3D游戏引擎》电子工业出版社和《Unity3D实战核心技术详解》电子工业出版社等。
CSDN视频网址:http://edu.csdn.net/lecturer/144
下面给读者讲解在游戏开发中经常使用的FSM有限状态机的实现,有限状态机在状态切换中使用的非常多,比如足球游戏,动作游戏等。角色在游戏场景中经常需要动作的切换,比如Idle,Run,Attack,Skill等,这些技能状态之间的切换,我们通常会使用FSM去处理。我们在游戏中将动作切换和技能切换放在一起使用FSM处理,下面通过代码的方式给读者进行封装处理:
public interface EntityFSM { bool CanNotStateChange{set;get;} FsmState State { get; } void Enter(Ientity entity , float stateLast); bool StateChange(Ientity entity , EntityFSM state); void Execute(Ientity entity); void Exit(Ientity Ientity); }
先定义一个抽象类用于具体状态的实现,游戏中的具体状态,我们通过枚举的方式定义如下:
public enum FsmState { FSM_STATE_FREE, FSM_STATE_RUN, FSM_STATE_SING, FSM_STATE_RELEASE, FSM_STATE_LEADING, FSM_STATE_LASTING, FSM_STATE_DEAD, FSM_STATE_ADMOVE, FSM_STATE_FORCEMOVE, FSM_STATE_RELIVE, FSM_STATE_IDLE, }下面告诉大家如何使用我们具体的动作状态切换,具体实现就是继承上面定义的接口:
public class EntityIdleFSM : EntityFSM { public static readonly EntityFSM Instance = new EntityIdleFSM(); public FsmState State { get { return FsmState.FSM_STATE_IDLE; } } public bool CanNotStateChange{ set;get; } public bool StateChange(Ientity entity , EntityFSM fsm) { return CanNotStateChange; } public void Enter(Ientity entity , float last) { entity.OnEnterIdle(); } public void Execute(Ientity entity) { if (EntityStrategyHelper.IsTick(entity, 3.0f)) { entity.OnFSMStateChange(EntityFreeFSM.Instance); } } public void Exit(Ientity entity){ } }在这个函数中使用了一个接口Ientity,其实它主要实现的是状态之间的切换,下面就把该类的主要功能实现如下所示:
/// <summary> /// 状态改变 /// </summary> /// <param name="fsm"></param> /// <param name="last"></param> public void OnFSMStateChange(EntityFSM fsm, float last) { if (this.FSM != null && this.FSM.StateChange(this, fsm)) { return; } if (this.FSM == fsm && this.FSM != null && this.FSM.State == FsmState.FSM_STATE_DEAD) { return; } if (this.FSM != null) { this.FSM.Exit(this); } if (this.FSM != null) this.RealEntity.FSMStateName = fsm.ToString(); this.FSM = fsm; StrategyTick = Time.time; this.FSM.Enter(this, last); } public void OnFSMStateChange(EntityFSM fsm) { if (this.FSM != null && this.FSM.StateChange(this, fsm)) { return; } if (this.FSM == fsm && this.FSM != null && (this.FSM.State == FsmState.FSM_STATE_DEAD)) { return; } if (this.FSM != null) { this.FSM.Exit(this); } this.FSM = fsm; if (this.FSM != null) this.RealEntity.FSMStateName = fsm.ToString(); StrategyTick = Time.time; this.FSM.Enter(this, 0.0f); }
该类还提供了各个动作的接口,实现如下所示:
public virtual void OnEnterIdle()
{
this.RealEntity.PlayerAnimation("idle");
}
/// <summary>
/// Run状态进入时调用
/// </summary>
public virtual void OnEnterMove()
{
}
这个RealEntity类实现的是具体的动作或者是新动画触发函数封装事例代码如下所示:
public void PlayerIdleAnimation() { if (this.animation == null) { return; } PlayerAnimation("idle"); this.animation.PlayQueued("free"); } public void PlayerFreeAnimation() { if (this.animation == null) { return; } PlayerAnimation("free"); } public void PlayerRunAnimation(){ if (this.animation == null) { return; } PlayerAnimation("walk"); }
技能的接口实现跟这个类似,代码如下所示:
public class EntityReleaseSkillFSM : EntityFSM
{
public static readonly EntityFSM Instance = new EntityReleaseSkillFSM();
public FsmState State{
get
{
return FsmState.FSM_STATE_RELEASE;
}
}
public bool CanNotStateChange{
set;get;
}
public bool StateChange(Ientity entity , EntityFSM fsm){
return CanNotStateChange;
}
public void Enter(Ientity entity , float last){
//Debug.LogError("prepareplayskill enter!");
entity.OnEntityReleaseSkill();
}
public void Execute(Ientity entity){
//entity.OnEntityPrepareAttack ();
}
public void Exit(Ientity entity){
}
}
这样我们的FSM状态机就实现完成了,使用该框架开发了多款游戏,效果如下:
作者:jxw167 发表于2017/4/4 12:49:16 原文链接
阅读:122 评论:0 查看评论