1、基本框架搭建
1.1首先创建一个枚举类来定义玩家的各个状态,我定义了四种基本状态,可根据具体的要求自我添加状态。
public enum PlayerState
{
Idle,
Run,
Walk,
Die
}
1.2、创建一个动画状态机控制器类—–PlayerFSMMgr.cs,该类管理玩家所有状态的切换
再创建一个玩家所有状态的基类,所有的状态类都继承于该类PlayerStateAbstract.cs
然后再根据你定义的玩家状态枚举类,定义其单独该状态类。如下图所示,定义了四种状态类, PlayerStateDie.cs ;PlayerStateIdle.cs;PlayerStateRun.cs;PlayerStateWalk.cs,这四个状态类都继承基类PlayerStateAbstract.cs
还有一个玩家控制类PlayerCtrl.cs
2.完善如下
2.1、首先为状态基类PlayerStateAbstract.cs的完善
using UnityEngine;
using System.Collections;
/// <summary>
/// 定义一个玩家角色状态的抽象基类
/// </summary>
public abstract class PlayerStateAbstract
{
/// <summary>
/// 当前角色有限状态机管理器
/// </summary>
public PlayerFSMMgr CurFSM;
/// <summary>
/// 当前动画状态信息
/// </summary>
public AnimatorStateInfo CurrRoleAnimtorStateInfo { get; set; }
public PlayerStateAbstract(PlayerFSMMgr FSM)
{
CurFSM = FSM;
}
/// <summary>
/// 进入状态
/// </summary>
public virtual void OnEnter() { }
/// <summary>
/// 执行状态
/// </summary>
public virtual void OnUpdate() { }
/// <summary>
/// 离开状态
/// </summary>
public virtual void OnLeave() { }
}
2.2、接下来为4个状态类的完善,此处以PlayerStateWalk.cs为例
using UnityEngine;
using System.Collections;
public class PlayerStateWalk : PlayerStateAbstract
{
public PlayerStateWalk(PlayerFSMMgr FSM) : base(FSM)
{
}
public override void OnEnter()
{
base.OnEnter();
//播放该状态下的动画
}
public override void OnLeave()
{
base.OnLeave();
}
/// <summary>
/// 每一帧都执行
/// </summary>
public override void OnUpdate()
{
base.OnUpdate();
//可以判断是否动画播放完成,也可以写控制玩家移动的控制判断等
}
}
2.3、状态机控制器类,包含当前玩家的当前状态枚举以及当前状态属性的定义等,还有玩家状态的切换方法等。
using UnityEngine;
using System.Collections;
using System.Collections.Generic;
/// <summary>
/// 玩家动画状态机控制器
/// </summary>
public class PlayerFSMMgr
{
/// <summary>
/// 当前角色状态枚举
/// </summary>
public PlayerState CurStateEnum { get; private set; }
/// <summary>
/// 当前角色状态类
/// </summary>
private PlayerStateAbstract CurState = null;
/// <summary>
/// 当前控制器所控制的玩家
/// </summary>
public PlayerCtrl CurPlayer;
public Dictionary<PlayerState, PlayerStateAbstract> PlayerStateDic = new Dictionary<PlayerState, PlayerStateAbstract>();
/// <summary>
/// 构造函数,初始化状态类
/// </summary>
public PlayerFSMMgr(PlayerCtrl Player)
{
CurStateEnum = PlayerState.Idle;
CurPlayer = Player;
PlayerStateDic[PlayerState.Idle] = new PlayerStateIdle(this);
PlayerStateDic[PlayerState.Walk] = new PlayerStateWalk(this);
PlayerStateDic[PlayerState.Run ] = new PlayerStateRun(this);
PlayerStateDic[PlayerState.Die ] = new PlayerStateDie(this);
if(PlayerStateDic.ContainsKey (CurStateEnum ))
{
CurState = PlayerStateDic[CurStateEnum];
}
}
/// <summary>
/// 切换状态类
/// </summary>
/// <param name="newState">新状态</param>
public void ChangeState(PlayerState newState)
{
if (CurStateEnum == newState) return;
if(CurState!=null )
{
//调用离开之前的方法
CurState.OnLeave();
}
//将当前状态枚举和当前状态都切换为新状态
CurStateEnum = newState;
if(PlayerStateDic.ContainsKey (CurStateEnum))
{
CurState = PlayerStateDic[CurStateEnum];
}
//并调用新状态进入方法
CurState.OnEnter();
}
/// <summary>
/// 每帧都执行
/// </summary>
public void OnUpdate()
{
if(CurState!=null )
{
CurState.OnUpdate();
}
}
}
2.4、简单的角色控制类,每个角色应该有一个该控制器,每个控制器控制自己角色的动画切换和播放。
using UnityEngine;
using System.Collections;
/// <summary>
/// 玩家控制器
/// </summary>
public class PlayerCtrl : MonoBehaviour {
/// <summary>
/// 当前玩家的动画状态器
/// </summary>
public PlayerFSMMgr m_FSM;
void Start ()
{
m_FSM = new PlayerFSMMgr(this);
}
// Update is called once per frame
void Update ()
{
if(m_FSM!=null )
{
m_FSM.OnUpdate();
}
}
}
以上为简单的状态机控制器