1. 程式人生 > 其它 >Unity中的UI狀態機

Unity中的UI狀態機

技術標籤:UnityC#基礎

using System;
using System.Collections.Generic;
using FrameWork;
using UnityEngine;

public abstract class StateSystem<T> : MonoBehaviour
{
    /// <summary>
    /// 狀態機
    /// </summary>
    protected StateMachine<T> mState;

    /// <summary>
    /// 狀態棧(可用於返回使用)
    /// </summary>
protected Stack<T> mStateStack; private void Awake() { mState = new StateMachine<T>(); mStateStack = new Stack<T>(); initialize(); initStates(); } protected virtual void initialize() { } protected virtual void initStates
() { } public void OnEnable() { mState.OnStart(); } public virtual void Update() { mState.OnUpdate(); } public void OnDisable() { mState.OnStop(); } /// <summary> /// 切換狀態 /// </summary> /// <param name="state">欲切換的狀態</param>
/// <param name="saveState">是否儲存上一個狀態</param> public void ChangeState(T state, bool saveState = false) { try { if (mState.CurrentState.Equals(state)) { return; } if (saveState) { mStateStack.Push(mState.CurrentState); } Debug.LogFormat("切換狀態:{0} -> {1}", mState.CurrentState, state); mState.ChangeState(state); } catch (Exception e) { Debug.Log(e.Message); throw; } } /// <summary> /// 當前狀態 /// </summary> public T currentState { get { return mState.CurrentState; } } /// <summary> /// 返回到上一個儲存的狀態 /// </summary> /// <returns></returns> public bool BackState() { if (mStateStack.Count == 0) { return false; } T lastState = mStateStack.Pop(); mStateStack.Clear(); ChangeState(lastState); return true; } }
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.XR;

namespace FrameWork
{
    public class StateMachine<T>
    {
        private class State
        {
            public readonly T label;
            public readonly Action onStart;
            public readonly Func<T> onUpdate;
            public readonly Action onStop;

            public State(T label, Action onStart, Func<T> onUpdate, Action onStop)
            {
                this.label = label;
                this.onStart = onStart;
                this.onUpdate = onUpdate;
                this.onStop = onStop;
            }
        }

        /// <summary>
        /// 狀態集合
        /// </summary>
        private readonly Dictionary<T, State> mStateDictionary;

        private State mCurrentState;

        /// <summary>
        /// 上一個狀態
        /// </summary>
        private State mPreState;

        /// <summary>
        /// 進入的狀態名稱
        /// </summary>
        private T mEnterState;

        /// <summary>
        /// 當前狀態的label
        /// </summary>
        public T CurrentState
        {
            get { return mCurrentState.label; }
            set { ChangeState(value); }
        }

        /// <summary>
        /// 返回上一狀態label
        /// </summary>
        public T PreState => mPreState.label;

        public bool IsRunning
        {
            get { return CurrentState != null; }
        }

        public StateMachine()
        {
            mStateDictionary = new Dictionary<T, State>();
        }

        public void OnStart()
        {
            if (mStateDictionary.Count == 0)
            {
                return;
            }

            mCurrentState = mStateDictionary[mEnterState];
            if (mCurrentState != null && mCurrentState.onStart != null)
            {
                mCurrentState.onStart();
            }
        }

        public void OnUpdate()
        {
            if (mCurrentState != null && mCurrentState.onUpdate != null)
            {
                mCurrentState.onUpdate();
            }
        }

        public void OnStop()
        {
            if (mCurrentState != null && mCurrentState.onStop != null)
            {
                mCurrentState.onStop();
            }
        }

        /// <summary>
        /// 新增狀態
        /// </summary>
        /// <param name="label">狀態</param>
        /// <param name="onStart">在狀態開始時呼叫</param>
        /// <param name="onUpdate">在狀態期間持續呼叫</param>
        /// <param name="onStop">在狀態結束時呼叫</param>
        public void AddState(T label, Action onStart, Func<T> onUpdate, Action onStop)
        {
            State state = new State(label, onStart, onUpdate, onStop);
            mStateDictionary[label] = state;
            if (mCurrentState == null) //第一個新增的狀態為初始狀態
            {
                mCurrentState = state;
                mEnterState = mCurrentState.label;
            }
        }


        /// <summary>
        /// 切換狀態
        /// </summary>
        /// <param name="newLabel"></param>
        public void ChangeState(T newLabel)
        {
            if (mCurrentState != null && mCurrentState.onStop != null)
            {
                mCurrentState.onStop();
            }

            mPreState = mCurrentState;
            mCurrentState = mStateDictionary[newLabel];

            if (mCurrentState != null && mCurrentState.onStart != null)
            {
                mCurrentState.onStart();
            }
        }
    }
}