目的:使用有限状态机封装角色动画播放
思路:
1. 设计有限状态机
父类:CBaseHomeState
using UnityEngine;
using System.Collections;
//状态机父类
public class CBaseHomeState
{
protected eActionState m_state;
protected CBaseHomeAvatar m_pHomeAvatar;
public CBaseHomeState(CBaseHomeAvatar avatar, eActionState state)
{
m_pHomeAvatar = avatar;
m_state = state;
}
public virtual void EnterState()
{
}
public virtual void ExitState()
{
}
public virtual void Update()
{
}
public eActionState GetState()
{
return m_state;
}
}
子类:CHomeRunState, CHomeNormalState
using UnityEngine;
using System.Collections;
public class CHomeNormalState : CBaseHomeState
{
public CHomeNormalState(CBaseHomeAvatar avatar)
: base(avatar, eActionState.IdelInHome)
{
}
public override void EnterState()
{
base.EnterState();
m_pHomeAvatar.PlayAction(m_state, 1, false, OnEnterActionFinished, 0.2f, null);
}
private void OnEnterActionFinished(object[] parms)
{
Debug.Log("idle动画播放完成!");
}
}
using UnityEngine;
using System.Collections;
public class CHomeRunState : CBaseHomeState
{
public CHomeRunState(CBaseHomeAvatar avatar)
: base(avatar, eActionState.RunInHome)
{
}
public override void EnterState()
{
base.EnterState();
m_pHomeAvatar.PlayAction(m_state, 1.0f, false, OnEnterActionFinished);
}
private void OnEnterActionFinished(object[] parms)
{
Debug.Log("run动画播放完成!");
}
public override void Update()
{
base.Update();
}
}
管理类:CHomeStateManager
using UnityEngine;
using System.Collections;
using System.Collections.Generic;
public class CHomeStateManager
{
private CBaseHomeAvatar m_pHomeAvatar;
private CBaseHomeState m_currentState;
private eActionState m_actState;
private Dictionary<eActionState, CBaseHomeState> m_stateDict = new Dictionary<eActionState, CBaseHomeState>();
public CHomeStateManager(CBaseHomeAvatar avatar)
{
m_pHomeAvatar = avatar;
Reuse();
RegisterState(new CHomeNormalState(m_pHomeAvatar));
RegisterState(new CHomeRunState(m_pHomeAvatar));
}
private void RegisterState(CBaseHomeState pState)
{
eActionState eState = pState.GetState();
if (!m_stateDict.ContainsKey(eState))
{
m_stateDict.Add(eState, pState);
}
}
public void Reuse()
{
m_currentState = null;
}
public void Update()
{
if (m_currentState != null)
m_currentState.Update();
}
public void EnterState(eActionState state)
{
CBaseHomeState pState = null;
m_stateDict.TryGetValue(state, out pState);
if (pState != null)
{
m_currentState = pState;
pState.EnterState();
}
}
public void ExitState(eActionState state)
{
CBaseHomeState pState = null;
m_stateDict.TryGetValue(state, out pState);
if (pState != null)
{
if (m_currentState != null && m_currentState == pState)
{
pState.ExitState();
//默认状态
if (m_currentState == pState && state != eActionState.IdelInHome)
{
m_pHomeAvatar.EnterState(eActionState.IdelInHome);
}
}
}
}
}
2. 封装角色
using UnityEngine;
using System.Collections;
public class CBaseHomeAvatar
{
protected CAnimator m_pAnimator;
protected CHomeStateManager m_stateMgr;
public void PlayAction(eActionState state, float speed = 1.0f, bool bRepeat = false, PlayOnceFinished callback = null, float fadeTime = 0.05f, object[] parms = null)
{
if (m_pAnimator != null)
{
string actionName = StateData.GetActionName(state);
m_pAnimator.PlayAction(actionName, speed, bRepeat, callback, fadeTime, parms);
}
}
public void EnterState(eActionState state)
{
if (m_stateMgr != null)
{
m_stateMgr.EnterState(state);
}
}
public void ExitState(eActionState state)
{
if (m_stateMgr != null)
{
m_stateMgr.ExitState(state);
}
}
public virtual void Update()
{
if (m_stateMgr != null)
{
m_stateMgr.Update();
}
}
}
PS:以上代码是伪代码