Files
beyond/Assets/ThirdParty/Invector-AIController/FSM/Editor/Utility/vNodeUtility.cs
2024-11-20 15:21:28 +01:00

306 lines
12 KiB
C#

using UnityEditor;
using System.Collections.Generic;
using UnityEngine;
using System;
using System.IO;
namespace Invector.vCharacterController.AI.FSMBehaviour
{
public static class vNodeUtility
{
public const string newfsmpath = "/Invector-AIController/My FSM Behaviours";
public static void CreateGraph()
{
string path = AssetDatabase.GetAssetPath(Selection.activeObject);
if (path == "")
{
path = "Assets";
}
else if (Path.GetExtension(path) != "")
{
path = path.Replace(Path.GetFileName(AssetDatabase.GetAssetPath(Selection.activeObject)), "");
}
string assetPathAndName = AssetDatabase.GenerateUniqueAssetPath(path + "/New FSM Behaviour.asset");
if (!string.IsNullOrEmpty(assetPathAndName))
{
CreateNewGraph(assetPathAndName);
}
}
public static float NearestRound(float x, float multiple)
{
if (multiple < 1)
{
float i = (float)Math.Floor(x);
float x2 = i;
while ((x2 += multiple) < x) ;
float x1 = x2 - multiple;
return (Math.Abs(x - x1) < Math.Abs(x - x2)) ? x1 : x2;
}
else
{
return (float)Math.Round(x / multiple, MidpointRounding.AwayFromZero) * multiple;
}
}
public static void NearestRound(this Vector2 vector,float multiple)
{
vector.x.NearestRound(multiple);
vector.y.NearestRound(multiple);
}
public static void CreateNewGraph(string path)
{
vFSMBehaviour curGraph = ScriptableObject.CreateInstance<vFSMBehaviour>();
if (curGraph != null)
{
AssetDatabase.CreateAsset(curGraph, path);
AssetDatabase.SaveAssets();
AssetDatabase.Refresh();
Selection.activeObject = curGraph;
var entryNode = CreateNode<vFSMState>("Entry", curGraph);
entryNode.resetCurrentDestination = false;
entryNode.parentGraph = curGraph;
entryNode.useDecisions = false;
entryNode.useActions = false;
entryNode.canEditName = false;
entryNode.canRemove = false;
entryNode.canTranstTo = false;
entryNode.canEditColor = false;
entryNode.canSetAsDefault = false;
entryNode.description = "This State Run Just in Start\n to init first state";
entryNode.nodeColor = Color.green;
var anyState = CreateNode<vFSMState>("AnyState", curGraph);
anyState.resetCurrentDestination = false;
anyState.useDecisions = true;
anyState.useActions = false;
anyState.canEditName = false;
anyState.canRemove = false;
anyState.canTranstTo = false;
anyState.canEditColor = false;
anyState.canSetAsDefault = false;
anyState.description = "This State Run after current state";
anyState.nodeColor = Color.cyan;
anyState.nodeRect.y += 100;
anyState.parentGraph = curGraph;
curGraph.states.Add(entryNode);
curGraph.states.Add(anyState);
curGraph.InitGraph();
vFSMNodeEditorWindow.InitEditorWindow(curGraph);
}
else
{
EditorUtility.DisplayDialog("Node Message", "Unable to create new graph, please see your friendly programmer!", "OK");
}
}
public static int GetSameComponentNameCount<T>(this UnityEngine.Object obj)
{
var objs = AssetDatabase.LoadAllAssetsAtPath(AssetDatabase.GetAssetPath(obj.GetInstanceID()));
int count = 0;
foreach (var o in objs)
{
if(o!=null)
{
if ((o.GetType().Equals(typeof(T)) || o.GetType().IsSubclassOf(typeof(T))) && o != obj && o.name.Equals(obj.name)) count++;
}
}
return count;
}
public static void LoadGraph()
{
vFSMBehaviour curGraph = null;
string graphPath = EditorUtility.OpenFilePanel("Load FSM Behaviour", Application.dataPath + "/Invector-AIController/", "asset");
if (!string.IsNullOrEmpty(graphPath))
{
int dataPathLength = Application.dataPath.Length - 6;
string finalPah = graphPath.Substring(dataPathLength);
curGraph = (vFSMBehaviour)AssetDatabase.LoadAssetAtPath(finalPah, typeof(vFSMBehaviour));
vFSMNodeEditorWindow curwindow = EditorWindow.GetWindow<vFSMNodeEditorWindow>();
if (curwindow != null)
{
curwindow.curGraph = curGraph;
Selection.activeObject = curGraph;
}
}
}
public static void UnloadGraph()
{
vFSMNodeEditorWindow curwindow = EditorWindow.GetWindow<vFSMNodeEditorWindow>();
if (curwindow != null)
{
if (curwindow.curGraph != null && Selection.activeObject == curwindow.curGraph)
Selection.activeObject = null;
curwindow.curGraph = null;
}
}
public static List<T> FindAssetsByType<T>() where T : UnityEngine.Object
{
List<T> assets = new List<T>();
string[] guids = AssetDatabase.FindAssets(string.Format("t:{0}", typeof(T)));
for (int i = 0; i < guids.Length; i++)
{
string assetPath = AssetDatabase.GUIDToAssetPath(guids[i]);
T asset = AssetDatabase.LoadAssetAtPath<T>(assetPath);
if (asset != null)
{
assets.Add(asset);
}
}
return assets;
}
public static void CreateNode(vFSMBehaviour curGraph, Vector2 mousePos)
{
if (curGraph != null)
{
vFSMState curState = null;
Undo.RecordObject(curGraph, "New Node");
curState = ScriptableObject.CreateInstance<vFSMState>();
curState.Name = "State " + (curGraph.states.Count > 1 ? (curGraph.states.Count - 2).ToString() : "");
if (curGraph.states.Count > 0)
{
if (curGraph.states[0].defaultTransition == null)
{
curGraph.states[0].defaultTransition = curState;
}
}
curState.nodeColor = Color.white;
if (curState != null)
{
curState.InitNode();
curState.nodeRect.x = mousePos.x;
curState.nodeRect.y = mousePos.y;
curState.parentGraph = curGraph;
curState.hideFlags = HideFlags.HideInHierarchy;
curGraph.states.Add(curState);
AssetDatabase.AddObjectToAsset(curState, curGraph);
var count = curState.GetSameComponentNameCount<vFSMState>();
if (count > 0)
curState.Name += " " + (count - 1).ToString();
AssetDatabase.SaveAssets();
AssetDatabase.Refresh();
}
}
}
public static void CreateNode(Type type, vFSMBehaviour curGraph, Vector2 mousePos)
{
if (curGraph != null && type.IsSubclassOf(typeof(vFSMState)))
{
var curState = ScriptableObject.CreateInstance(type.FullName);
Undo.RegisterCreatedObjectUndo(curState, "Create object");
curState.name = "State " + (curGraph.states.Count > 1 ? (curGraph.states.Count - 2).ToString() : "");
if (curGraph.states.Count > 0)
{
if (curGraph.states[0].defaultTransition == null)
{
curGraph.states[0].defaultTransition = curState as vFSMState;
}
}
(curState as vFSMState).nodeColor = Color.white;
if (curState != null)
{
(curState as vFSMState).InitNode();
(curState as vFSMState).nodeRect.x = mousePos.x;
(curState as vFSMState).nodeRect.y = mousePos.y;
(curState as vFSMState).parentGraph = curGraph;
curState.hideFlags = HideFlags.HideInHierarchy;
curGraph.states.Add((curState as vFSMState));
AssetDatabase.AddObjectToAsset(curState, curGraph);
var count = curState.GetSameComponentNameCount<vFSMState>();
if (count > 0)
(curState as vFSMState).Name += " " + (count - 1).ToString();
AssetDatabase.SaveAssets();
AssetDatabase.Refresh();
}
}
}
public static T CreateNode<T>(string name, vFSMBehaviour parentGraph) where T : ScriptableObject
{
T curNode = null;
curNode = (T)ScriptableObject.CreateInstance<T>();
curNode.name = name;
if (curNode != null)
{
AssetDatabase.AddObjectToAsset(curNode, parentGraph);
curNode.hideFlags = HideFlags.HideInHierarchy;
AssetDatabase.SaveAssets();
AssetDatabase.Refresh();
}
return curNode;
}
public static T Get<T>(Type type)
{
return (T)Convert.ChangeType(type, typeof(T));
}
public static void DeleteNode(int id, vFSMBehaviour curGraph)
{
if (curGraph)
{
if (id >= 0 && id < curGraph.states.Count)
{
vFSMState deleteNode = curGraph.states[id];
if (deleteNode)
{
curGraph.selectedNode = null;
curGraph.overNode = false;
curGraph.states.RemoveAt(id);
for (int i = 0; i < deleteNode.actions.Count; i++)
{
if (deleteNode.actions[i])
{
var o = new SerializedObject(deleteNode.actions[i]);
o.ApplyModifiedProperties();
}
}
for (int i = 0; i < deleteNode.transitions.Count; i++)
{
if (deleteNode.transitions[i].decisions != null)
{
for (int a = 0; a < deleteNode.transitions[i].decisions.Count; a++)
{
if (deleteNode.transitions[i].decisions[a].decision)
{
var o = new SerializedObject(deleteNode.transitions[i].decisions[a].decision);
o.ApplyModifiedProperties();
}
}
}
}
if (curGraph.states.Count > 2 && curGraph.states[0].defaultTransition == deleteNode)
{
curGraph.states[0].defaultTransition = curGraph.states[2] as vFSMState;
}
Undo.DestroyObjectImmediate(deleteNode);
AssetDatabase.SaveAssets();
AssetDatabase.Refresh();
}
}
}
}
}
}