This commit is contained in:
2024-10-16 00:03:41 +08:00
commit 897058435c
5033 changed files with 1009728 additions and 0 deletions

View File

@@ -0,0 +1,97 @@
using UnityEditor;
using UnityEngine;
namespace XFFSM
{
public class PackageInfo
{
public string version;
}
public class FSMAboutWindow : EditorWindow
{
Rect textureRect = new Rect(0, 10, 291 * 0.7F, 96 * 0.7F);
Texture logo;
private GUIStyle style;
private string version;
private void Awake()
{
logo = AssetDatabase.LoadAssetAtPath<Texture>("Packages/com.xfkj.xffsm/Editor/Texture/logo_web.png");
TextAsset p = AssetDatabase.LoadAssetAtPath<TextAsset>("Packages/com.xfkj.xffsm/package.json");
if(p != null )
{
PackageInfo info = JsonUtility.FromJson<PackageInfo>(p.text);
version = string.Format("Version {0}", info.version);
}
}
private void ConfigStyle()
{
style = new GUIStyle(GUI.skin.label);
style.richText = true;
style.normal.textColor = new Color(0.03f, 0.4f, 0.9f, 1);
style.onHover.textColor = Color.white;
style.alignment = TextAnchor.MiddleLeft;
style.fontStyle = FontStyle.Italic;
//style.onFocused.textColor = Color.red;
}
// 每秒10帧更新
void OnInspectorUpdate()
{
//开启窗口的重绘,不然窗口信息不会刷新
Repaint();
}
private void OnGUI()
{
if(logo!=null)
GUI.DrawTexture(textureRect, logo);
GUILayout.Space(textureRect.height + 20);
GUILayout.BeginHorizontal();
GUILayout.Space(130);
GUILayout.Label(version);
GUILayout.EndHorizontal();
GUILayout.Space(10);
GUILayout.Label("欢迎使用XFFSM!");
GUILayout.Label("XFFSM 是一款可视化有限状态机插件,XFFSM 能够帮助您加速开发流程,简化状态设计!");
GUILayout.Label("如果您在使用的过程碰到任何问题 或 错误请通过下面的QQ交流群联系到我们!");
GUILayout.Label("感谢您的支持!");
//GUILayout.Label("更多信息可通过点击下方教程链接获取!");
GUILayout.Space(20);
if (style == null)
{
ConfigStyle();
}
//DrawLink("更多教程:", "https://space.bilibili.com/258939476");
DrawLink("插件源码:", "https://gitee.com/xianfengkeji/xffsm");
GUILayout.Space(20);
GUILayout.Label("XFFSM 交流群:644685781");
//GUILayout.Space(20);
GUILayout.Label("*弦风课堂制作");
}
private void DrawLink(string title, string url)
{
GUILayout.BeginHorizontal();
GUILayout.Label(title, GUILayout.Width(60));
if (GUILayout.Button(url, style))
{
Application.OpenURL(url);
}
GUILayout.EndHorizontal();
}
}
}

View File

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

View File

@@ -0,0 +1,107 @@
using System.Collections.Generic;
using UnityEditor.IMGUI.Controls;
using UnityEngine;
namespace XFFSM
{
public class FSMParamListTree : TreeView
{
#region
private RuntimeFSMController controller;
private FSMConditionData condition;
#endregion
#region
protected override TreeViewItem BuildRoot()
{
TreeViewItem root = new TreeViewItem(-1, -1);
if (controller != null)
{
for (int i = 0; i < controller.parameters.Count; i++)
{
root.AddChild(new TreeViewItem(i, 0, controller.parameters[i].name));
}
}
return root;
}
protected override IList<TreeViewItem> BuildRows(TreeViewItem root)
{
return base.BuildRows(root);
}
protected override void SingleClickedItem(int id)
{
base.SingleClickedItem(id);
string paramterName = FindItem(id, rootItem).displayName;
FSMParameterData p = controller.GetParameterData(paramterName);
if (p != null)
{
condition.parameterName = paramterName;
switch (p.parameterType)
{
case ParameterType.Float:
case ParameterType.Int:
condition.compareType = CompareType.Greater;
break;
case ParameterType.Bool:
condition.compareType = CompareType.Equal;
break;
case ParameterType.Trigger:
condition.compareType = CompareType.Equal;
condition.targetValue = 1;
break;
}
}
else {
Debug.LogErrorFormat("参数查询失败:{0}", paramterName);
}
// 保存
controller.Save();
}
protected override void RowGUI(RowGUIArgs args)
{
base.RowGUI(args);
if ( args.label.Equals(condition.parameterName) ) {
GUI.Label(args.rowRect, "√");
}
}
#endregion
#region
public FSMParamListTree(TreeViewState state, RuntimeFSMController controller, FSMConditionData condition) : base(state)
{
this.controller = controller;
this.condition = condition;
showBorder = true;
showAlternatingRowBackgrounds = true;
}
#endregion
}
}

View File

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

View File

@@ -0,0 +1,83 @@
using UnityEditor;
using UnityEditor.IMGUI.Controls;
using UnityEngine;
namespace XFFSM
{
public class FSMSelectParamWindow : PopupWindowContent
{
#region
private float width;
private FSMConditionData condition;
private RuntimeFSMController controller;
// 搜索框
private SearchField searchField;
private Rect searchRect;
const float searchHeight = 25f;
// 标签
private Rect labelRect;
const float labelHeight = 30f;
// 参数列表
private FSMParamListTree paramTree;
private TreeViewState paramState;
private Rect paramRect;
#endregion
public FSMSelectParamWindow(float width,FSMConditionData condition,RuntimeFSMController controller)
{
this.width = width;
this.condition = condition;
this.controller = controller;
}
public override Vector2 GetWindowSize()
{
return new Vector2(this.width,120);
}
public override void OnGUI(Rect rect)
{
if (paramTree == null)
{
if (paramState == null)
{
paramState = new TreeViewState();
}
paramTree = new FSMParamListTree(paramState, controller, condition);
paramTree.Reload();
}
// 搜索框
if (searchField == null) {
searchField = new SearchField();
}
searchRect.Set(rect.x + 5, rect.y + 5, rect.width - 10, searchHeight);
paramTree.searchString = searchField.OnGUI(searchRect, paramTree.searchString);
// 标签
labelRect.Set(rect.x, rect.y + searchHeight, rect.width, labelHeight);
EditorGUI.LabelField(labelRect, condition.parameterName, GUI.skin.GetStyle("AC BoldHeader"));
// 参数列表
paramRect.Set(rect.x, rect.y + searchHeight + labelHeight - 5, rect.width, rect.height - searchHeight - labelHeight);
paramTree.OnGUI(paramRect);
}
}
}

View File

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

View File

@@ -0,0 +1,226 @@
using UnityEditor;
using UnityEditor.IMGUI.Controls;
using UnityEngine;
namespace XFFSM
{
public class FSMSelectStateWindow : PopupWindowContent
{
// Fix编码
#region
private RuntimeFSMController controller;
// 搜索框
private SearchField searchField;
private Rect searchRect;
const float searchHeight = 25f;
// 标签
private Rect labelRect;
const float labelHeight = 30f;
// 参数列表
private FSMStateListTree stateTree;
private TreeViewState stateState;
private Rect stateRect;
private Rect rect;
private FSMStateNodeData nodeData;
private bool showCreateScriptGUI = false;
private string scriptName = string.Empty;
private string scriptName2;
#endregion
public FSMSelectStateWindow(Rect rect,RuntimeFSMController controller,FSMStateNodeData nodeData)
{
//this.width = width;
this.controller = controller;
this.rect = rect;
this.nodeData = nodeData;
this.showCreateScriptGUI = false;
EditorApplication.update -= Update;
EditorApplication.update += Update;
}
public override Vector2 GetWindowSize()
{
return new Vector2(this.rect.width, this.rect.height);
}
public override void OnGUI(Rect rect)
{
if (!showCreateScriptGUI)
{
OnGUISearchScripts(rect);
}
else {
OnGUICreateScripts(rect);
}
}
private void OnGUISearchScripts(Rect rect)
{
if (stateTree == null)
{
if (stateState == null)
{
stateState = new TreeViewState();
}
stateTree = new FSMStateListTree(stateState, controller, this.nodeData,editorWindow);
stateTree.Reload();
}
// 搜索框
if (searchField == null)
{
searchField = new SearchField();
}
searchRect.Set(rect.x + 5, rect.y + 5, rect.width - 5, searchHeight);
stateTree.searchString = searchField.OnGUI(searchRect, stateTree.searchString);
// 标签
labelRect.Set(rect.x, rect.y + searchHeight, rect.width, labelHeight);
EditorGUI.LabelField(labelRect, "FSMStates", GUI.skin.GetStyle("AC BoldHeader"));
// 参数列表
stateRect.Set(rect.x, rect.y + searchHeight + labelHeight - 5, rect.width, rect.height - searchHeight - labelHeight - 20);
stateTree.OnGUI(stateRect);
stateRect.Set(rect.x, stateRect.y + stateRect.height, rect.width, 23);
if (GUI.Button(stateRect, "New Scripts", "AppToolbarButtonMid")) {
showCreateScriptGUI = true;
scriptName = string.Empty;
}
}
private void OnGUICreateScripts(Rect rect) {
EditorGUI.BeginDisabledGroup(true);
// 搜索框
if (searchField == null)
{
searchField = new SearchField();
}
searchRect.Set(rect.x + 5, rect.y + 5, rect.width - 5, searchHeight);
stateTree.searchString = searchField.OnGUI(searchRect, stateTree.searchString);
EditorGUI.EndDisabledGroup();
// 标签
labelRect.Set(rect.x, rect.y + searchHeight, rect.width, labelHeight);
if (GUI.Button(labelRect, "New Script", "AC BoldHeader"))
{
showCreateScriptGUI = false;
}
labelRect.y -= 3;
GUI.Label(labelRect, EditorGUIUtility.IconContent("ArrowNavigationLeft"));
// 参数列表
stateRect.Set(rect.x, rect.y + searchHeight + labelHeight - 5, rect.width, rect.height - searchHeight - labelHeight - 20);
GUILayout.BeginArea(stateRect);
GUILayout.Space(10);
GUILayout.Label("Name");
EditorGUI.BeginChangeCheck();
scriptName2 = EditorGUILayout.DelayedTextField(scriptName);
if (EditorGUI.EndChangeCheck())
{
scriptName = scriptName2;
EditorApplication.delayCall += CreateAndAddScript;
}
//GUILayout.Label(string.Format("scriptName:{0} scriptName2:{1}", scriptName, scriptName2));
GUILayout.EndArea();
stateRect.Set(rect.x,rect.height - 23, rect.width, 23);
if (GUI.Button(stateRect, "Create And Add", "AppToolbarButtonMid"))
{
OnButtonClick();
}
if (Event.current.type == EventType.KeyDown && Event.current.keyCode == KeyCode.Return )
{
EditorApplication.delayCall += CreateAndAddScript;
}
}
private void Update() {
if(!showCreateScriptGUI && editorWindow != null)
editorWindow.Repaint();
if (EditorWindow.focusedWindow != editorWindow)
{
EditorApplication.update -= Update;
}
}
public void Close() {
EditorApplication.update -= Update;
if (editorWindow == null) {
Debug.Log("host view is null!");
return;
}
editorWindow.Close();
}
private void CreateAndAddScript() {
if (EditorWindow.focusedWindow != editorWindow)
return;
if (string.IsNullOrEmpty(scriptName2))
return;
FSMStateGraphView.SavePrefsSelection(this.nodeData.name);
string dir = System.IO.Path.GetDirectoryName(AssetDatabase.GetAssetPath(controller));
string path = string.Format("{0}/{1}.cs", dir, scriptName2);
bool isSuccess = FSMStateCreator.CreateFSMState(path, false);
if (!isSuccess)
{
GUIContent content = new GUIContent(string.Format("名称:{0}不可用,请修改后重试!", scriptName));
this.editorWindow.ShowNotification(content);
return;
}
EditorApplication.delayCall += () =>
{
MonoScript script = AssetDatabase.LoadAssetAtPath<MonoScript>(path);
EditorGUIUtility.PingObject(script);
this.nodeData.AddStateScript(script);
controller.Save();
AssetDatabase.SaveAssets();
};
//Close();
}
private void OnButtonClick()
{
GUI.FocusControl(null);
}
}
}

View File

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

View File

@@ -0,0 +1,177 @@
using System;
using System.Collections.Generic;
using UnityEditor;
using UnityEditor.IMGUI.Controls;
using UnityEngine;
namespace XFFSM
{
public class FSMStateTreeViewItem : TreeViewItem
{
public MonoScript MonoScript { get; private set; }
private Type _type = null;
public Type Type
{
get
{
if (_type == null)
_type = MonoScript.GetClass();
return _type;
}
}
public FSMStateTreeViewItem(int id, int depth, string displayName, MonoScript script) : base(id, depth, displayName)
{
MonoScript = script;
}
}
public class FSMStateListTree : TreeView
{
// Fix编码
#region
private RuntimeFSMController controller;
//private FSMConditionData condition;
private GUIStyle style = new GUIStyle("label");
private FSMStateNodeData nodeData = null;
private EditorWindow editorWindow = null;
private List<int> selections = new List<int>();
#endregion
#region
protected override TreeViewItem BuildRoot()
{
TreeViewItem root = new TreeViewItem(-1, -1);
List<MonoScript> scripts = AssemblyTools.GetAllStatesType();
for (int i = 0; i < scripts.Count; i++)
{
Type type = scripts[i].GetClass();
if (type == null) continue;
string displayName = type.Name;
FSMStateTreeViewItem item = new FSMStateTreeViewItem(i, 0, displayName, scripts[i]);
root.AddChild(item);
}
return root;
}
protected override IList<TreeViewItem> BuildRows(TreeViewItem root)
{
return base.BuildRows(root);
}
protected override void SingleClickedItem(int id)
{
base.SingleClickedItem(id);
FSMStateTreeViewItem item = FindItem(id, rootItem) as FSMStateTreeViewItem;
if (item != null)
{
try
{
nodeData.AddStateScript(item.MonoScript);
}
catch (Exception e)
{
editorWindow.ShowNotification(new GUIContent(e.Message));
return;
}
}
// 保存
controller.Save();
editorWindow.Close();
}
protected override void RowGUI(RowGUIArgs args)
{
//base.RowGUI(args);
FSMStateTreeViewItem item = args.item as FSMStateTreeViewItem;
if (item == null) return;
Type type = item.Type;
if (type == null) return;
if (args.rowRect.Contains(Event.current.mousePosition))
{
selections.Clear();
selections.Add(item.id);
this.SetSelection(selections);
}
Rect rect = new Rect();
rect.Set(args.rowRect.x + 20,args.rowRect.y,args.rowRect.width - 20, args.rowRect.height);
GUI.Label(new Rect(0, args.rowRect.y - 2, 20, 20), EditorGUIUtility.IconContent("d_cs Script Icon"));
if (string.IsNullOrEmpty(type.Namespace)) {
GUI.Label(rect, type.Name);
}
else
{
style.richText = true;
GUI.Label(rect, string.Format("{0}<color=#A4A4A4>({1})</color>", type.Name, type.Namespace), style);
}
//EditorGUIUtility.IconContent("d_cs Script Icon");
}
//protected override void ContextClicked()
//{
// base.ContextClicked();
//}
protected override void SelectionChanged(IList<int> selectedIds)
{
base.SelectionChanged(selectedIds);
}
protected override bool CanMultiSelect(TreeViewItem item)
{
return false;
}
#endregion
#region
public FSMStateListTree(TreeViewState state, RuntimeFSMController controller, FSMStateNodeData nodeData,EditorWindow editorWindow) : base(state)
{
this.controller = controller;
showBorder = true;
showAlternatingRowBackgrounds = true;
this.nodeData = nodeData;
this.editorWindow = editorWindow;
}
#endregion
}
}

View File

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