游戏蛮牛学习群(纯技术交流,不闲聊):159852603
游戏蛮牛 手机端
开启辅助访问
 找回密码
 注册帐号

扫一扫,访问微社区

首页   >   博客   >   UnityTerminator

游戏框架-FSM状态机 热度 2

个人分类: MMO游戏设计框架 | 2018-7-5 16:41
标签:FSM状态机
2 个评论 | 阅读 245 | 收藏 | 举报

[code]csharpcode:

using UnityEngine;
using System.Collections.Generic;

[System.Serializable]
public class StateFunc
{
    public delegate void EnterFunc(object param);
    public delegate void ExitFunc();
    public delegate void UpdateFunc(float dt);

    public EnterFunc enterFunc;
    public ExitFunc exitFunc;
    public UpdateFunc updateFunc;
}

[System.Serializable()]
public class FsmManager<T> where T : struct
{
    /// <summary>
    /// 之前的状态
    /// </summary>
    [SerializeField]
    protected T _prevState;

    /// <summary>
    /// 当前的状态
    /// </summary>
    [SerializeField]
    protected T _currState;

    [SerializeField]
    public float stateTimer = 0;

    public T CurrState { get { return _currState; } }

    protected Dictionary<T, StateFunc> _stateFuncs = new Dictionary<T, StateFunc>();

    /// <summary>
    /// 注册状态
    /// </summary>
    /// <param name="state"></param>
    /// <param name="enter"></param>
    /// <param name="update"></param>
    /// <param name="exit"></param>
    public void RegistState(T state,StateFunc.EnterFunc enter,StateFunc.UpdateFunc update,StateFunc.ExitFunc exit)
    {
        StateFunc func = new StateFunc
        {
            enterFunc = enter,
            updateFunc = update,
            exitFunc = exit
        };
        _stateFuncs.Add(state, func);
        Debug.Log("State:" + state);
    }

    /// <summary>
    /// 更新状态
    /// </summary>
    /// <param name="dt"></param>
    public void UpdateState(float dt)
    {
        if(_stateFuncs.ContainsKey(_currState)&&(_stateFuncs[_currState].updateFunc != null))
        {
            _stateFuncs[_currState].updateFunc(dt);
        }
    }

    /// <summary>
    /// 设置状态
    /// </summary>
    /// <param name="state"></param>
    /// <param name="param"></param>
    public void SetState(T state,object param = null)
    {
        if (_stateFuncs.Equals(state)) return;
        T curState = _currState;
        _prevState = curState;
        _currState = state;

        if (_stateFuncs.ContainsKey(curState) && (_stateFuncs[curState].exitFunc) != null)
        {
            _stateFuncs[curState].exitFunc();
        }

        if(_stateFuncs.ContainsKey(_currState) &&( _stateFuncs[_currState].enterFunc)!=null)
        {
            _stateFuncs[_currState].enterFunc(param);
        }
        stateTimer = 0;
    }

    /// <summary>
    /// 是否有状态
    /// </summary>
    /// <param name="state"></param>
    /// <returns></returns>
    public bool HasState(T state)
    {
        return _stateFuncs.ContainsKey(state);
    }
}

下面为调用测试代码:

[code]csharpcode:

using System;
using UnityEngine;

public class TFsm : MonoBehaviour
{
    public enum EnemyState
    {
        Idle,
        Attack,
        Run,
        Die
    }

    FsmManager<EnemyState> enemyState = new FsmManager<EnemyState>();

    void Start()
    {
        enemyState.RegistState(EnemyState.Idle, OnIdleEnter, OnIdleUpdate, OnIdleExit);
        enemyState.RegistState(EnemyState.Run, OnRunEnter, OnRunUpdate, OnRunExit);
        enemyState.RegistState(EnemyState.Attack, OnAttackEnter, OnAttackUpdate, OnAttackExit);
        enemyState.RegistState(EnemyState.Die, OnDieEnter, OnDieUpdate, OnDieExit);
        enemyState.SetState(EnemyState.Idle);
    }

    private void OnDieExit()
    {
        Debug.Log("退出死亡");
    }

    private void OnDieUpdate(float dt)
    {
        Debug.Log("更新死亡");
    }

    private void OnDieEnter(object param)
    {
        Debug.Log("进入死亡");
    }

    private void OnAttackExit()
    {
        Debug.Log("退出攻击");
    }

    private void OnAttackUpdate(float dt)
    {
        Debug.Log("更新攻击");
    }

    private void OnAttackEnter(object param)
    {
        Debug.Log("进入攻击");
    }

    private void OnRunExit()
    {
        Debug.Log("退出奔跑");
    }

    private void OnRunUpdate(float dt)
    {
        Debug.Log("更新奔跑");
    }

    private void OnRunEnter(object param)
    {
        Debug.Log("进入奔跑");
    }

    private void OnIdleExit()
    {
        Debug.Log("退出Idle");
    }

    private void OnIdleUpdate(float dt)
    {
        Debug.Log("更新Idle");
    }

    private void OnIdleEnter(object param)
    {
        Debug.Log("进入Idle");
    }

    void Update()
    {
        float dt = Time.deltaTime;
        enemyState.UpdateState(dt);

        if (Input.GetKeyDown(KeyCode.Q))
        {
            enemyState.SetState(EnemyState.Idle);
        }
        if (Input.GetKeyDown(KeyCode.W))
        {
            enemyState.SetState(EnemyState.Run);
        }
        if (Input.GetKeyDown(KeyCode.E))
        {
            enemyState.SetState(EnemyState.Attack);
        }
        if (Input.GetKeyDown(KeyCode.R))
        {
            enemyState.SetState(EnemyState.Die);
        }

    }  
}


1 0

评论 (2 个评论)

回复 3084 2018-7-6 13:42
感谢分享
回复 MrXx旌歌 2018-7-9 17:32
  

facelist doodle 涂鸦板

您需要登录后才可以评论 登录 | 注册帐号

个人分类

标签

阅读排行

评论排行

推荐博客

最新博客

关闭

站长推荐 上一条 /1 下一条

返回顶部