毕业设计之角色状态机

      这两天一直没做多少毕设的东西,只是简单的实现了下fsm状态机,之前只是了解并没有彻底接触过,学习了一下发现并没有想象中那么复杂,于是根据一篇教程自己改动了下。状态机果然好用,把逻辑简化了很多,虽然代码量多了很多。原贴地址:https://blog.csdn.net/code_sheen/article/details/45869505


IState:

     

public interface IState
{
    /// <summary>
    /// 获取状态ID
    /// </summary>
    /// <returns></returns>
    int GetStateID();

    /// <summary>
    /// 进入状态回调此方法
    /// </summary>
    /// <param name="stateMachine">控制此状态的状态机</param>
    /// <param name="prevState">进入此状态的前状态</param>
    void OnEnter(GameStateMachine stateMachine, IState prevState, object param1, object param2);

    /// <summary>
    /// 离开状态时回调此方法
    /// </summary>
    /// <param name="nextState">离开此状态后的下一状态</param>
    void OnLeave(IState nextState, object param1, object param2);

    /// <summary>
    /// 每帧的OnUpdate方法回调
    /// </summary>
    void OnUpdate();

}
PlayerRunState:
using UnityEngine;
using System.Collections;

public class PlayerRuningState : IState
{
    Player m_Player = null;
    private bool isRight;
    private static bool isFirst = true;//自己加的,因为OnLeave之后还是被一直调用,很烦
    public PlayerRuningState(Player player)
    {
        m_Player = player;
    }
    #region IState 成员

    public int GetStateID()
    {
        return (int)Player.PlayerState.Runing;
    }

    public void OnEnter(GameStateMachine stateMachine, IState prevState, object param1, object param2)
    {
        m_Player.anim.SetBool("isRun",true);//这里还有个报错,获取不到
        Debug.Log("进入行走状态 上次的状态为 :" + prevState);
    }

    public void OnLeave(IState nextState, object param1, object param2)
    {
 
        m_Player.anim.SetBool("isRun", false);
        Debug.Log("退出行走状态 下次的状态为 :" + nextState);
    }

    public void OnUpdate()
    {
        float v = Input.GetAxis("Vertical");
        float h = Input.GetAxis("Horizontal");

        if (Mathf.Abs(h) > 0.1f)
        {
            m_Player.gameObject.transform.Translate(Vector3.forward * Time.deltaTime * v * 5);
            m_Player.gameObject.transform.eulerAngles += new Vector3(0, -h, 0);

        }
        else if (Mathf.Abs(v) > 0.1f)
        {
            m_Player.gameObject.transform.Translate(Vector3.forward * Time.deltaTime * v * 5);
            m_Player.gameObject.transform.eulerAngles += new Vector3(0, -h, 0);

        }
        if(Input.GetKeyDown(KeyCode.Space))
        {
            m_Player.anim.SetTrigger("isJump");
           m_Player.gameObject.GetComponent<Rigidbody>().AddForce(Vector3.up * 200);
        }
    }

    #endregion
}
GameStateMachine:
using UnityEngine;
using System.Collections;

//
/// Author: sheen
/// Date: 2015-5-20 13:46:51
/// Description: 状态机
//
using System.Collections.Generic;

public class GameStateMachine 
{
    /// <summary>
    /// 存储所有注册进来的状态。key是状态ID,value是状态对象
    /// </summary>
    private Dictionary<int, IState> m_dictState;
    /// <summary>
    /// 当前运行的状态
    /// </summary>
    private IState m_curState;

    public GameStateMachine()
    {
        m_curState = null;
        m_dictState = new Dictionary<int, IState>();
    }

    /// <summary>
    /// 注册一个状态
    /// </summary>
    /// <param name="state">要注册的状态</param>
    /// <returns>成功返回true,如果此状态ID已存在或状态为NULL,则返回false</returns>
    public bool RegistState(IState state)
    {
        if (null == state)
        {
            Debug.LogWarning("StateMachine::RegistState->state is null");
            return false;
        }

        if (m_dictState.ContainsKey(state.GetStateID()))
        {
            Debug.LogWarning("StateMachine::RegistState->state had exist! state id=" + state.GetStateID());
            return false;
        }

        m_dictState[state.GetStateID()] = state;

        return true;
    }

    /// <summary>
    /// 尝试获取一个状态
    /// </summary>
    /// <param name="iStateId"></param>
    /// <returns></returns>
    public IState GetState(int iStateId)
    {
        IState ret = null;
        m_dictState.TryGetValue(iStateId, out ret);
        return ret;
    }

    /// <summary>
    /// 停止当前正在运行的状态, 切换到空状态
    /// </summary>
    public void StopState(object param1, object param2)
    {
        if (null == m_curState)
        {
            return;
        }

        m_curState.OnLeave(null, param1, param2);

        m_curState = null;
    }

    /// <summary>
    /// 取消状态的注册
    /// </summary>
    /// <param name="iStateID">要取消的状态ID</param>
    /// <returns>如果找不到状态或状态正在运行,则会返回false</returns>
    public bool CancelState(int iStateID)
    {
        if (!m_dictState.ContainsKey(iStateID))
        {
            return false;
        }

        if (null != m_curState && m_curState.GetStateID() == iStateID)
        {
            return false;
        }

        return m_dictState.Remove(iStateID);
    }

    //public delegate void BetweenSwitchState(IState from, IState to, object param1, object param2);

    / <summary>
    / 在切换状态之间回调
    / </summary>
    //public BetweenSwitchState BetweenSwitchStateCallBack { get; set; }

    /// <summary>
    /// 切换状态
    /// </summary>
    /// <param name="iNewStateID">要切换的新状态</param>
    /// <returns>如果找不到新的状态,或者新旧状态一样,返回false</returns>
    public bool SwitchState(int iNewStateID, object param1, object param2)
    {
        //状态一样,不做转换//
        if (null != m_curState && m_curState.GetStateID() == iNewStateID)
        {

            return false;
        }
        //通过iNewStateID判断是否能够获取到状态
        IState newState = null;
        m_dictState.TryGetValue(iNewStateID, out newState);
        if (null == newState)
        {
            return false;
        }
        //执行oldState的Leave状态
        IState oldState = m_curState;
        if ( oldState!=null)
        {

            oldState.OnLeave(newState, param1, param2);
            oldState=null;
        }
                        // if (BetweenSwitchStateCallBack != null) BetweenSwitchStateCallBack(oldState, newState, param1, param2);
        m_curState = newState;
        if (null != newState)
        {
            newState.OnEnter(this, oldState, param1, param2);
        }

        return true;
    }

    /// <summary>
    /// 获取当前状态
    /// </summary>
    /// <returns></returns>
    public IState GetCurState()
    {
        return m_curState;
    }

    /// <summary>
    /// 获取当前状态ID
    /// </summary>
    /// <returns></returns>
    public int GetCurStateID()
    {
        IState state = GetCurState();
        return (null == state) ? 0 : state.GetStateID();
    }
    /// <summary>
    /// 判断当前是否在某个状态下
    /// </summary>
    /// <param name="iStateID"></param>
    /// <returns></returns>
    public bool IsInState(int iStateID)
    {
        if (null == m_curState)
        {
            return false;
        }

        return m_curState.GetStateID() == iStateID;
    }
    /// <summary>
    /// 每帧的更新回调
    /// </summary>
    public void OnUpdate()
    {
        if (null != m_curState)
        {
            m_curState.OnUpdate();
        }
    }
}
Player:

using UnityEngine;
using System.Collections;

public class Player : MonoBehaviour {
    public Animator anim;
    private Rigidbody rigid;
    public static int isIdel = 2;
    GameStateMachine playerGameStateMachine = new GameStateMachine();
    public enum PlayerState
    {
        Ide = 0,
        Runing = 1,
        NULL=2
    }

    void Awake() 
    {
        rigid = this.gameObject.GetComponent<Rigidbody>();
        //注册所有状态//
        playerGameStateMachine.RegistState(new PlayerIdeState(this)); //注册待机状态//
        playerGameStateMachine.RegistState(new PlayerRuningState(this)); //注册行走状态//
        //设置默认状态
        playerGameStateMachine.SwitchState((int)PlayerState.Ide, null, null);
    }

    void Update()
    {
        playerGameStateMachine.OnUpdate();

        //进入行走状态
        if (Input.GetKey(KeyCode.A) || Input.GetKey(KeyCode.W) || Input.GetKey(KeyCode.S) || Input.GetKey(KeyCode.D))
        {
            isIdel = 2;
            playerGameStateMachine.SwitchState((int)PlayerState.Runing, null, null);
        }
        else
        {
            if (isIdel == 2)
            {

                playerGameStateMachine.SwitchState((int)PlayerState.Ide, null, null);
                isIdel++;
            }
        }
    }
}


  • 3
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Zero游戏开发

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值