using System; using System.Collections.Generic; using UnityEngine; namespace XFFSM { public class FSMController : MonoBehaviour { #region 字段 [SerializeField] private List _runtimeFSMController = new List(); internal object userData; private List Instances = new List(); private List runtimeControllers = new List(); [SerializeField] [Tooltip("是否在OnDisable时重置状态机")] [Header("是否在OnDisable时重置状态机")] private bool resetOnDisable = true; #endregion #region 事件 /// /// 初始化完成的回调 /// public Action onInitFinish; /// /// 状态改变的回调 参数1:状态机名称 参数2:当前状态 /// public Action onStateChange; #endregion #region 属性 /// /// 当前状态机执行的状态配置文件列表 /// public List RuntimeFSMController { get { if (Application.isPlaying) { return runtimeControllers; } return _runtimeFSMController; } } /// /// 状态机是否初始化完成 /// public bool Initialized { get; private set; } = false; #endregion #region 生命周期 public void DoUpdate() { if (!Initialized) return; foreach (var item in Instances) { // 如果没有启动 就启动一下 if(!item.Started) item.StartUp(); item.Update(); } } // protected void LateUpdate() // { // if (!Initialized) // return; // foreach (var item in Instances) // { // item.LateUpdate(); // } // } // // protected void FixedUpdate() // { // if (!Initialized) // return; // foreach (var item in Instances) // { // item.FixedUpdate(); // } // } private void OnDestroy() { if (!Initialized) return; foreach (var item in Instances) { item.Close(); } } private void OnDisable() { if (!Initialized) return; if (resetOnDisable) { foreach (var item in Instances) { item.Close(); } } } #endregion #region 方法 // 初始化 public void Init(object userData) { if (Initialized) return; Instances.Clear(); runtimeControllers.Clear(); this.userData = userData; foreach (var item in _runtimeFSMController) { if (item == null) continue; RuntimeFSMControllerInstance instance = new RuntimeFSMControllerInstance(item, this); instance.StartUp(); runtimeControllers.Add(instance.RuntimeFSMController); Instances.Add(instance); } Initialized = true; onInitFinish?.Invoke(); } /// /// 设置bool类型参数的值 /// /// 参数名称 /// 值 public void SetBool(string name, bool v) { if (Initialized) { if (!IsContainParameter(name, ParameterType.Bool)) { Debug.LogWarningFormat("未查询到参数:{0} 类型:{1}",name, ParameterType.Bool); return; } foreach (var item in Instances) { item.SetBool(name, v); } } else { onInitFinish += () => { if (!IsContainParameter(name, ParameterType.Bool)) { Debug.LogWarningFormat("未查询到参数:{0} 类型:{1}", name, ParameterType.Bool); return; } foreach (var item in Instances) { item.SetBool(name, v); } }; } } /// /// 设置float类型参数的值 /// /// 参数名称 /// 值 public void SetFloat(string name, float v) { if (Initialized) { if (!IsContainParameter(name, ParameterType.Float)) { Debug.LogWarningFormat("未查询到参数:{0} 类型:{1}", name, ParameterType.Float); return; } foreach (var item in Instances) { item.SetFloat(name, v); } } else { onInitFinish += () => { if (!IsContainParameter(name, ParameterType.Float)) { Debug.LogWarningFormat("未查询到参数:{0} 类型:{1}", name, ParameterType.Float); return; } foreach (var item in Instances) { item.SetFloat(name, v); } }; } } /// /// 设置Int类型参数的值 /// /// 参数名称 /// 值 public void SetInt(string name, int v) { if (Initialized) { if (!IsContainParameter(name, ParameterType.Int)) { Debug.LogWarningFormat("未查询到参数:{0} 类型:{1}", name, ParameterType.Int); return; } foreach (var item in Instances) { item.SetInt(name, v); } } else { onInitFinish += () => { if (!IsContainParameter(name, ParameterType.Int)) { Debug.LogWarningFormat("未查询到参数:{0} 类型:{1}", name, ParameterType.Int); return; } foreach (var item in Instances) { item.SetInt(name, v); } }; } } /// /// 触发Trigger /// /// Trigger名称 public void SetTrigger(string name) { if (Initialized) { if (!IsContainParameter(name, ParameterType.Trigger)) { Debug.LogWarningFormat("未查询到参数:{0} 类型:{1}", name, ParameterType.Trigger); return; } foreach (var item in Instances) { item.SetTrigger(name); } } else { onInitFinish += () => { if (!IsContainParameter(name, ParameterType.Trigger)) { Debug.LogWarningFormat("未查询到参数:{0} 类型:{1}", name, ParameterType.Trigger); return; } foreach (var item in Instances) { item.SetTrigger(name); } }; } } /// /// 还原Trigger /// /// Trigger名称 public void ResetTrigger(string name) { foreach (var item in Instances) { item.ResetTrigger(name); } } /// /// 获取Bool类型参数的值 /// /// 参数名称 /// public bool GetBool(string name) { foreach (var item in Instances) { if (item.GetParamter(name) == 1) return true; } return false; } /// /// 获取Float类型参数的值 /// /// 参数名称 /// public float GetFloat(string name ) { foreach (var item in Instances) { float v = item.GetParamter(name); if (v != 0) return v; } return 0; } /// /// 获取Int类型参数的值 /// /// 参数名称 /// public int GetInt(string name) { foreach (var item in Instances) { int v = (int)(item.GetParamter(name)); if (v != 0) return v; } return 0; } /// /// 获取Trigger类型参数的值 /// /// 参数名称 /// public bool GetTrigger(string name ) { foreach (var item in Instances) { if (item.GetTriggerCount(name) > 0 || item.GetParamter(name) == 1) return true; } return false; } private bool IsContainParameter(string name,ParameterType type) { foreach (var item in Instances) { if(item.parameters.ContainsKey(name) && item.parameters[name].parameterType == type) return true; } return false; } /// /// 运行时添加并执行状态配置文件 /// /// public void AddRuntimeFSMController(RuntimeFSMController controller) { if (_runtimeFSMController.Contains(controller)) { Debug.LogWarningFormat("状态机:{0}已经执行,请勿重复添加!", controller.name); return; // 说明已经添加了该状态机 } _runtimeFSMController.Add(controller); // 如果没有初始化完成 不需要处理 在初始化的时候会处理 if (Initialized) { // 如果初始化完成了 启动这个状态 RuntimeFSMControllerInstance controllerInstance = new RuntimeFSMControllerInstance(controller, this); controllerInstance.StartUp(); runtimeControllers.Add(controllerInstance.RuntimeFSMController); Instances.Add(controllerInstance); } } /// /// 运行时移除状态机配置文件 /// /// 配置文件下标 public void RemoveRuntimeFSMController(int index) { if (index < 0 || index >= RuntimeFSMController.Count) return; RuntimeFSMController controller = RuntimeFSMController[index]; RuntimeFSMController.RemoveAt(index); for (int i = 0; i < Instances.Count; i++) { if (Instances[i].RuntimeFSMController == controller) { Instances[i].Close(); Instances.Remove(Instances[i]); break; } } } /// /// 获取当前正在执行的状态信息 /// /// 状态配置下标 /// 子状态机名称(默认:空) /// public FSMStateNode GetCurrentStateInfo(int index,string subStateName = "") { if (index < 0 || index >= Instances.Count) return null; return Instances[index].GetCurrentState(subStateName); } public FSMStateNode GetCurrentStateInfo(string controllerName, string subStateName = "") { if (string.IsNullOrEmpty(controllerName)) return null; foreach (var item in Instances) { if (item.name.Equals(controllerName)) return item.GetCurrentState(subStateName); } return null; } /// /// 获取当前的状态切换信息 /// /// /// public FSMTransition GetCurrentTransition(int index) { if (index < 0 || index >= Instances.Count) return null; return Instances[index].currentTransition; } #endregion #region 静态字段 private static Dictionary fsms = new Dictionary(); #endregion #region 静态属性 private static Transform FSMParent { get; set; } #endregion #region 静态方法 [RuntimeInitializeOnLoadMethod] static void InitFSMController() { fsms.Clear(); GameObject obj = new GameObject("FSMControllers"); DontDestroyOnLoad(obj); FSMParent = obj.transform; } /// /// 启动状态(适用于没有具体游戏物体的状态管理,例如:游戏状态) /// /// 状态机名称 /// 状态配置文件 /// 自定义参数或数据 /// public static FSMController StartupFSM(string fsmName,RuntimeFSMController fsm,object userData = null) { if (fsms.ContainsKey(fsmName)) return null; GameObject obj = new GameObject(fsmName); obj.transform.SetParent(FSMParent,false); FSMController controller = obj.AddComponent(); controller.userData = userData; controller.AddRuntimeFSMController(fsm); fsms.Add(fsmName, controller); return controller; } /// /// 查询通过FSMController.StartupFSM启动的状态机 /// /// 状态机名称 /// public static FSMController GetFSM(string fsmName) { if(fsms.ContainsKey(fsmName)) return fsms[fsmName]; return null; } /// /// 移除通过FSMController.StartupFSM启动的状态机 /// /// 状态机名称 public static void RemoveFSM(string fsmName) { if (!fsms.ContainsKey(fsmName)) return; FSMController controller = fsms[fsmName]; fsms.Remove(fsmName); Destroy(controller.gameObject); } #endregion } }