FSM

作者: 醉酒青牛_fa4e | 来源:发表于2019-04-17 00:08 被阅读0次

    状态抽象:
    1.进入状态
    2.退出状态
    3.在状态中(Update)

    C层抽象:
    1.管理子状态
    2.负责状态间的交换
    3.一个状态一个类
    4.状态只能通过C层跳转
    5.使用枚举代替数值,最后设置一个maxvalue


    using System;
    using System.Collections;
    using System.Collections.Generic;
    using UnityEngine;
    using UnityEngine.Events;

    /// <summary>
    /// 状态脚本,一个状态一个类
    /// </summary>
    public class OrcIdle : FSMBase
    {
    Animator animator;

    public OrcIdle() { }
    
    public OrcIdle(Animator ani)
    {
        animator = ani;
    
    }
    
    
    public override void OnEnter()
    {
        animator.SetInteger("StateIndex", 1);
        Debug.Log("进入Idle");
    }
    
    public override void OnLeave()
    {
        Debug.Log("退出Idle");
    }
    
    public override void Update()
    {
        Debug.Log("在Idle中");
    }
    

    }
    public class OrcJump : FSMBase
    {
    Animator animator;
    //Func的泛型是返回值类型,UnityAction的泛型是参数类型
    UnityAction<sbyte> callBack;

    public OrcJump() { }
    
    public OrcJump(Animator ani,UnityAction<sbyte> tmpBack)
    {
        animator = ani;
        callBack = tmpBack;
    }
    
    public float timeCount;
    public override void OnEnter()
    {
        animator.SetInteger("StateIndex", 2);
        Debug.Log("进入Jump");
    }
    
    public override void OnLeave()
    {
        Debug.Log("退出Jump");
    }
    
    public override void Update()
    {
        timeCount += Time.deltaTime;
        if (timeCount > 1)
        {
            timeCount = 0;
            callBack((sbyte)OrcCtrl.AnimalState.Idle);
        }
        Debug.Log("在Jump中");
    }
    

    }
    public class OrcRun : FSMBase
    {
    Animator animator;

    public OrcRun() { }
    
    public OrcRun(Animator ani)
    {
        animator = ani;
    
    }
    
    
    public override void OnEnter()
    {
        animator.SetInteger("StateIndex", 3);
        Debug.Log("进入run");
    }
    
    public override void OnLeave()
    {
        Debug.Log("退出run");
    }
    
    public override void Update()
    {
        Debug.Log("在run中");
    }
    

    }

    /// <summary>
    /// 状态类的父类,抽象出3个函数
    /// </summary>
    public abstract class FSMBase {

    public abstract void OnEnter();
    
    public abstract void OnLeave();
    
    public abstract void Update();
    

    }
    /// <summary>
    /// 状态管理类
    /// </summary>
    public class FsmManager
    {

    //数组比list快
    FSMBase[] allState;
    
    public FsmManager(){}
    /// <summary>
    /// 状态总数
    /// </summary>
    sbyte stateIndex;
    /// <summary>
    /// 当前状态索引
    /// </summary>
    sbyte currentIndex;
    
    public FsmManager(byte stateCount)
    {
        allState = new FSMBase[stateCount];
        stateIndex = -1;
        currentIndex = -1;
    }
    /// <summary>
    /// 添加
    /// </summary>
    /// <param name="state"></param>
    public void AddState(FSMBase state)
    {
        if (stateIndex < allState.Length)
        {
            stateIndex++;
    
            allState[stateIndex] = state;
    
        }
    }
    /// <summary>
    /// 交换
    /// </summary>
    /// <param name="stateNuber"></param>
    public void ChangeState(sbyte stateNuber)
    {
        stateNuber =(sbyte)( stateNuber % allState.Length);
        if (currentIndex != -1)
        {
            allState[currentIndex].OnLeave();
    
        currentIndex = stateNuber;
    
            allState[currentIndex].OnEnter();
    
        }
        else
        {
            currentIndex = stateNuber;
    
            allState[currentIndex].OnEnter();
        }    
    }
    /// <summary>
    /// 在状态中
    /// </summary>
    public void Update()
    {
        if (currentIndex != -1)
        {
            allState[currentIndex].Update();
        }
    }
    

    }

    using System.Collections;
    using System.Collections.Generic;
    using UnityEngine;
    /// <summary>
    /// C层
    /// </summary>
    public class OrcCtrl : MonoBehaviour {

    FsmManager fsmManager;
    
    
    /// <summary>
    /// 所有状态, MaxValue为状态总数
    /// </summary>
    public enum AnimalState
    {
        Idle,
        Jump,
        Run,
        MaxValue
    }
    
    // Use this for initialization
    void Start () {
        fsmManager = new FsmManager((byte)AnimalState.MaxValue);
    
        Animator tmpAni = transform.GetComponent<Animator>();
    
        OrcIdle tmpIdle = new OrcIdle(tmpAni);
    
        fsmManager.AddState(tmpIdle);
    
        OrcJump tmpJump = new OrcJump(tmpAni, ChangeState);
    
        fsmManager.AddState(tmpJump);
    
        OrcRun tmpRun = new OrcRun(tmpAni);
    
        fsmManager.AddState(tmpRun);
    }
    
    // Update is called once per frame
    void Update () {
        if (Input.GetKey(KeyCode.A))
        {
            fsmManager.ChangeState((sbyte)AnimalState.Jump);
        }
        fsmManager.Update();
    }
    
    public void ChangeState(sbyte stateIndex)
    {
        fsmManager.ChangeState(stateIndex);
    }
    

    }

    相关文章

      网友评论

          本文标题:FSM

          本文链接:https://www.haomeiwen.com/subject/afjbwqtx.html