using System; using System.Collections.Generic; using System.Text; using UnityEditor; using UnityEngine; namespace XFFSM { [System.Serializable] public class FSMStateScriptInfo { public string className; public string guid; } [System.Serializable] public class FSMStateNodeData { #if UNITY_EDITOR public Rect rect; public void AddStateScript(MonoScript script) { string guid = AssetDatabase.AssetPathToGUID( AssetDatabase.GetAssetPath(script)); if (string.IsNullOrEmpty(guid)) throw new System.Exception(string.Format("脚本添加失败,获取guid失败:{0}",script.name)); foreach (var item in StateScripts) { if (item.guid.Equals(guid)) throw new System.Exception("脚本重复添加!"); } FSMStateScriptInfo info = new FSMStateScriptInfo(); info.guid = guid; Type type = script.GetClass(); if (type != null) { info.className = type.FullName; } StateScripts.Add(info); } public void RefreshStateScripts(RuntimeFSMController controller) { //EditorApplication. List invalid = new List(); foreach (var item in StateScripts) { if (string.IsNullOrEmpty(item.guid) && !string.IsNullOrEmpty(item.className)) item.guid = AssemblyTools.GetGUIDByStateClassFullName(item.className); string path = AssetDatabase.GUIDToAssetPath(item.guid); if (string.IsNullOrEmpty(path)) { invalid.Add(item); continue; } MonoScript script = AssetDatabase.LoadAssetAtPath(path); if (script == null) { //Debug.LogFormat("添加无效脚本:{0} guid:{1}", script.name, path); //invalid.Add(item); continue; } Type type = script.GetClass(); // 如果等于空或者没有继承自FSMState视为无效 if (type == null) { //invalid.Add(item); continue; } item.className = type.FullName; } // 移除无效的脚本 ( 这些脚本可能已经被删除了 ) foreach (var item in invalid) { StateScripts.Remove(item); } if(controller != null) controller.Save(); } public void RemoveStateScript(MonoScript script) { Type type = script.GetClass(); if (type == null) return; string guid = AssetDatabase.AssetPathToGUID(AssetDatabase.GetAssetPath(script)); if (string.IsNullOrEmpty(guid)) throw new System.Exception(string.Format("脚本添加失败,获取guid失败:{0}", script.name)); FSMStateScriptInfo info = null; foreach (var item in StateScripts) { if (item.guid.Equals(guid)) { info = item; break; } } if (info == null) return; StateScripts.Remove(info); } #endif /// /// 是否是默认状态 /// public bool defaultState; /// /// 名称 /// public string name; /// /// 状态脚本的名称 /// public List StateScripts = new List(); /// /// 当前状态的父节点名称 /// public List parents; /// /// 是否为子状态机 /// public bool isSubStateMachine = false; /// /// 是否为内置状态 /// public bool isBuildInState = false; /// /// 内置状态名称 /// public string buildInStateName = null; #region 属性 /// /// 判断当前状态是否为Any状态 /// public bool IsAnyState { get { if (name.Equals(FSMConst.anyState)) return true; if (isBuildInState && buildInStateName.Equals(FSMConst.anyState)) return true; return false; } } /// /// 判断当前状态是否Entry状态 /// public bool IsEntryState { get { if (name.Equals(FSMConst.entryState)) return true; if (isBuildInState && buildInStateName.Equals(FSMConst.entryState)) return true; return false; } } /// /// 判断是否为返回上一层的按钮 /// public bool IsUpState { get { if (isBuildInState && buildInStateName.Equals(FSMConst.up)) return true; return false; } } public string DisplayName { get { if (IsAnyState) return FSMConst.anyState; if (IsEntryState) return FSMConst.entryState; if (IsUpState) { if (parents.Count > 1) return string.Format("(Up){0}", parents[parents.Count - 2]); else return "(Up)Base Layer"; } return name; } } public string ParentPath { get { if (parents == null || parents.Count == 0) return string.Empty; StringBuilder sb = new StringBuilder(); for (int i = 0; i < parents.Count; i++) { sb.Append(parents[i]); if (i < parents.Count - 1) sb.Append("/"); } return sb.ToString(); } } public string NextParentPath { get { List next_parents = new List(); if (parents != null && parents.Count != 0) next_parents.AddRange(parents); next_parents.Add(name); StringBuilder sb = new StringBuilder(); for (int i = 0; i < next_parents.Count; i++) { sb.Append(next_parents[i]); if (i < next_parents.Count - 1) sb.Append("/"); } return sb.ToString(); } } public string Parent { get { if (parents == null || parents.Count == 0) return string.Empty; return parents[parents.Count - 1]; } } #endregion public bool CompareParent(FSMStateNodeData node) { if (BaseLayer() && node.BaseLayer()) return true; if(parents == null || node.parents == null) return false; if (node.parents.Count != this.parents.Count) return false; for (int i = 0; i < parents.Count; i++) { if (!parents[i].Equals(node.parents[i])) return false; } return true; } public bool CompareParent(List parents) { if (BaseLayer()) return parents == null || parents.Count == 0; if (parents == null || this.parents == null) return false; if (parents.Count != this.parents.Count) return false; for (int i = 0; i < this.parents.Count; i++) { if (!this.parents[i].Equals(parents[i])) return false; } return true; } public bool BaseLayer() { return this.parents == null || this.parents.Count == 0; } public bool ContainsParent(string parent) { if(BaseLayer()) return false; return parents.Contains(parent); } public bool BelongToParent(string parent) { if(BaseLayer()) return false; return parents[parents.Count - 1].Equals(parent); } public void RenameParent(string oldParent, string newName) { int index = parents.IndexOf(oldParent); parents[index] = newName; } public List GetParent() { List parents = new List(); if (parents == null) return parents; parents.AddRange(this.parents); return parents; } } }