Merge branch '03.FiniteStateMachine' into master1

# Conflicts:
#	.gitlab-ci.yml
#	Assets/01.CodeChecker.meta
#	Assets/01.CodeChecker/Editor.meta
#	Assets/01.CodeChecker/Editor/UnityRoslyn.meta
#	Assets/02.InformationSave/RunTime/Abstract.meta
#	Assets/02.InformationSave/RunTime/Base.meta
#	Assets/03.FiniteStateMachine/RunTime/Abstract.meta
#	Assets/03.FiniteStateMachine/RunTime/Base.meta
#	Assets/03.FiniteStateMachine/RunTime/FiniteStateMachine.RunTime.asmdef.meta
#	Assets/03.FiniteStateMachine/RunTime/Use.meta
#	Assets/04.AudioCore/README.md
#	Assets/04.AudioCore/RunTime/Abstract/IAudio.cs
#	Assets/04.AudioCore/RunTime/Abstract/IAudio.cs.meta
#	Assets/04.AudioCore/RunTime/Base/AudioSourcePool.cs
#	Assets/04.AudioCore/RunTime/Base/AudioSourcePool.cs.meta
#	Assets/04.AudioCore/RunTime/Base/CoroutineHelper.cs
#	Assets/04.AudioCore/RunTime/Base/CoroutineHelper.cs.meta
#	Assets/04.AudioCore/RunTime/Base/MusicPlayer.cs
#	Assets/04.AudioCore/RunTime/Base/MusicPlayer.cs.meta
#	Assets/04.AudioCore/RunTime/Base/SFXPlayer.cs
#	Assets/04.AudioCore/RunTime/Base/SFXPlayer.cs.meta
#	Assets/04.AudioCore/RunTime/Base/VoicePlayer.cs
#	Assets/04.AudioCore/RunTime/Base/VoicePlayer.cs.meta
#	Assets/04.AudioCore/RunTime/Use/AudioCoreManager.cs
#	Assets/04.AudioCore/RunTime/Use/AudioCoreManager.cs.meta
#	Assets/04.AudioCore/package.json
#	Assets/05.TableTextConversion/Editor/ConvertedExslDataMessage.cs.meta
#	Assets/05.TableTextConversion/Editor/EditorFrameworkUtils.cs.meta
#	Assets/05.TableTextConversion/Editor/Excel.meta
#	Assets/05.TableTextConversion/Editor/Excel/I18N.meta
#	Assets/05.TableTextConversion/README.md
#	Assets/05.TableTextConversion/RunTime/Abstract.meta
#	Assets/05.TableTextConversion/RunTime/Base.meta
#	Assets/05.TableTextConversion/RunTime/Base/AudioTableData.cs.meta
#	Assets/05.TableTextConversion/RunTime/Test.cs.meta
#	Assets/05.TableTextConversion/RunTime/Use.meta
#	Assets/05.TableTextConversion/package.json
#	Assets/Plugins.meta
This commit is contained in:
2025-04-07 11:50:47 +08:00
21 changed files with 482 additions and 478 deletions

View File

@@ -1 +1 @@
# 代码检查工具
# 状态机工具

View File

@@ -0,0 +1,12 @@
fileFormatVersion: 2
<<<<<<<< HEAD:Assets/05.TableTextConversion/RunTime/Abstract.meta
guid: 3f4958b2707b1874fb59e045842881b7
========
guid: a4c1b2e6dc7695646be9fd2a98863529
>>>>>>>> 03.FiniteStateMachine:Assets/03.FiniteStateMachine/RunTime/Abstract.meta
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,87 @@
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
namespace Stary.Evo.FiniteStateMachine
{
public interface IState
{
public FSMController Machine { get; set; }
public void OnEnter();
public void OnExit();
public void Update();
public void FixedUpdate();
public void OnInit();
public void OnDestory();
}
public abstract class AbstractState : IState
{
public FSMController Machine { get; set; }
public abstract void OnEnter();
public abstract void OnExit();
public abstract void Update();
public abstract void FixedUpdate();
public abstract void OnInit();
public abstract void OnDestory();
}
/// <summary>
/// 状态中具体行为:
/// OnInitAction初始化
/// OnEnterAction进入
/// UpdateAction循环
/// FixedUpdateAction后循环
/// OnExitAction离开
/// OnDestoryAction销毁
/// </summary>
public struct StateDateAction
{
public System.Action OnEnterAction;
public System.Action OnExitAction;
public System.Action UpdateAction;
public System.Action FixedUpdateAction;
public System.Action OnInitAction;
public System.Action OnDestoryAction;
}
/// <summary>
/// 单个状态
/// </summary>
public class SingleState : AbstractState
{
public StateDateAction stateDate;
public bool IsRunning;
public override void FixedUpdate()
{
stateDate.FixedUpdateAction?.Invoke();
}
public override void OnDestory()
{
stateDate.OnDestoryAction?.Invoke();
}
public override void OnEnter()
{
stateDate.OnEnterAction?.Invoke();
}
public override void OnExit()
{
stateDate.OnExitAction?.Invoke();
}
public override void OnInit()
{
stateDate.OnInitAction?.Invoke();
}
public override void Update()
{
stateDate.UpdateAction?.Invoke();
}
}
}

View File

@@ -0,0 +1,12 @@
fileFormatVersion: 2
<<<<<<<< HEAD:Assets/05.TableTextConversion/RunTime/Base.meta
guid: f458924b47972e344ab95e73c17cec83
========
guid: 482775b04d27d6644bc8d880e135e6ac
>>>>>>>> 03.FiniteStateMachine:Assets/03.FiniteStateMachine/RunTime/Base.meta
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,135 @@
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using UnityEngine;
namespace Stary.Evo.FiniteStateMachine
{
public class FSMController : MonoBehaviour
{
private Dictionary<Type, SingleState> states = new Dictionary<Type, SingleState>();
public void AddState(SingleState state)
{
var type = state.GetType();
if (!states.ContainsKey(type))
{
// 添加时初始化
state.Machine = this;
state.OnInit();
states.Add(type, state);
}
else
{
Debug.LogError("该FSMController中已经添加过该状态");
}
}
/* //public bool IsRunning<T>() where T : SingleState => IsRunning(typeof(T));
//public void Enter<T>() where T : SingleState => Enter(typeof(T));
//public void Exit<T>() where T : SingleState => Exit(typeof(T));
//public void ForceEnter<T>() where T : SingleState => ForceEnter(typeof(T));*/
public bool IsRunning(Type type)
{
if (states.ContainsKey(type))
{
if (states[type].IsRunning) return true;
}
else
{
Debug.LogError("状态已不存在!!!");
}
return false;
}
public void Enter(Type type)
{
if (states.ContainsKey(type))
{
if (IsRunning(type))
{
Debug.LogError("该状态正在进行,无法再次进入!!!");
return;
}
ForceEnter(type);
}
else
{
Debug.LogError("状态已不存在!!!");
}
}
public void ForceEnter(Type type)
{
if (states.ContainsKey(type))
{
SingleState state = states[type];
state.OnEnter();
state.IsRunning = true;
}
else
{
Debug.LogError("状态已不存在!!!");
}
}
public void Exit(Type type)
{
if (states.TryGetValue(type, out SingleState state))
{
if (!IsRunning(type)) return;
state.IsRunning = false;
state.OnExit();
}
else
{
Debug.LogError("状态已不存在!!!");
}
}
public void ExitAll()
{
foreach (var state in states)
{
if (state.Value.IsRunning) Exit(state.Key);
}
}
private void Update()
{
foreach (var state in states)
{
if (state.Value.IsRunning) state.Value.Update();
}
}
private void FixedUpdate()
{
foreach (var state in states)
{
if (state.Value.IsRunning) state.Value.FixedUpdate();
}
}
private void OnDestroy()
{
ExitAll();
// 遍历字典中的每个状态
foreach (var key in states.Keys.ToList())
{
states[key].OnDestory();
// 将每个值设置为 null释放引用
states[key] = null;
}
// 清空字典
states.Clear();
}
}
}

View File

@@ -1,132 +0,0 @@
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using UnityEngine;
public class FSMController : MonoBehaviour
{
private Dictionary<Type, SingleState> states = new Dictionary<Type, SingleState>();
public void AddState(SingleState state)
{
var type = state.GetType();
if (!states.ContainsKey(type))
{
// 添加时初始化
state.Machine = this;
state.OnInit();
states.Add(type, state);
}
else
{
Debug.LogError("该FSMController中已经添加过该状态");
}
}
/* //public bool IsRunning<T>() where T : SingleState => IsRunning(typeof(T));
//public void Enter<T>() where T : SingleState => Enter(typeof(T));
//public void Exit<T>() where T : SingleState => Exit(typeof(T));
//public void ForceEnter<T>() where T : SingleState => ForceEnter(typeof(T));*/
public bool IsRunning(Type type)
{
if (states.ContainsKey(type))
{
if (states[type].IsRunning) return true;
}
else
{
Debug.LogError("状态已不存在!!!");
}
return false;
}
public void Enter(Type type)
{
if (states.ContainsKey(type))
{
if (IsRunning(type))
{
Debug.LogError("该状态正在进行,无法再次进入!!!");
return;
}
ForceEnter(type);
}
else
{
Debug.LogError("状态已不存在!!!");
}
}
public void ForceEnter(Type type)
{
if (states.ContainsKey(type))
{
SingleState state = states[type];
state.OnEnter();
state.IsRunning = true;
}
else
{
Debug.LogError("状态已不存在!!!");
}
}
public void Exit(Type type)
{
if (states.TryGetValue(type, out SingleState state))
{
if (!IsRunning(type)) return;
state.IsRunning = false;
state.OnExit();
}
else
{
Debug.LogError("状态已不存在!!!");
}
}
public void ExitAll()
{
foreach (var state in states)
{
if (state.Value.IsRunning) Exit(state.Key);
}
}
private void Update()
{
foreach (var state in states)
{
if (state.Value.IsRunning) state.Value.Update();
}
}
private void FixedUpdate()
{
foreach (var state in states)
{
if (state.Value.IsRunning) state.Value.FixedUpdate();
}
}
private void OnDestroy()
{
ExitAll();
// 遍历字典中的每个状态
foreach (var key in states.Keys.ToList())
{
states[key].OnDestory();
// 将每个值设置为 null释放引用
states[key] = null;
}
// 清空字典
states.Clear();
}
}

View File

@@ -1,46 +0,0 @@
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using UnityEngine;
using UnityEngine.SceneManagement;
public static class FSMInitialize
{
/// <summary>
/// 状态机初始化
/// </summary>
/// <param name="targetScene">指定场景</param>
/// <returns></returns>
public static FSMManager Init(Scene targetScene)
{
GameObject targetObject = targetScene.GetRootGameObjects().FirstOrDefault(go => go.name == "FSMManger");
FSMManager fSMManager;
if (targetObject == null)
{
targetObject = new GameObject("FSMManger");
SceneManager.MoveGameObjectToScene(targetObject, targetScene);
fSMManager = new FSMManager();
fSMManager.FSMMangerObject = targetObject;
void OnSceneUnloaded(Scene scene)
{
// 当场景卸载时释放缓存
if (scene.name == targetScene.name)
{
GameObject.Destroy(targetObject);
fSMManager = null;
}
}
SceneManager.sceneUnloaded += OnSceneUnloaded;
return fSMManager;
}
else
{
Debug.LogError("场景: "+targetScene.name + "已经初始化过FSM状态机");
return null;
}
}
}

View File

@@ -1,146 +0,0 @@
using System;
using System.Collections.Generic;
using UnityEngine;
public class FSMManager
{
public GameObject FSMMangerObject;
private Dictionary<int, FSMController> controllers = new Dictionary<int, FSMController>();
private Dictionary<int, SingleState> states = new Dictionary<int, SingleState>();
private int nextControllerId = 0;
private int nextStateId = 0;
/// <summary>
/// 创建FSMController
/// </summary>
/// <returns>返回创建的FSMController的识别Int值</returns>
public int CreateFSMController()
{
if(FSMMangerObject == null)
{
Debug.LogError("FSM状态机还未初始化");
return -1;
}
else
{
int id = nextControllerId++;
GameObject newController = new GameObject("FSMController" + id);
newController.transform.SetParent(FSMMangerObject.transform);
var controller = newController.AddComponent<FSMController>();
controllers[id] = controller;
return id;
}
}
/// <summary>
/// 销毁指定FSMController
/// </summary>
/// <param name="controllerId"></param>
public void DestroyFSMController(int controllerId)
{
if (controllers.TryGetValue(controllerId, out var controller))
{
GameObject.Destroy(controller.gameObject);
controllers.Remove(controllerId);
}
else
{
Debug.LogError("该Id的FSMController不存在或已被销毁");
}
}
/// <summary>
/// 退出指定Controller中的所有状态
/// </summary>
/// <param name="controllerId"></param>
public void ExitAllStateInController(int controllerId)
{
if (controllers.TryGetValue(controllerId, out var controller))
{
controller.ExitAll();
}
else
{
Debug.LogError("该Id的FSMController不存在或已被销毁");
}
}
/// <summary>
/// 创建状态
/// </summary>
/// <param name="controllerId">状态挂载的ControllerId</param>
/// <param name="stateDateAction">状态行为数据</param>
/// <returns></returns>
public int CreateState(int controllerId, StateDateAction stateDateAction)
{
if (controllers.TryGetValue(controllerId, out var controller))
{
// 创建state并将其添加到指定controller生命周期中
SingleState state = new SingleState();
state.stateDate = stateDateAction;
controller.AddState(state);
int id = nextStateId++;
states[id] = state;
return id;
}
else
{
Debug.LogError("该Id的FSMController不存在或已被销毁状态初始化失败");
return -1;
}
}
/// <summary>
/// 进入指定状态
/// </summary>
/// <param name="stateId"></param>
public void EnterState(int stateId)
{
if(states.TryGetValue(stateId, out var state))
{
state.Machine.Enter(state.GetType());
}
else
{
Debug.LogError("该Id的状态不存在");
}
}
/// <summary>
/// 离开指定状态
/// </summary>
/// <param name="stateId"></param>
public void ExitState(int stateId)
{
if (states.TryGetValue(stateId, out var state))
{
state.Machine.Exit(state.GetType());
}
else
{
Debug.LogError("该Id的状态不存在");
}
}
/// <summary>
/// 销毁指定状态
/// </summary>
/// <param name="stateId"></param>
public void DestroyState(int stateId)
{
if (states.TryGetValue(stateId, out var state))
{
states.Remove(stateId);
}
}
// 将状态添加到FSMController
public void AddStateToController(int controllerId, int stateId)
{
if (controllers.TryGetValue(controllerId, out var controller) && states.TryGetValue(stateId, out var state))
{
controller.AddState(state);
}
}
}

View File

@@ -0,0 +1,3 @@
{
"name": "FiniteStateMachine.RunTime"
}

View File

@@ -0,0 +1,15 @@
fileFormatVersion: 2
<<<<<<<< HEAD:Assets/05.TableTextConversion/Editor/Excel/I18N.meta
guid: a0ddbcdd27271534b8277ca2bddffca7
folderAsset: yes
timeCreated: 1531104110
licenseType: Pro
DefaultImporter:
========
guid: fd2529d4be47388488cf47fbdd0ee1bf
AssemblyDefinitionImporter:
>>>>>>>> 03.FiniteStateMachine:Assets/03.FiniteStateMachine/RunTime/FiniteStateMachine.RunTime.asmdef.meta
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -1,84 +0,0 @@
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public interface IState
{
public FSMController Machine { get; set; }
public void OnEnter();
public void OnExit();
public void Update();
public void FixedUpdate();
public void OnInit();
public void OnDestory();
}
public abstract class AbstractState : IState
{
public FSMController Machine { get; set; }
public abstract void OnEnter();
public abstract void OnExit();
public abstract void Update();
public abstract void FixedUpdate();
public abstract void OnInit();
public abstract void OnDestory();
}
/// <summary>
/// 状态中具体行为:
/// OnInitAction初始化
/// OnEnterAction进入
/// UpdateAction循环
/// FixedUpdateAction后循环
/// OnExitAction离开
/// OnDestoryAction销毁
/// </summary>
public struct StateDateAction
{
public System.Action OnEnterAction;
public System.Action OnExitAction;
public System.Action UpdateAction;
public System.Action FixedUpdateAction;
public System.Action OnInitAction;
public System.Action OnDestoryAction;
}
/// <summary>
/// 单个状态
/// </summary>
public class SingleState : AbstractState
{
public StateDateAction stateDate;
public bool IsRunning;
public override void FixedUpdate()
{
stateDate.FixedUpdateAction?.Invoke();
}
public override void OnDestory()
{
stateDate.OnDestoryAction?.Invoke();
}
public override void OnEnter()
{
stateDate.OnEnterAction?.Invoke();
}
public override void OnExit()
{
stateDate.OnExitAction?.Invoke();
}
public override void OnInit()
{
stateDate.OnInitAction?.Invoke();
}
public override void Update()
{
stateDate.UpdateAction?.Invoke();
}
}

View File

@@ -1,53 +0,0 @@
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.SceneManagement;
public class PlayerFSMExample : MonoBehaviour
{
private int controllerId;
private int idleStateId;
private float timer = 0.0f;
private FSMManager fSMManager;
void Start()
{
fSMManager = FSMInitialize.Init(gameObject.scene);
controllerId = fSMManager.CreateFSMController();
StateDateAction stateDateAction = new StateDateAction()
{
OnEnterAction = () =>
{
Debug.Log("进入状态");
},
UpdateAction = () =>
{
timer += Time.deltaTime;
Debug.Log("当前时间:" + timer);
},
OnExitAction = () =>
{
Debug.Log("离开状态");
}
};
idleStateId = fSMManager.CreateState(controllerId, stateDateAction);
}
void Update()
{
// 按下空格键切换到Running状态
if (Input.GetKeyDown(KeyCode.A))
{
fSMManager.EnterState(idleStateId);
}
if (Input.GetKeyDown(KeyCode.D))
{
fSMManager.ExitState(idleStateId);
}
}
void OnDestroy()
{
}
}

View File

@@ -1,11 +0,0 @@
fileFormatVersion: 2
guid: 0deab708fd53bb4428ef48220df57be7
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,12 @@
fileFormatVersion: 2
<<<<<<<< HEAD:Assets/05.TableTextConversion/RunTime/Use.meta
guid: 102768b9489625641a18c187eac264be
========
guid: bacf497398db3124994cae839e813842
>>>>>>>> 03.FiniteStateMachine:Assets/03.FiniteStateMachine/RunTime/Use.meta
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,50 @@
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using UnityEngine;
using UnityEngine.SceneManagement;
namespace Stary.Evo.FiniteStateMachine
{
public static class FSMInitialize
{
/// <summary>
/// 状态机初始化
/// </summary>
/// <param name="targetScene">指定场景</param>
/// <returns></returns>
public static FSMManager Init(Scene targetScene)
{
GameObject targetObject = targetScene.GetRootGameObjects().FirstOrDefault(go => go.name == "FSMManger");
FSMManager fSMManager;
if (targetObject == null)
{
targetObject = new GameObject("FSMManger");
SceneManager.MoveGameObjectToScene(targetObject, targetScene);
fSMManager = new FSMManager();
fSMManager.FSMMangerObject = targetObject;
void OnSceneUnloaded(Scene scene)
{
// 当场景卸载时释放缓存
if (scene.name == targetScene.name)
{
GameObject.Destroy(targetObject);
fSMManager = null;
}
}
SceneManager.sceneUnloaded += OnSceneUnloaded;
return fSMManager;
}
else
{
Debug.LogError("场景: " + targetScene.name + "已经初始化过FSM状态机");
return null;
}
}
}
}

View File

@@ -0,0 +1,150 @@
using System;
using System.Collections.Generic;
using UnityEngine;
namespace Stary.Evo.FiniteStateMachine
{
public class FSMManager
{
public GameObject FSMMangerObject;
private Dictionary<int, FSMController> controllers = new Dictionary<int, FSMController>();
private Dictionary<int, SingleState> states = new Dictionary<int, SingleState>();
private int nextControllerId = 0;
private int nextStateId = 0;
/// <summary>
/// 创建FSMController
/// </summary>
/// <returns>返回创建的FSMController的识别Int值</returns>
public int CreateFSMController()
{
if (FSMMangerObject == null)
{
Debug.LogError("FSM状态机还未初始化");
return -1;
}
else
{
int id = nextControllerId++;
GameObject newController = new GameObject("FSMController" + id);
newController.transform.SetParent(FSMMangerObject.transform);
var controller = newController.AddComponent<FSMController>();
controllers[id] = controller;
return id;
}
}
/// <summary>
/// 销毁指定FSMController
/// </summary>
/// <param name="controllerId"></param>
public void DestroyFSMController(int controllerId)
{
if (controllers.TryGetValue(controllerId, out var controller))
{
GameObject.Destroy(controller.gameObject);
controllers.Remove(controllerId);
}
else
{
Debug.LogError("该Id的FSMController不存在或已被销毁");
}
}
/// <summary>
/// 退出指定Controller中的所有状态
/// </summary>
/// <param name="controllerId"></param>
public void ExitAllStateInController(int controllerId)
{
if (controllers.TryGetValue(controllerId, out var controller))
{
controller.ExitAll();
}
else
{
Debug.LogError("该Id的FSMController不存在或已被销毁");
}
}
/// <summary>
/// 创建状态
/// </summary>
/// <param name="controllerId">状态挂载的ControllerId</param>
/// <param name="stateDateAction">状态行为数据</param>
/// <returns></returns>
public int CreateState(int controllerId, StateDateAction stateDateAction)
{
if (controllers.TryGetValue(controllerId, out var controller))
{
// 创建state并将其添加到指定controller生命周期中
SingleState state = new SingleState();
state.stateDate = stateDateAction;
controller.AddState(state);
int id = nextStateId++;
states[id] = state;
return id;
}
else
{
Debug.LogError("该Id的FSMController不存在或已被销毁状态初始化失败");
return -1;
}
}
/// <summary>
/// 进入指定状态
/// </summary>
/// <param name="stateId"></param>
public void EnterState(int stateId)
{
if (states.TryGetValue(stateId, out var state))
{
state.Machine.Enter(state.GetType());
}
else
{
Debug.LogError("该Id的状态不存在");
}
}
/// <summary>
/// 离开指定状态
/// </summary>
/// <param name="stateId"></param>
public void ExitState(int stateId)
{
if (states.TryGetValue(stateId, out var state))
{
state.Machine.Exit(state.GetType());
}
else
{
Debug.LogError("该Id的状态不存在");
}
}
/// <summary>
/// 销毁指定状态
/// </summary>
/// <param name="stateId"></param>
public void DestroyState(int stateId)
{
if (states.TryGetValue(stateId, out var state))
{
states.Remove(stateId);
}
}
// 将状态添加到FSMController
public void AddStateToController(int controllerId, int stateId)
{
if (controllers.TryGetValue(controllerId, out var controller) && states.TryGetValue(stateId, out var state))
{
controller.AddState(state);
}
}
}
}

View File

@@ -1,10 +1,10 @@
{
"name": "com.staryevo.codechecker",
"version": "1.0.0",
"displayName": "01.CodeChecker",
"description": "代码检查工具",
"name": "com.staryevo.finitestatemachine",
"version": "1.0.1",
"displayName": "03.FiniteStateMachine",
"description": "状态机工具",
"unity": "2021.3",
"unityRelease": "30f1",
"unityRelease": "23f1",
"keywords": [
"unity",
"scirpt"