protected override void OnRuntimeEnable() { base.OnRuntimeEnable(); Dictionary <Type, FiniteStateBase> states = Target.GetType().GetField("_stateInstances", BindingFlags.Instance | BindingFlags.NonPublic).GetValue(Target) as Dictionary <Type, FiniteStateBase>; _stateInstances = new Dictionary <string, Type>(); foreach (var state in states) { FiniteStateNameAttribute attribute = state.Key.GetCustomAttribute <FiniteStateNameAttribute>(); _stateInstances.Add(attribute != null ? attribute.Name : state.Key.Name, state.Key); } FiniteStateNameAttribute nameAttribute = Target.CurrentState.GetType().GetCustomAttribute <FiniteStateNameAttribute>(); _currentStateName = nameAttribute != null ? nameAttribute.Name : Target.CurrentState.GetType().Name; }
protected override void OnPlayingEnable() { base.OnPlayingEnable(); Dictionary <Type, FiniteState> states = _target.GetType().GetField("_stateInstances", BindingFlags.Instance | BindingFlags.NonPublic).GetValue(_target) as Dictionary <Type, FiniteState>; _stateInstances = new Dictionary <string, Type>(); foreach (KeyValuePair <Type, FiniteState> state in states) { FiniteStateNameAttribute attribute = state.Key.GetCustomAttribute <FiniteStateNameAttribute>(); _stateInstances.Add(attribute != null ? attribute.Name : state.Key.Name, state.Key); } _currentState = _target.GetType().GetField("_currentState", BindingFlags.Instance | BindingFlags.NonPublic).GetValue(_target) as FiniteState; FiniteStateNameAttribute nameAttribute = _currentState.GetType().GetCustomAttribute <FiniteStateNameAttribute>(); _currentStateName = nameAttribute != null ? nameAttribute.Name : _currentState.GetType().Name; }
protected override void OnPlayingInspectorGUI() { base.OnPlayingInspectorGUI(); GUILayout.BeginVertical("Helpbox"); GUILayout.BeginHorizontal(); GUILayout.Label("Runtime Data", "BoldLabel"); GUILayout.EndHorizontal(); GUILayout.BeginHorizontal(); GUILayout.Label("Current State: " + _currentStateName); GUILayout.EndHorizontal(); GUILayout.BeginHorizontal(); GUILayout.Label("States: "); GUILayout.EndHorizontal(); foreach (KeyValuePair <string, Type> state in _stateInstances) { GUILayout.BeginHorizontal(); GUILayout.Space(20); GUILayout.Label(state.Key); GUILayout.FlexibleSpace(); GUI.enabled = _currentStateName != state.Key; if (GUILayout.Button("Switch", "Minibutton")) { _target.SwitchState(state.Value); _currentState = _target.GetType().GetField("_currentState", BindingFlags.Instance | BindingFlags.NonPublic).GetValue(_target) as FiniteState; FiniteStateNameAttribute nameAttribute = _currentState.GetType().GetCustomAttribute <FiniteStateNameAttribute>(); _currentStateName = nameAttribute != null ? nameAttribute.Name : _currentState.GetType().Name; } GUI.enabled = true; GUILayout.EndHorizontal(); } GUILayout.EndVertical(); }
protected override void OnInspectorDefaultGUI() { base.OnInspectorDefaultGUI(); GUILayout.BeginHorizontal(); EditorGUILayout.HelpBox("State Count:" + Target.StateNames.Count, MessageType.Info); GUILayout.EndHorizontal(); GUILayout.BeginHorizontal(); Toggle(Target.IsAutoRegister, out Target.IsAutoRegister, "Auto Register"); GUILayout.EndHorizontal(); GUILayout.BeginHorizontal(); GUILayout.Label("Name: "); TextField(Target.Name, out Target.Name); GUILayout.EndHorizontal(); GUILayout.BeginHorizontal(); GUILayout.Label("Data: "); if (GUILayout.Button(Target.Data, "MiniPopup")) { GenericMenu gm = new GenericMenu(); List <Type> types = GlobalTools.GetTypesInRunTimeAssemblies(); gm.AddItem(new GUIContent("<None>"), Target.Data == "<None>", () => { Undo.RecordObject(target, "Set FSM Data Class"); Target.Data = "<None>"; HasChanged(); }); for (int i = 0; i < types.Count; i++) { if (types[i].IsSubclassOf(typeof(FSMData))) { int j = i; gm.AddItem(new GUIContent(types[j].FullName), Target.Data == types[j].FullName, () => { Undo.RecordObject(target, "Set FSM Data Class"); Target.Data = types[j].FullName; HasChanged(); }); } } gm.ShowAsContext(); } GUILayout.EndHorizontal(); GUILayout.BeginHorizontal(); GUI.enabled = Target.DefaultStateName != ""; GUILayout.Label("Default: " + Target.DefaultStateName); GUI.enabled = true; GUILayout.FlexibleSpace(); GUI.enabled = Target.StateNames.Count > 0; if (GUILayout.Button("Set Default", "MiniPopup")) { GenericMenu gm = new GenericMenu(); for (int i = 0; i < Target.StateNames.Count; i++) { int j = i; gm.AddItem(new GUIContent(Target.StateNames[j]), Target.DefaultStateName == Target.StateNames[j], () => { Undo.RecordObject(target, "Set FSM Default State"); Target.DefaultState = Target.States[j]; Target.DefaultStateName = Target.StateNames[j]; HasChanged(); }); } gm.ShowAsContext(); } GUI.enabled = true; GUILayout.EndHorizontal(); for (int i = 0; i < Target.StateNames.Count; i++) { GUILayout.BeginHorizontal(); GUILayout.Label(string.Format("{0}.{1}", i + 1, Target.StateNames[i])); GUILayout.FlexibleSpace(); if (GUILayout.Button("Edit", "minibuttonleft")) { if (_stateTypes.ContainsKey(Target.States[i])) { UnityEngine.Object classFile = AssetDatabase.LoadAssetAtPath(_stateTypes[Target.States[i]], typeof(TextAsset)); if (classFile) { AssetDatabase.OpenAsset(classFile); } else { GlobalTools.LogError("没有找到 " + Target.States[i] + " 脚本文件!"); } } else { GlobalTools.LogError("没有找到 " + Target.States[i] + " 脚本文件!"); } } if (GUILayout.Button("Delete", "minibuttonright")) { Undo.RecordObject(target, "Delete FSM State"); if (Target.DefaultStateName == Target.StateNames[i]) { Target.DefaultState = ""; Target.DefaultStateName = ""; } Target.States.RemoveAt(i); Target.StateNames.RemoveAt(i); if (Target.DefaultStateName == "" && Target.StateNames.Count > 0) { Target.DefaultState = Target.States[0]; Target.DefaultStateName = Target.StateNames[0]; } HasChanged(); } GUILayout.EndHorizontal(); } GUILayout.BeginHorizontal(); if (GUILayout.Button("Add State", "MiniPopup")) { GenericMenu gm = new GenericMenu(); List <Type> types = GlobalTools.GetTypesInRunTimeAssemblies(); for (int i = 0; i < types.Count; i++) { if (types[i].IsSubclassOf(typeof(FiniteState))) { int j = i; string stateName = types[j].FullName; FiniteStateNameAttribute fsmAtt = types[j].GetCustomAttribute <FiniteStateNameAttribute>(); if (fsmAtt != null) { stateName = fsmAtt.Name; } if (Target.States.Contains(types[j].FullName)) { gm.AddDisabledItem(new GUIContent(stateName)); } else { gm.AddItem(new GUIContent(stateName), false, () => { Undo.RecordObject(target, "Add FSM State"); Target.States.Add(types[j].FullName); Target.StateNames.Add(stateName); if (Target.DefaultStateName == "") { Target.DefaultState = Target.States[0]; Target.DefaultStateName = Target.StateNames[0]; } HasChanged(); }); } } } gm.ShowAsContext(); } GUILayout.EndHorizontal(); }
protected override void OnInspectorDefaultGUI() { base.OnInspectorDefaultGUI(); GUILayout.BeginHorizontal(); EditorGUILayout.HelpBox("Finite state machine!", MessageType.Info); GUILayout.EndHorizontal(); GUILayout.BeginHorizontal(); Toggle(Target.IsAutoRegister, out Target.IsAutoRegister, "Auto Register"); GUILayout.EndHorizontal(); GUILayout.BeginHorizontal(); TextField(Target.Name, out Target.Name, "Name"); GUILayout.EndHorizontal(); GUILayout.BeginHorizontal(); TextField(Target.Group, out Target.Group, "Group"); GUILayout.EndHorizontal(); GUILayout.BeginHorizontal(); GUI.color = Target.Data == "<None>" ? Color.gray : Color.white; GUILayout.Label("Data", GUILayout.Width(60)); if (GUILayout.Button(Target.Data, EditorGlobalTools.Styles.MiniPopup)) { GenericMenu gm = new GenericMenu(); gm.AddItem(new GUIContent("<None>"), Target.Data == "<None>", () => { Undo.RecordObject(target, "Set FSM Data Class"); Target.Data = "<None>"; HasChanged(); }); List <Type> types = ReflectionToolkit.GetTypesInRunTimeAssemblies(type => { return(type.IsSubclassOf(typeof(FSMDataBase)) && !type.IsAbstract); }); for (int i = 0; i < types.Count; i++) { int j = i; gm.AddItem(new GUIContent(types[j].FullName), Target.Data == types[j].FullName, () => { Undo.RecordObject(target, "Set FSM Data Class"); Target.Data = types[j].FullName; HasChanged(); }); } gm.ShowAsContext(); } GUI.color = Color.white; GUILayout.EndHorizontal(); GUILayout.BeginHorizontal(); GUI.enabled = Target.DefaultStateName != ""; GUILayout.Label("Default: " + Target.DefaultStateName); GUI.enabled = true; GUILayout.FlexibleSpace(); GUI.enabled = Target.StateNames.Count > 0; if (GUILayout.Button("Set Default", EditorGlobalTools.Styles.MiniPopup)) { GenericMenu gm = new GenericMenu(); for (int i = 0; i < Target.StateNames.Count; i++) { int j = i; gm.AddItem(new GUIContent(Target.StateNames[j]), Target.DefaultStateName == Target.StateNames[j], () => { Undo.RecordObject(target, "Set FSM Default State"); Target.DefaultState = Target.States[j]; Target.DefaultStateName = Target.StateNames[j]; HasChanged(); }); } gm.ShowAsContext(); } GUI.enabled = true; GUILayout.EndHorizontal(); GUILayout.BeginHorizontal(); GUI.enabled = Target.FinalStateName != ""; GUILayout.Label("Final: " + Target.FinalStateName); GUI.enabled = true; GUILayout.FlexibleSpace(); GUI.enabled = Target.StateNames.Count > 0; if (GUILayout.Button("Set Final", EditorGlobalTools.Styles.MiniPopup)) { GenericMenu gm = new GenericMenu(); for (int i = 0; i < Target.StateNames.Count; i++) { int j = i; gm.AddItem(new GUIContent(Target.StateNames[j]), Target.FinalStateName == Target.StateNames[j], () => { Undo.RecordObject(target, "Set FSM Final State"); Target.FinalState = Target.States[j]; Target.FinalStateName = Target.StateNames[j]; HasChanged(); }); } gm.ShowAsContext(); } GUI.enabled = true; GUILayout.EndHorizontal(); GUILayout.BeginVertical(EditorGlobalTools.Styles.Box); GUILayout.BeginHorizontal(); GUILayout.Label("Enabled State:"); GUILayout.FlexibleSpace(); GUILayout.EndHorizontal(); for (int i = 0; i < Target.StateNames.Count; i++) { GUILayout.BeginHorizontal(); GUILayout.Label(string.Format("{0}.{1}", i + 1, Target.StateNames[i])); GUILayout.FlexibleSpace(); if (GUILayout.Button("Edit", EditorStyles.miniButtonLeft)) { MonoScriptToolkit.OpenMonoScript(Target.States[i]); } if (GUILayout.Button("Delete", EditorStyles.miniButtonRight)) { Undo.RecordObject(target, "Delete FSM State"); if (Target.DefaultStateName == Target.StateNames[i]) { Target.DefaultState = ""; Target.DefaultStateName = ""; } if (Target.FinalStateName == Target.StateNames[i]) { Target.FinalState = ""; Target.FinalStateName = ""; } Target.States.RemoveAt(i); Target.StateNames.RemoveAt(i); if (Target.DefaultStateName == "" && Target.StateNames.Count > 0) { Target.DefaultState = Target.States[0]; Target.DefaultStateName = Target.StateNames[0]; } if (Target.FinalStateName == "" && Target.StateNames.Count > 0) { Target.FinalState = Target.States[0]; Target.FinalStateName = Target.StateNames[0]; } HasChanged(); } GUILayout.EndHorizontal(); } GUILayout.BeginHorizontal(); if (GUILayout.Button("Add State", EditorGlobalTools.Styles.MiniPopup)) { GenericMenu gm = new GenericMenu(); List <Type> types = ReflectionToolkit.GetTypesInRunTimeAssemblies(type => { return(type.IsSubclassOf(typeof(FiniteStateBase)) && !type.IsAbstract); }); for (int i = 0; i < types.Count; i++) { int j = i; string stateName = types[j].FullName; FiniteStateNameAttribute fsmAtt = types[j].GetCustomAttribute <FiniteStateNameAttribute>(); if (fsmAtt != null) { stateName = fsmAtt.Name; } if (Target.States.Contains(types[j].FullName)) { gm.AddDisabledItem(new GUIContent(stateName)); } else { gm.AddItem(new GUIContent(stateName), false, () => { Undo.RecordObject(target, "Add FSM State"); Target.States.Add(types[j].FullName); Target.StateNames.Add(stateName); if (Target.DefaultStateName == "") { Target.DefaultState = Target.States[0]; Target.DefaultStateName = Target.StateNames[0]; } if (Target.FinalStateName == "") { Target.FinalState = Target.States[0]; Target.FinalStateName = Target.StateNames[0]; } HasChanged(); }); } } gm.ShowAsContext(); } GUILayout.EndHorizontal(); GUILayout.EndVertical(); }
protected override void OnDefaultEnable() { base.OnDefaultEnable(); if (Targets.Length > 1) { return; } _stateGC = new GUIContent(); _stateGC.image = EditorGUIUtility.IconContent("AnimatorState Icon").image; _addGC = new GUIContent(); _addGC.image = EditorGUIUtility.IconContent("d_Toolbar Plus More").image; _addGC.tooltip = "Add a new state"; _removeGC = new GUIContent(); _removeGC.image = EditorGUIUtility.IconContent("d_Toolbar Minus").image; _removeGC.tooltip = "Remove select state"; _defaultGC = new GUIContent(); _defaultGC.image = EditorGUIUtility.IconContent("TimelineEditModeRippleON").image; _defaultGC.tooltip = "Default state"; _finalGC = new GUIContent(); _finalGC.image = EditorGUIUtility.IconContent("TimelineEditModeReplaceON").image; _finalGC.tooltip = "Final state"; _editGC = new GUIContent(); _editGC.image = EditorGUIUtility.IconContent("d_editicon.sml").image; _editGC.tooltip = "Edit state script"; _states = GetProperty("States"); _stateList = new ReorderableList(serializedObject, _states, true, true, false, false); _stateList.drawHeaderCallback = (Rect rect) => { Rect sub = rect; sub.Set(rect.x, rect.y, 200, rect.height); GUI.Label(sub, "Enabled States:"); if (!EditorApplication.isPlaying) { sub.Set(rect.x + rect.width - 40, rect.y - 2, 20, 20); if (GUI.Button(sub, _addGC, "InvisibleButton")) { GenericMenu gm = new GenericMenu(); List <Type> types = ReflectionToolkit.GetTypesInRunTimeAssemblies(type => { return(type.IsSubclassOf(typeof(FiniteStateBase)) && !type.IsAbstract); }); for (int i = 0; i < types.Count; i++) { int j = i; string stateName = types[j].FullName; FiniteStateNameAttribute fsmAtt = types[j].GetCustomAttribute <FiniteStateNameAttribute>(); if (fsmAtt != null) { stateName = fsmAtt.Name; } if (Target.States.Contains(types[j].FullName)) { gm.AddDisabledItem(new GUIContent(stateName)); } else { gm.AddItem(new GUIContent(stateName), false, () => { Undo.RecordObject(target, "Add FSM State"); Target.States.Add(types[j].FullName); if (string.IsNullOrEmpty(Target.DefaultState)) { Target.DefaultState = Target.States[0]; } if (string.IsNullOrEmpty(Target.FinalState)) { Target.FinalState = Target.States[0]; } HasChanged(); }); } } gm.ShowAsContext(); } sub.Set(rect.x + rect.width - 20, rect.y - 2, 20, 20); GUI.enabled = _stateList.index >= 0 && _stateList.index < Target.States.Count; if (GUI.Button(sub, _removeGC, "InvisibleButton")) { Undo.RecordObject(target, "Delete FSM State"); if (Target.DefaultState == Target.States[_stateList.index]) { Target.DefaultState = null; } if (Target.FinalState == Target.States[_stateList.index]) { Target.FinalState = null; } Target.States.RemoveAt(_stateList.index); if (string.IsNullOrEmpty(Target.DefaultState) && Target.States.Count > 0) { Target.DefaultState = Target.States[0]; } if (string.IsNullOrEmpty(Target.FinalState) && Target.States.Count > 0) { Target.FinalState = Target.States[0]; } HasChanged(); } GUI.enabled = true; } }; _stateList.drawElementCallback = (Rect rect, int index, bool isActive, bool isFocused) => { if (index >= 0 && index < Target.States.Count) { SerializedProperty property = _states.GetArrayElementAtIndex(index); string stateType = property.stringValue; if (!_stateNames.ContainsKey(stateType)) { Type type = ReflectionToolkit.GetTypeInRunTimeAssemblies(stateType); if (type != null) { string stateName = type.FullName; FiniteStateNameAttribute fsmAtt = type.GetCustomAttribute <FiniteStateNameAttribute>(); if (fsmAtt != null) { stateName = fsmAtt.Name; } _stateNames.Add(stateType, stateName); } else { _stateNames.Add(stateType, "<Missing>"); } } Rect subrect = rect; subrect.Set(rect.x, rect.y + 2, rect.width, 16); _stateGC.text = _stateNames[stateType]; GUI.color = _stateGC.text != "<Missing>" ? Color.white : Color.red; GUI.Label(subrect, _stateGC); GUI.color = Color.white; int size = 20; if (Target.FinalState == stateType) { subrect.Set(rect.x + rect.width - size, rect.y + 2, 20, 16); if (GUI.Button(subrect, _finalGC, "InvisibleButton")) { GenericMenu gm = new GenericMenu(); foreach (var state in _stateNames) { gm.AddItem(new GUIContent(state.Value), Target.FinalState == state.Key, () => { Undo.RecordObject(target, "Set FSM Final State"); Target.FinalState = state.Key; HasChanged(); }); } gm.ShowAsContext(); } size += 20; } if (Target.DefaultState == stateType) { subrect.Set(rect.x + rect.width - size, rect.y + 2, 20, 16); if (GUI.Button(subrect, _defaultGC, "InvisibleButton")) { GenericMenu gm = new GenericMenu(); foreach (var state in _stateNames) { gm.AddItem(new GUIContent(state.Value), Target.DefaultState == state.Key, () => { Undo.RecordObject(target, "Set FSM Default State"); Target.DefaultState = state.Key; HasChanged(); }); } gm.ShowAsContext(); } size += 20; } if (isActive && isFocused) { subrect.Set(rect.x + rect.width - size, rect.y, 20, 20); if (GUI.Button(subrect, _editGC, "InvisibleButton")) { MonoScriptToolkit.OpenMonoScript(stateType); } size += 20; } } }; _stateList.drawElementBackgroundCallback = (Rect rect, int index, bool isActive, bool isFocused) => { if (Event.current.type == EventType.Repaint) { GUIStyle gUIStyle = (index % 2 != 0) ? "CN EntryBackEven" : "CN EntryBackodd"; gUIStyle = (!isActive && !isFocused) ? gUIStyle : "RL Element"; rect.x += 2; rect.width -= 6; gUIStyle.Draw(rect, false, isActive, isActive, isFocused); } }; _stateNames = new Dictionary <string, string>(); if (Target.Args == null) { FSMArgsBase args = Target.GetComponent <FSMArgsBase>(); if (args != null) { Target.Args = args; HasChanged(); } } if (Target.Args != null) { Target.Args.hideFlags = HideFlags.HideInHierarchy | HideFlags.HideInInspector; } }
public override void OnInspectorGUI() { GUILayout.BeginHorizontal(); EditorGUILayout.HelpBox("State Count:" + _target.StateNames.Count, MessageType.Info); GUILayout.EndHorizontal(); GUILayout.BeginHorizontal(); GUILayout.Label("Name: "); this.TextField(_target.Name, out _target.Name); GUILayout.EndHorizontal(); GUILayout.BeginHorizontal(); GUILayout.Label("Data: "); if (GUILayout.Button(_target.Data, "MiniPopup")) { GenericMenu gm = new GenericMenu(); List <Type> types = GlobalTools.GetTypesInRunTimeAssemblies(); gm.AddItem(new GUIContent("<None>"), _target.Data == "<None>", () => { Undo.RecordObject(target, "Set FSM Data Class"); _target.Data = "<None>"; this.HasChanged(); }); for (int i = 0; i < types.Count; i++) { if (types[i].BaseType == typeof(FSMData)) { int j = i; gm.AddItem(new GUIContent(types[j].FullName), _target.Data == types[j].FullName, () => { Undo.RecordObject(target, "Set FSM Data Class"); _target.Data = types[j].FullName; this.HasChanged(); }); } } gm.ShowAsContext(); } GUILayout.EndHorizontal(); GUILayout.BeginHorizontal(); GUI.enabled = _target.DefaultStateName != ""; GUILayout.Label("Default: " + _target.DefaultStateName); GUI.enabled = true; GUILayout.FlexibleSpace(); GUI.enabled = _target.StateNames.Count > 0; if (GUILayout.Button("Set Default", "MiniPopup")) { GenericMenu gm = new GenericMenu(); for (int i = 0; i < _target.StateNames.Count; i++) { int j = i; gm.AddItem(new GUIContent(_target.StateNames[j]), _target.DefaultStateName == _target.StateNames[j], () => { Undo.RecordObject(target, "Set FSM Default State"); _target.DefaultState = _target.States[j]; _target.DefaultStateName = _target.StateNames[j]; this.HasChanged(); }); } gm.ShowAsContext(); } GUI.enabled = true; GUILayout.EndHorizontal(); for (int i = 0; i < _target.StateNames.Count; i++) { GUILayout.BeginHorizontal(); GUILayout.Label(string.Format("{0}.{1} [{2}]", i + 1, _target.StateNames[i], _target.States[i])); GUILayout.FlexibleSpace(); if (GUILayout.Button("Delete", "MiniButton")) { Undo.RecordObject(target, "Delete FSM State"); if (_target.DefaultStateName == _target.StateNames[i]) { _target.DefaultState = ""; _target.DefaultStateName = ""; } _target.States.RemoveAt(i); _target.StateNames.RemoveAt(i); if (_target.DefaultStateName == "" && _target.StateNames.Count > 0) { _target.DefaultState = _target.States[0]; _target.DefaultStateName = _target.StateNames[0]; } this.HasChanged(); } GUILayout.EndHorizontal(); } GUILayout.BeginHorizontal(); if (GUILayout.Button("Add State", "MiniPopup")) { GenericMenu gm = new GenericMenu(); List <Type> types = GlobalTools.GetTypesInRunTimeAssemblies(); for (int i = 0; i < types.Count; i++) { if (types[i].BaseType == typeof(FiniteState)) { int j = i; string stateName = types[j].FullName; object[] atts = types[j].GetCustomAttributes(false); foreach (object att in atts) { FiniteStateNameAttribute fsmAtt = att as FiniteStateNameAttribute; if (fsmAtt != null) { stateName = fsmAtt.Name; break; } } if (_target.States.Contains(types[j].FullName)) { gm.AddDisabledItem(new GUIContent(stateName)); } else { gm.AddItem(new GUIContent(stateName), false, () => { Undo.RecordObject(target, "Add FSM State"); _target.States.Add(types[j].FullName); _target.StateNames.Add(stateName); if (_target.DefaultStateName == "") { _target.DefaultState = _target.States[0]; _target.DefaultStateName = _target.StateNames[0]; } this.HasChanged(); }); } } } gm.ShowAsContext(); } GUILayout.EndHorizontal(); }