init
This commit is contained in:
commit
11e5744b46
8
Editor.meta
Normal file
8
Editor.meta
Normal file
@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 3c8cb3e33a856dc4a99a3bbe94231fa9
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
18
Editor/AlicizaX.AnimationFlow.Editor.asmdef
Normal file
18
Editor/AlicizaX.AnimationFlow.Editor.asmdef
Normal file
@ -0,0 +1,18 @@
|
||||
{
|
||||
"name": "AlicizaX.AnimationFlow.Editor",
|
||||
"rootNamespace": "AlicizaX.AnimationFlow.Editor",
|
||||
"references": [
|
||||
"GUID:189d55e03d78888459720d730f4d2424"
|
||||
],
|
||||
"includePlatforms": [
|
||||
"Editor"
|
||||
],
|
||||
"excludePlatforms": [],
|
||||
"allowUnsafeCode": false,
|
||||
"overrideReferences": false,
|
||||
"precompiledReferences": [],
|
||||
"autoReferenced": true,
|
||||
"defineConstraints": [],
|
||||
"versionDefines": [],
|
||||
"noEngineReferences": false
|
||||
}
|
7
Editor/AlicizaX.AnimationFlow.Editor.asmdef.meta
Normal file
7
Editor/AlicizaX.AnimationFlow.Editor.asmdef.meta
Normal file
@ -0,0 +1,7 @@
|
||||
fileFormatVersion: 2
|
||||
guid: da025bffb2b9d1344b59cf03601655ea
|
||||
AssemblyDefinitionImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
8
Editor/Data.meta
Normal file
8
Editor/Data.meta
Normal file
@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: dc52eb5fc47d72342a352309fb3b7832
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
11
Editor/Data/AnimationFlowSerialize.cs
Normal file
11
Editor/Data/AnimationFlowSerialize.cs
Normal file
@ -0,0 +1,11 @@
|
||||
using System.Collections.Generic;
|
||||
using AlicizaX.AnimationFlow.Runtime;
|
||||
using UnityEngine;
|
||||
|
||||
namespace AlicizaX.AnimationFlow.Editor {
|
||||
public class AnimationFlowSerialize {
|
||||
public string flag;
|
||||
[SerializeReference]
|
||||
public List<ActionNode> nodes = new();
|
||||
}
|
||||
}
|
11
Editor/Data/AnimationFlowSerialize.cs.meta
Normal file
11
Editor/Data/AnimationFlowSerialize.cs.meta
Normal file
@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 4af60c68d7208084695e7fa37b683425
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
8
Editor/Graph.meta
Normal file
8
Editor/Graph.meta
Normal file
@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 10fd447a6852a0e42b41b454370606a2
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
367
Editor/Graph/GraphView.cs
Normal file
367
Editor/Graph/GraphView.cs
Normal file
@ -0,0 +1,367 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using AlicizaX.AnimationFlow.Runtime;
|
||||
using UnityEditor;
|
||||
using UnityEditor.Experimental.GraphView;
|
||||
using UnityEngine;
|
||||
using UnityEngine.UIElements;
|
||||
|
||||
namespace AlicizaX.AnimationFlow.Editor
|
||||
{
|
||||
public class GraphView : UnityEditor.Experimental.GraphView.GraphView
|
||||
{
|
||||
private readonly SearchWindowProvider searchWindowProvider;
|
||||
private readonly GraphWindow graphWindow;
|
||||
private readonly Dictionary<string, NodeView> dicNodeView = new();
|
||||
private Runtime.AnimationFlow animationFlow;
|
||||
private const string applicationFlag = "@AnimationFlow";
|
||||
|
||||
private readonly Dictionary<string, ActionNode> pendingNodes = new();
|
||||
|
||||
public GraphView(GraphWindow graphWindow) : base()
|
||||
{
|
||||
this.graphWindow = graphWindow;
|
||||
InitView();
|
||||
SetupZoom(ContentZoomer.DefaultMinScale, ContentZoomer.DefaultMaxScale);
|
||||
this.AddManipulator(new SelectionDragger());
|
||||
this.AddManipulator(new RectangleSelector());
|
||||
this.AddManipulator(new ContentDragger());
|
||||
|
||||
searchWindowProvider = ScriptableObject.CreateInstance<SearchWindowProvider>();
|
||||
searchWindowProvider.Initialize(graphWindow, this);
|
||||
|
||||
|
||||
SetCopyAndPaste();
|
||||
graphViewChanged += OnGraphViewChanged;
|
||||
}
|
||||
|
||||
|
||||
private void InitView()
|
||||
{
|
||||
this.StretchToParentSize();
|
||||
|
||||
Insert(0, new GridBackground());
|
||||
AddStyles();
|
||||
MiniMap miniMap = new();
|
||||
Add(miniMap);
|
||||
miniMap.style.backgroundColor = new Color(0.12f, 0.12f, 0.12f, 1f);
|
||||
miniMap.style.borderBottomColor = new Color(0.2f, 0.2f, 0.2f, 1f);
|
||||
miniMap.style.borderRightColor = new Color(0.2f, 0.2f, 0.2f, 1f);
|
||||
miniMap.style.borderTopColor = new Color(0.2f, 0.2f, 0.2f, 1f);
|
||||
miniMap.style.borderLeftColor = new Color(0.2f, 0.2f, 0.2f, 1f);
|
||||
}
|
||||
|
||||
private void SetCopyAndPaste()
|
||||
{
|
||||
serializeGraphElements += (IEnumerable<GraphElement> elements) =>
|
||||
{
|
||||
AnimationFlowSerialize serialize = new();
|
||||
serialize.flag = applicationFlag;
|
||||
foreach (var ele in elements)
|
||||
{
|
||||
if (ele is NodeView nodeView)
|
||||
{
|
||||
serialize.nodes.Add(nodeView.actionNode);
|
||||
}
|
||||
}
|
||||
|
||||
return JsonUtility.ToJson(serialize);
|
||||
};
|
||||
canPasteSerializedData += (string data) => { return data.Contains(applicationFlag); };
|
||||
unserializeAndPaste += (string operationName, string data) =>
|
||||
{
|
||||
ClearSelection();
|
||||
Undo.RecordObject(animationFlow, operationName);
|
||||
Vector2 mousePos = contentViewContainer.WorldToLocal(contentRect.center);
|
||||
try
|
||||
{
|
||||
AnimationFlowSerialize serialize = JsonUtility.FromJson<AnimationFlowSerialize>(data);
|
||||
List<ActionNode> newDatas = new();
|
||||
Dictionary<string, ActionNode> dicUid = new();
|
||||
foreach (ActionNode node in serialize.nodes)
|
||||
{
|
||||
node.nodePos = node.nodePos + mousePos;
|
||||
string uuid = node.uuid;
|
||||
node.uuid = Guid.NewGuid().ToString();
|
||||
NodeView nodeView = AddNodeView(node);
|
||||
AddToSelection(nodeView);
|
||||
newDatas.Add(node);
|
||||
dicUid.Add(uuid, node);
|
||||
}
|
||||
|
||||
foreach (ActionNode copyNode in newDatas)
|
||||
{
|
||||
for (int i = copyNode.Childs.Count - 1; i >= 0; i--)
|
||||
{
|
||||
if (dicUid.TryGetValue(copyNode.Childs[i].uuid, out ActionNode newNode))
|
||||
{
|
||||
copyNode.Childs[i] = newNode;
|
||||
if (dicNodeView.TryGetValue(copyNode.uuid, out NodeView inNode) && dicNodeView.TryGetValue(newNode.uuid, out NodeView outNode))
|
||||
{
|
||||
AddElement(inNode.portOut.ConnectTo(outNode.portIn));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
copyNode.Childs.RemoveAt(i);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
private void ResetEdge()
|
||||
{
|
||||
List<ActionNode> nodes = new List<ActionNode>();
|
||||
foreach (var item in animationFlow.AnimationNodes)
|
||||
{
|
||||
nodes.Add(item);
|
||||
}
|
||||
|
||||
List<ActionNode> allNodes = new List<ActionNode>();
|
||||
LoadAllChildNode(nodes, allNodes);
|
||||
|
||||
|
||||
foreach (ActionNode data in allNodes)
|
||||
{
|
||||
foreach (ActionNode node in allNodes)
|
||||
{
|
||||
if (data.Childs.Count > 0 && data.Childs.Find(a => a.uuid == node.uuid) != null)
|
||||
{
|
||||
if (dicNodeView.TryGetValue(data.uuid, out NodeView inNode) && dicNodeView.TryGetValue(node.uuid, out NodeView outNode))
|
||||
{
|
||||
AddElement(inNode.portOut.ConnectTo(outNode.portIn));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private NodeView ResetNodeView(ActionNode data)
|
||||
{
|
||||
NodeView nodeView = new(data, graphWindow);
|
||||
AddElement(nodeView);
|
||||
nodeView.SetPosition(new Rect(data.nodePos, Vector2.zero));
|
||||
dicNodeView.Add(data.uuid, nodeView);
|
||||
return nodeView;
|
||||
}
|
||||
|
||||
private void RemoveNodeView(NodeView nodeView)
|
||||
{
|
||||
dicNodeView.Remove(nodeView.actionNode.uuid);
|
||||
pendingNodes.Remove(nodeView.actionNode.uuid);
|
||||
if (nodeView.actionNode is EntryNode)
|
||||
{
|
||||
animationFlow.AnimationNodes.Remove(nodeView.actionNode as EntryNode);
|
||||
}
|
||||
}
|
||||
|
||||
private void AddStyles()
|
||||
{
|
||||
StyleSheet styleSheet = AssetDatabase.LoadAssetAtPath<StyleSheet>(EditorResourceTool.editorAssets + "/AnimationFlowStyles.uss");
|
||||
styleSheets.Add(styleSheet);
|
||||
}
|
||||
|
||||
private GraphViewChange OnGraphViewChanged(GraphViewChange change)
|
||||
{
|
||||
change.edgesToCreate?.ForEach(edge =>
|
||||
{
|
||||
if (animationFlow == null)
|
||||
{
|
||||
ClearGraph();
|
||||
return;
|
||||
}
|
||||
|
||||
Undo.RecordObject(animationFlow, "Create Edge");
|
||||
NodeView nodeIn = edge.input.node as NodeView;
|
||||
NodeView nodeOut = edge.output.node as NodeView;
|
||||
nodeOut.actionNode.Childs.Add(nodeIn.actionNode);
|
||||
EditorUtility.SetDirty(animationFlow);
|
||||
});
|
||||
|
||||
change.elementsToRemove?.ForEach(elem =>
|
||||
{
|
||||
if (animationFlow == null)
|
||||
{
|
||||
ClearGraph();
|
||||
return;
|
||||
}
|
||||
|
||||
if (elem is Edge edge)
|
||||
{
|
||||
Undo.RecordObject(animationFlow, "Rmove Edge");
|
||||
NodeView nodeIn = edge.input.node as NodeView;
|
||||
NodeView nodeOut = edge.output.node as NodeView;
|
||||
nodeOut.actionNode.Childs.Remove(nodeIn.actionNode);
|
||||
}
|
||||
|
||||
if (elem is NodeView node)
|
||||
{
|
||||
Undo.RecordObject(animationFlow, "Remove Node");
|
||||
RemoveNodeView(node);
|
||||
graphWindow.OnNodeRemove();
|
||||
}
|
||||
|
||||
EditorUtility.SetDirty(animationFlow);
|
||||
});
|
||||
change.movedElements?.ForEach(elem =>
|
||||
{
|
||||
if (animationFlow == null)
|
||||
{
|
||||
ClearGraph();
|
||||
return;
|
||||
}
|
||||
|
||||
if (elem is NodeView nodeView)
|
||||
{
|
||||
Undo.RecordObject(animationFlow, "Move Node");
|
||||
nodeView.actionNode.nodePos = nodeView.GetPosition().position;
|
||||
}
|
||||
|
||||
EditorUtility.SetDirty(animationFlow);
|
||||
});
|
||||
return change;
|
||||
}
|
||||
|
||||
public override void BuildContextualMenu(ContextualMenuPopulateEvent evt)
|
||||
{
|
||||
SearchWindow.Open(new SearchWindowContext(GUIUtility.GUIToScreenPoint(evt.mousePosition)), searchWindowProvider);
|
||||
}
|
||||
|
||||
public override List<Port> GetCompatiblePorts(Port startPort, NodeAdapter nodeAdapter)
|
||||
{
|
||||
List<Port> compatiblePorts = new();
|
||||
ports.ForEach(port =>
|
||||
{
|
||||
if (startPort == port)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (startPort.node == port.node)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (startPort.direction == port.direction)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (startPort.portType != port.portType)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
compatiblePorts.Add(port);
|
||||
});
|
||||
|
||||
return compatiblePorts;
|
||||
}
|
||||
|
||||
protected override bool canDeleteSelection => base.canDeleteSelection && !Application.isPlaying && animationFlow != null && !animationFlow.InPlaying;
|
||||
protected override bool canCopySelection => base.canCopySelection && !Application.isPlaying && animationFlow != null && !animationFlow.InPlaying;
|
||||
protected override bool canCutSelection => base.canCutSelection && !Application.isPlaying && animationFlow != null && !animationFlow.InPlaying;
|
||||
protected override bool canDuplicateSelection => base.canDuplicateSelection && !Application.isPlaying && animationFlow != null && !animationFlow.InPlaying;
|
||||
protected override bool canPaste => base.canPaste && !Application.isPlaying && animationFlow != null;
|
||||
|
||||
public NodeView AddNodeView(ActionNode node)
|
||||
{
|
||||
if (animationFlow == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
Undo.RecordObject(animationFlow, "Create Node");
|
||||
if (node is EntryNode)
|
||||
{
|
||||
animationFlow.AnimationNodes.Add(node as EntryNode);
|
||||
}
|
||||
else
|
||||
{
|
||||
pendingNodes.Add(node.uuid, node);
|
||||
}
|
||||
|
||||
return ResetNodeView(node);
|
||||
}
|
||||
|
||||
public void ClearGraph()
|
||||
{
|
||||
graphElements.ForEach(g => RemoveElement(g));
|
||||
dicNodeView.Clear();
|
||||
animationFlow = null;
|
||||
}
|
||||
|
||||
public void SetAnimationFlow(Runtime.AnimationFlow animationFlow)
|
||||
{
|
||||
this.animationFlow = animationFlow;
|
||||
|
||||
List<ActionNode> nodes = new List<ActionNode>();
|
||||
foreach (var VARIABLE in animationFlow.AnimationNodes)
|
||||
{
|
||||
nodes.Add(VARIABLE);
|
||||
}
|
||||
|
||||
|
||||
List<ActionNode> allNodes = new List<ActionNode>();
|
||||
LoadAllChildNode(nodes, allNodes);
|
||||
|
||||
foreach (ActionNode data in allNodes)
|
||||
{
|
||||
ResetNodeView(data);
|
||||
}
|
||||
|
||||
ResetEdge();
|
||||
}
|
||||
|
||||
private void LoadAllChildNode(List<ActionNode> nodes, List<ActionNode> collector)
|
||||
{
|
||||
foreach (var item in nodes)
|
||||
{
|
||||
collector.Add(item);
|
||||
if (item.Childs.Count > 0) LoadAllChildNode(item.Childs, collector);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public void ResetView()
|
||||
{
|
||||
foreach (NodeView nodeView in dicNodeView.Values)
|
||||
{
|
||||
nodeView.RemoveProgress();
|
||||
nodeView.RemoveComplete();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public void OnNodeEnter(ActionNode actionNode)
|
||||
{
|
||||
if (dicNodeView.TryGetValue(actionNode.uuid, out NodeView nodeView))
|
||||
{
|
||||
nodeView.AddProgress();
|
||||
}
|
||||
}
|
||||
|
||||
public void OnNodeExit(ActionNode actionNode)
|
||||
{
|
||||
if (dicNodeView.TryGetValue(actionNode.uuid, out NodeView nodeView))
|
||||
{
|
||||
nodeView.RemoveProgress();
|
||||
nodeView.AddComplete();
|
||||
}
|
||||
}
|
||||
|
||||
public void OnNodeUpdate(ActionNode actionNode)
|
||||
{
|
||||
if (dicNodeView.TryGetValue(actionNode.uuid, out NodeView nodeView))
|
||||
{
|
||||
nodeView.UpdateProgress();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
11
Editor/Graph/GraphView.cs.meta
Normal file
11
Editor/Graph/GraphView.cs.meta
Normal file
@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 58e6b0dfd8ab40e4b8854c0fd03a2fdf
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
123
Editor/Graph/NodeView.cs
Normal file
123
Editor/Graph/NodeView.cs
Normal file
@ -0,0 +1,123 @@
|
||||
using System;
|
||||
using System.Linq;
|
||||
using AlicizaX.AnimationFlow.Runtime;
|
||||
using UnityEditor;
|
||||
using UnityEditor.Experimental.GraphView;
|
||||
using UnityEngine;
|
||||
using UnityEngine.UIElements;
|
||||
using static UnityEditor.Experimental.GraphView.Port;
|
||||
|
||||
namespace AlicizaX.AnimationFlow.Editor {
|
||||
public class NodeView : Node {
|
||||
public readonly ActionNode actionNode;
|
||||
public Port portIn;
|
||||
public Port portOut;
|
||||
private readonly GraphWindow graphWindow;
|
||||
private ProgressBar progressPlaying;
|
||||
private Image imageComplete;
|
||||
private Image imageWarning;
|
||||
private Label sub_title;
|
||||
|
||||
public NodeView(ActionNode node, GraphWindow graphWindow) {
|
||||
this.actionNode = node;
|
||||
this.graphWindow = graphWindow;
|
||||
Draw();
|
||||
}
|
||||
private void Draw() {
|
||||
Type type = actionNode.GetType();
|
||||
NameAttribute nameAttribute = type.GetCustomAttributes(typeof(NameAttribute), true).FirstOrDefault() as NameAttribute;
|
||||
title = nameAttribute != null && !string.IsNullOrEmpty(nameAttribute.name) ? nameAttribute.name : type.Name;
|
||||
if (actionNode.HasInputPort()) {
|
||||
portIn = InstantiatePort(Orientation.Horizontal, Direction.Input, actionNode.MultiInputPort() ? Capacity.Multi : Capacity.Single, typeof(bool));
|
||||
inputContainer.Add(portIn);
|
||||
portIn.portName = "in";
|
||||
}
|
||||
if (actionNode.HasOutPort()) {
|
||||
portOut = InstantiatePort(Orientation.Horizontal, Direction.Output, actionNode.MultiOutPort() ? Capacity.Multi : Capacity.Single, typeof(bool));
|
||||
outputContainer.Add(portOut);
|
||||
portOut.portName = "out";
|
||||
}
|
||||
titleContainer.Remove(titleButtonContainer);
|
||||
imageComplete = new() {
|
||||
image = AssetDatabase.LoadAssetAtPath<Texture2D>(EditorResourceTool.editorAssets + "/Complete.png"),
|
||||
tintColor = new Color(0.4f, 0.7f, 0.2f),
|
||||
style = { marginLeft = 3, marginRight = 10, visibility = Visibility.Hidden }
|
||||
};
|
||||
titleContainer.Add(imageComplete);
|
||||
|
||||
imageWarning = new() {
|
||||
image = AssetDatabase.LoadAssetAtPath<Texture2D>(EditorResourceTool.editorAssets + "/Warning.png"),
|
||||
tintColor = Color.red,
|
||||
style = { position = Position.Absolute, right = 0, top = 5 }
|
||||
};
|
||||
titleContainer.Add(imageWarning);
|
||||
|
||||
RefreshState();
|
||||
|
||||
if (actionNode.HasSubTitle()) {
|
||||
sub_title = new(actionNode.SubTitle()) {
|
||||
style = { fontSize = 12, paddingLeft = 8, paddingBottom = 5, backgroundColor = new Color(0.23f, 0.23f, 0.23f, 1f) }
|
||||
};
|
||||
this.Q<VisualElement>("node-border").Insert(1, sub_title);
|
||||
}
|
||||
this.Q<VisualElement>("title").style.height = 25;
|
||||
}
|
||||
|
||||
public void RefreshState() {
|
||||
imageWarning.style.visibility = actionNode.Valid() ? Visibility.Hidden : Visibility.Visible;
|
||||
if (sub_title != null) {
|
||||
if (string.IsNullOrEmpty(actionNode.SubTitle())) {
|
||||
sub_title.text = "<Empty>";
|
||||
sub_title.style.color = Color.red;
|
||||
} else {
|
||||
sub_title.text = actionNode.SubTitle();
|
||||
sub_title.style.color = new Color(0.82f, 0.82f, 0.82f, 1f);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void AddComplete() {
|
||||
imageComplete.style.visibility = Visibility.Visible;
|
||||
}
|
||||
|
||||
public void RemoveComplete() {
|
||||
imageComplete.style.visibility = Visibility.Hidden;
|
||||
}
|
||||
|
||||
public void AddProgress() {
|
||||
if (actionNode.Duration() == 0) {
|
||||
return;
|
||||
}
|
||||
progressPlaying = new();
|
||||
progressPlaying.style.height = 10;
|
||||
contentContainer.Add(progressPlaying);
|
||||
progressPlaying.highValue = actionNode.Duration();
|
||||
progressPlaying.value = 0;
|
||||
RefreshExpandedState();
|
||||
}
|
||||
|
||||
public void UpdateProgress() {
|
||||
if (actionNode.Duration() == 0) {
|
||||
return;
|
||||
}
|
||||
if (progressPlaying == null) {
|
||||
AddProgress();
|
||||
}
|
||||
progressPlaying.value = actionNode.elapsedTime;
|
||||
}
|
||||
|
||||
public void RemoveProgress() {
|
||||
if (progressPlaying == null) {
|
||||
return;
|
||||
}
|
||||
contentContainer.Remove(progressPlaying);
|
||||
progressPlaying = null;
|
||||
RefreshExpandedState();
|
||||
}
|
||||
|
||||
public override void OnSelected() {
|
||||
base.OnSelected();
|
||||
graphWindow.OnSelect(this);
|
||||
}
|
||||
}
|
||||
}
|
11
Editor/Graph/NodeView.cs.meta
Normal file
11
Editor/Graph/NodeView.cs.meta
Normal file
@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: cdc2d2302b871c641bb2538b37280dbd
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
64
Editor/Graph/SearchWindowProvider.cs
Normal file
64
Editor/Graph/SearchWindowProvider.cs
Normal file
@ -0,0 +1,64 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using AlicizaX.AnimationFlow.Runtime;
|
||||
using UnityEditor.Experimental.GraphView;
|
||||
using UnityEngine;
|
||||
using UnityEngine.UIElements;
|
||||
|
||||
namespace AlicizaX.AnimationFlow.Editor {
|
||||
public class SearchWindowProvider : ScriptableObject, ISearchWindowProvider {
|
||||
private GraphWindow graphWindow;
|
||||
private GraphView graphView;
|
||||
private Texture2D icon;
|
||||
|
||||
public void Initialize(GraphWindow graphWindow, GraphView graphView) {
|
||||
this.graphWindow = graphWindow;
|
||||
this.graphView = graphView;
|
||||
icon = new Texture2D(1, 1);
|
||||
icon.SetPixel(0, 0, Color.clear);
|
||||
icon.Apply();
|
||||
}
|
||||
|
||||
List<SearchTreeEntry> ISearchWindowProvider.CreateSearchTree(SearchWindowContext context) {
|
||||
List<SearchTreeEntry> entries = new() {
|
||||
new SearchTreeGroupEntry(new GUIContent("Create Node",icon))
|
||||
};
|
||||
Dictionary<string, List<Type>> dicType = new();
|
||||
foreach (var assembly in AppDomain.CurrentDomain.GetAssemblies()) {
|
||||
foreach (var type in assembly.GetTypes()) {
|
||||
if (type.IsClass && !type.IsAbstract && type.IsSubclassOf(typeof(ActionNode))) {
|
||||
CategoryAttribute categoryAttribute = type.GetCustomAttributes(typeof(CategoryAttribute), true).FirstOrDefault() as CategoryAttribute;
|
||||
if (categoryAttribute == null || string.IsNullOrEmpty(categoryAttribute.category)) {
|
||||
NameAttribute nameAttribute = type.GetCustomAttributes(typeof(NameAttribute), true).FirstOrDefault() as NameAttribute;
|
||||
entries.Add(new SearchTreeEntry(new GUIContent(nameAttribute != null && !string.IsNullOrEmpty(nameAttribute.name) ? nameAttribute.name : type.Name, icon)) { level = 1, userData = type });
|
||||
} else {
|
||||
if (dicType.TryGetValue(categoryAttribute.category, out var list)) {
|
||||
list.Add(type);
|
||||
} else {
|
||||
dicType.Add(categoryAttribute.category, new List<Type>() { type });
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
foreach (var kv in dicType) {
|
||||
entries.Add(new SearchTreeGroupEntry(new GUIContent(kv.Key), 1));
|
||||
foreach (Type type in kv.Value) {
|
||||
NameAttribute nameAttribute = type.GetCustomAttributes(typeof(NameAttribute), true).FirstOrDefault() as NameAttribute;
|
||||
entries.Add(new SearchTreeEntry(new GUIContent(nameAttribute != null && !string.IsNullOrEmpty(nameAttribute.name) ? nameAttribute.name : type.Name, icon)) { level = 2, userData = type });
|
||||
}
|
||||
}
|
||||
return entries;
|
||||
}
|
||||
|
||||
bool ISearchWindowProvider.OnSelectEntry(SearchTreeEntry searchTreeEntry, SearchWindowContext context) {
|
||||
var type = searchTreeEntry.userData as Type;
|
||||
var data = Activator.CreateInstance(type) as ActionNode;
|
||||
data.uuid = Guid.NewGuid().ToString();
|
||||
data.nodePos = graphView.contentViewContainer.WorldToLocal(context.screenMousePosition - graphWindow.position.position);
|
||||
graphView.AddNodeView(data);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
11
Editor/Graph/SearchWindowProvider.cs.meta
Normal file
11
Editor/Graph/SearchWindowProvider.cs.meta
Normal file
@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: d78888718c3f29e45a248128d078a137
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
8
Editor/Inspector.meta
Normal file
8
Editor/Inspector.meta
Normal file
@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: d6016243a18ef4b4896a29f8f4ebd99d
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
45
Editor/Inspector/GraphInspector.cs
Normal file
45
Editor/Inspector/GraphInspector.cs
Normal file
@ -0,0 +1,45 @@
|
||||
using System;
|
||||
using System.Linq;
|
||||
using AlicizaX.AnimationFlow.Runtime;
|
||||
using Sirenix.OdinInspector.Editor;
|
||||
using UnityEditor;
|
||||
using UnityEngine;
|
||||
using UnityEngine.UIElements;
|
||||
|
||||
namespace AlicizaX.AnimationFlow.Editor
|
||||
{
|
||||
public class GraphInspector : VisualElement
|
||||
{
|
||||
private PropertyTree propertyTree;
|
||||
|
||||
public void DrawNode(NodeView nodeView)
|
||||
{
|
||||
Clear();
|
||||
if (nodeView.actionNode == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// 使用 Odin PropertyTree 来处理非 UnityEngine.Object 对象
|
||||
propertyTree = PropertyTree.Create(nodeView.actionNode);
|
||||
|
||||
var imguiContainer = new IMGUIContainer(() =>
|
||||
{
|
||||
if (propertyTree == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
propertyTree.Draw(false);
|
||||
// 手动调用 Odin 的 Apply,处理数据更新后的逻辑
|
||||
if (propertyTree.ApplyChanges())
|
||||
{
|
||||
nodeView.RefreshState();
|
||||
}
|
||||
});
|
||||
|
||||
Add(imguiContainer);
|
||||
propertyTree.Dispose();
|
||||
}
|
||||
}
|
||||
}
|
11
Editor/Inspector/GraphInspector.cs.meta
Normal file
11
Editor/Inspector/GraphInspector.cs.meta
Normal file
@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: e3354982c2d9e304da519e305e3a88ba
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
8
Editor/Misc.meta
Normal file
8
Editor/Misc.meta
Normal file
@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 70212f83948d68d49a038353c5c292e7
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
44
Editor/Misc/EditorResourceTool.cs
Normal file
44
Editor/Misc/EditorResourceTool.cs
Normal file
@ -0,0 +1,44 @@
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
|
||||
namespace AlicizaX.AnimationFlow.Editor {
|
||||
public static class EditorResourceTool {
|
||||
public static string editorAssets;
|
||||
|
||||
public static bool LocateEditorAssets() {
|
||||
string projectPath = Application.dataPath;
|
||||
if (projectPath.EndsWith("/Assets")) {
|
||||
projectPath = projectPath.Remove(projectPath.Length - ("Assets".Length));
|
||||
}
|
||||
editorAssets = "Packages/com.yuliuren.alicizaframework/ThirdParty/AnimationFlow/Editor/Styles";
|
||||
if (!System.IO.File.Exists(projectPath + editorAssets + "/AnimationFlowStyles.uss")) {
|
||||
var sdir = new System.IO.DirectoryInfo(Application.dataPath);
|
||||
var dirQueue = new Queue<System.IO.DirectoryInfo>();
|
||||
dirQueue.Enqueue(sdir);
|
||||
bool found = false;
|
||||
while (dirQueue.Count > 0) {
|
||||
System.IO.DirectoryInfo dir = dirQueue.Dequeue();
|
||||
if (System.IO.File.Exists(dir.FullName + "/AnimationFlowStyles.uss")) {
|
||||
string path = dir.FullName.Replace('\\', '/');
|
||||
found = true;
|
||||
path = path.Replace(projectPath, "");
|
||||
if (path.StartsWith("/")) {
|
||||
path = path.Remove(0, 1);
|
||||
}
|
||||
editorAssets = path;
|
||||
return true;
|
||||
}
|
||||
var dirs = dir.GetDirectories();
|
||||
for (int i = 0; i < dirs.Length; i++) {
|
||||
dirQueue.Enqueue(dirs[i]);
|
||||
}
|
||||
}
|
||||
if (!found) {
|
||||
Debug.LogWarning("Could not locate editor assets folder. Make sure you have imported the package correctly.");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
11
Editor/Misc/EditorResourceTool.cs.meta
Normal file
11
Editor/Misc/EditorResourceTool.cs.meta
Normal file
@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: f7a3682890e722b41b230347c29487d8
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
8
Editor/Styles.meta
Normal file
8
Editor/Styles.meta
Normal file
@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: bc7e58d5bf8127246b4ef1945c0d9140
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
7
Editor/Styles/AnimationFlowStyles.uss
Normal file
7
Editor/Styles/AnimationFlowStyles.uss
Normal file
@ -0,0 +1,7 @@
|
||||
GridBackground
|
||||
{
|
||||
--grid-background-color:#2b2b2b;
|
||||
--line-color:rgba(55,55,55,1);
|
||||
--thick-line-color:rgba(55,55,55,1);
|
||||
--spacing:40;
|
||||
}
|
11
Editor/Styles/AnimationFlowStyles.uss.meta
Normal file
11
Editor/Styles/AnimationFlowStyles.uss.meta
Normal file
@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 5f82e3630fa0ecb41b029ea6ce3a5cbb
|
||||
ScriptedImporter:
|
||||
internalIDToNameTable: []
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
script: {fileID: 12385, guid: 0000000000000000e000000000000000, type: 0}
|
||||
disableValidation: 0
|
BIN
Editor/Styles/Complete.png
Normal file
BIN
Editor/Styles/Complete.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 18 KiB |
98
Editor/Styles/Complete.png.meta
Normal file
98
Editor/Styles/Complete.png.meta
Normal file
@ -0,0 +1,98 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 675b0173b4bfbcb4ebd0ec1d0fdc3293
|
||||
TextureImporter:
|
||||
fileIDToRecycleName: {}
|
||||
serializedVersion: 4
|
||||
mipmaps:
|
||||
mipMapMode: 0
|
||||
enableMipMap: 0
|
||||
sRGBTexture: 0
|
||||
linearTexture: 1
|
||||
fadeOut: 0
|
||||
borderMipMap: 0
|
||||
mipMapFadeDistanceStart: 1
|
||||
mipMapFadeDistanceEnd: 3
|
||||
bumpmap:
|
||||
convertToNormalMap: 0
|
||||
externalNormalMap: 0
|
||||
heightScale: 0.25
|
||||
normalMapFilter: 0
|
||||
isReadable: 0
|
||||
grayScaleToAlpha: 0
|
||||
generateCubemap: 6
|
||||
cubemapConvolution: 0
|
||||
seamlessCubemap: 0
|
||||
textureFormat: -3
|
||||
maxTextureSize: 1024
|
||||
textureSettings:
|
||||
filterMode: -1
|
||||
aniso: 1
|
||||
mipBias: -1
|
||||
wrapMode: 1
|
||||
nPOTScale: 0
|
||||
lightmap: 0
|
||||
compressionQuality: 50
|
||||
spriteMode: 0
|
||||
spriteExtrude: 1
|
||||
spriteMeshType: 1
|
||||
alignment: 0
|
||||
spritePivot: {x: 0.5, y: 0.5}
|
||||
spriteBorder: {x: 0, y: 0, z: 0, w: 0}
|
||||
spritePixelsToUnits: 100
|
||||
alphaUsage: 1
|
||||
alphaIsTransparency: 1
|
||||
spriteTessellationDetail: -1
|
||||
textureType: 2
|
||||
textureShape: 1
|
||||
maxTextureSizeSet: 0
|
||||
compressionQualitySet: 0
|
||||
textureFormatSet: 0
|
||||
platformSettings:
|
||||
- buildTarget: DefaultTexturePlatform
|
||||
maxTextureSize: 1024
|
||||
textureFormat: -1
|
||||
textureCompression: 0
|
||||
compressionQuality: 50
|
||||
crunchedCompression: 0
|
||||
allowsAlphaSplitting: 0
|
||||
overridden: 0
|
||||
- buildTarget: Standalone
|
||||
maxTextureSize: 1024
|
||||
textureFormat: -1
|
||||
textureCompression: 0
|
||||
compressionQuality: 50
|
||||
crunchedCompression: 0
|
||||
allowsAlphaSplitting: 0
|
||||
overridden: 0
|
||||
- buildTarget: Android
|
||||
maxTextureSize: 1024
|
||||
textureFormat: -1
|
||||
textureCompression: 0
|
||||
compressionQuality: 50
|
||||
crunchedCompression: 0
|
||||
allowsAlphaSplitting: 0
|
||||
overridden: 0
|
||||
- buildTarget: Windows Store Apps
|
||||
maxTextureSize: 1024
|
||||
textureFormat: -1
|
||||
textureCompression: 0
|
||||
compressionQuality: 50
|
||||
crunchedCompression: 0
|
||||
allowsAlphaSplitting: 0
|
||||
overridden: 0
|
||||
- buildTarget: WebGL
|
||||
maxTextureSize: 1024
|
||||
textureFormat: -1
|
||||
textureCompression: 0
|
||||
compressionQuality: 50
|
||||
crunchedCompression: 0
|
||||
allowsAlphaSplitting: 0
|
||||
overridden: 0
|
||||
spriteSheet:
|
||||
serializedVersion: 2
|
||||
sprites: []
|
||||
outline: []
|
||||
spritePackingTag:
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
7
Editor/Styles/SplitView.cs
Normal file
7
Editor/Styles/SplitView.cs
Normal file
@ -0,0 +1,7 @@
|
||||
using UnityEngine.UIElements;
|
||||
|
||||
namespace AlicizaX.AnimationFlow.Editor {
|
||||
public class SplitView : TwoPaneSplitView {
|
||||
public new class UxmlFactory : UxmlFactory<SplitView, UxmlTraits> { }
|
||||
}
|
||||
}
|
3
Editor/Styles/SplitView.cs.meta
Normal file
3
Editor/Styles/SplitView.cs.meta
Normal file
@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: a794fdf26eb8e9c4aac599b04c03fa37
|
||||
timeCreated: 1675978413
|
BIN
Editor/Styles/UICheckMark.png
Normal file
BIN
Editor/Styles/UICheckMark.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 973 B |
117
Editor/Styles/UICheckMark.png.meta
Normal file
117
Editor/Styles/UICheckMark.png.meta
Normal file
@ -0,0 +1,117 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 3a8e09bf61f38fe42beb76e9adc5921d
|
||||
TextureImporter:
|
||||
internalIDToNameTable: []
|
||||
externalObjects: {}
|
||||
serializedVersion: 13
|
||||
mipmaps:
|
||||
mipMapMode: 0
|
||||
enableMipMap: 1
|
||||
sRGBTexture: 1
|
||||
linearTexture: 0
|
||||
fadeOut: 0
|
||||
borderMipMap: 0
|
||||
mipMapsPreserveCoverage: 0
|
||||
alphaTestReferenceValue: 0.5
|
||||
mipMapFadeDistanceStart: 1
|
||||
mipMapFadeDistanceEnd: 3
|
||||
bumpmap:
|
||||
convertToNormalMap: 0
|
||||
externalNormalMap: 0
|
||||
heightScale: 0.25
|
||||
normalMapFilter: 0
|
||||
flipGreenChannel: 0
|
||||
isReadable: 0
|
||||
streamingMipmaps: 0
|
||||
streamingMipmapsPriority: 0
|
||||
vTOnly: 0
|
||||
ignoreMipmapLimit: 0
|
||||
grayScaleToAlpha: 0
|
||||
generateCubemap: 6
|
||||
cubemapConvolution: 0
|
||||
seamlessCubemap: 0
|
||||
textureFormat: 1
|
||||
maxTextureSize: 2048
|
||||
textureSettings:
|
||||
serializedVersion: 2
|
||||
filterMode: 0
|
||||
aniso: 1
|
||||
mipBias: 0
|
||||
wrapU: 0
|
||||
wrapV: 0
|
||||
wrapW: 0
|
||||
nPOTScale: 0
|
||||
lightmap: 0
|
||||
compressionQuality: 50
|
||||
spriteMode: 1
|
||||
spriteExtrude: 1
|
||||
spriteMeshType: 0
|
||||
alignment: 0
|
||||
spritePivot: {x: 0.5, y: 0.5}
|
||||
spritePixelsToUnits: 100
|
||||
spriteBorder: {x: 0, y: 0, z: 0, w: 0}
|
||||
spriteGenerateFallbackPhysicsShape: 1
|
||||
alphaUsage: 1
|
||||
alphaIsTransparency: 0
|
||||
spriteTessellationDetail: -1
|
||||
textureType: 0
|
||||
textureShape: 1
|
||||
singleChannelComponent: 0
|
||||
flipbookRows: 1
|
||||
flipbookColumns: 1
|
||||
maxTextureSizeSet: 0
|
||||
compressionQualitySet: 0
|
||||
textureFormatSet: 0
|
||||
ignorePngGamma: 0
|
||||
applyGammaDecoding: 1
|
||||
swizzle: 50462976
|
||||
cookieLightType: 1
|
||||
platformSettings:
|
||||
- serializedVersion: 4
|
||||
buildTarget: DefaultTexturePlatform
|
||||
maxTextureSize: 32
|
||||
resizeAlgorithm: 1
|
||||
textureFormat: -1
|
||||
textureCompression: 0
|
||||
compressionQuality: 50
|
||||
crunchedCompression: 0
|
||||
allowsAlphaSplitting: 0
|
||||
overridden: 0
|
||||
ignorePlatformSupport: 0
|
||||
androidETC2FallbackOverride: 0
|
||||
forceMaximumCompressionQuality_BC6H_BC7: 0
|
||||
- serializedVersion: 4
|
||||
buildTarget: Standalone
|
||||
maxTextureSize: 32
|
||||
resizeAlgorithm: 1
|
||||
textureFormat: -1
|
||||
textureCompression: 0
|
||||
compressionQuality: 50
|
||||
crunchedCompression: 0
|
||||
allowsAlphaSplitting: 0
|
||||
overridden: 0
|
||||
ignorePlatformSupport: 0
|
||||
androidETC2FallbackOverride: 0
|
||||
forceMaximumCompressionQuality_BC6H_BC7: 0
|
||||
spriteSheet:
|
||||
serializedVersion: 2
|
||||
sprites: []
|
||||
outline: []
|
||||
customData:
|
||||
physicsShape: []
|
||||
bones: []
|
||||
spriteID: 5e97eb03825dee720800000000000000
|
||||
internalID: 0
|
||||
vertices: []
|
||||
indices:
|
||||
edges: []
|
||||
weights: []
|
||||
secondaryTextures: []
|
||||
spriteCustomMetadata:
|
||||
entries: []
|
||||
nameFileIdTable: {}
|
||||
mipmapLimitGroupName:
|
||||
pSDRemoveMatte: 0
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
6
Editor/Styles/UIGraphWindow.uxml
Normal file
6
Editor/Styles/UIGraphWindow.uxml
Normal file
@ -0,0 +1,6 @@
|
||||
<ui:UXML xmlns:ui="UnityEngine.UIElements" xmlns:uie="UnityEditor.UIElements" xsi="http://www.w3.org/2001/XMLSchema-instance" engine="UnityEngine.UIElements" editor="UnityEditor.UIElements" noNamespaceSchemaLocation="../../../../../UIElementsSchema/UIElements.xsd" editor-extension-mode="True">
|
||||
<AlicizaX.AnimationFlow.Editor.SplitView fixed-pane-index="0" fixed-pane-initial-dimension="250" tabindex="0">
|
||||
<ui:VisualElement name="Inspector" />
|
||||
<ui:VisualElement name="Graph" style="flex-grow: 1;" />
|
||||
</AlicizaX.AnimationFlow.Editor.SplitView>
|
||||
</ui:UXML>
|
10
Editor/Styles/UIGraphWindow.uxml.meta
Normal file
10
Editor/Styles/UIGraphWindow.uxml.meta
Normal file
@ -0,0 +1,10 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 43465dc65d73bca49a224ece1d2b91d8
|
||||
ScriptedImporter:
|
||||
internalIDToNameTable: []
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
script: {fileID: 13804, guid: 0000000000000000e000000000000000, type: 0}
|
BIN
Editor/Styles/Warning.png
Normal file
BIN
Editor/Styles/Warning.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 20 KiB |
98
Editor/Styles/Warning.png.meta
Normal file
98
Editor/Styles/Warning.png.meta
Normal file
@ -0,0 +1,98 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 90b2d00dd1c22fe4b8edb550dabd9dc5
|
||||
TextureImporter:
|
||||
fileIDToRecycleName: {}
|
||||
serializedVersion: 4
|
||||
mipmaps:
|
||||
mipMapMode: 0
|
||||
enableMipMap: 0
|
||||
sRGBTexture: 0
|
||||
linearTexture: 1
|
||||
fadeOut: 0
|
||||
borderMipMap: 0
|
||||
mipMapFadeDistanceStart: 1
|
||||
mipMapFadeDistanceEnd: 3
|
||||
bumpmap:
|
||||
convertToNormalMap: 0
|
||||
externalNormalMap: 0
|
||||
heightScale: 0.25
|
||||
normalMapFilter: 0
|
||||
isReadable: 0
|
||||
grayScaleToAlpha: 0
|
||||
generateCubemap: 6
|
||||
cubemapConvolution: 0
|
||||
seamlessCubemap: 0
|
||||
textureFormat: -3
|
||||
maxTextureSize: 1024
|
||||
textureSettings:
|
||||
filterMode: 1
|
||||
aniso: 1
|
||||
mipBias: -1
|
||||
wrapMode: 1
|
||||
nPOTScale: 0
|
||||
lightmap: 0
|
||||
compressionQuality: 50
|
||||
spriteMode: 0
|
||||
spriteExtrude: 1
|
||||
spriteMeshType: 1
|
||||
alignment: 0
|
||||
spritePivot: {x: 0.5, y: 0.5}
|
||||
spriteBorder: {x: 0, y: 0, z: 0, w: 0}
|
||||
spritePixelsToUnits: 100
|
||||
alphaUsage: 1
|
||||
alphaIsTransparency: 1
|
||||
spriteTessellationDetail: -1
|
||||
textureType: 2
|
||||
textureShape: 1
|
||||
maxTextureSizeSet: 0
|
||||
compressionQualitySet: 0
|
||||
textureFormatSet: 0
|
||||
platformSettings:
|
||||
- buildTarget: DefaultTexturePlatform
|
||||
maxTextureSize: 1024
|
||||
textureFormat: -1
|
||||
textureCompression: 0
|
||||
compressionQuality: 50
|
||||
crunchedCompression: 0
|
||||
allowsAlphaSplitting: 0
|
||||
overridden: 0
|
||||
- buildTarget: Standalone
|
||||
maxTextureSize: 1024
|
||||
textureFormat: -1
|
||||
textureCompression: 0
|
||||
compressionQuality: 50
|
||||
crunchedCompression: 0
|
||||
allowsAlphaSplitting: 0
|
||||
overridden: 0
|
||||
- buildTarget: Android
|
||||
maxTextureSize: 1024
|
||||
textureFormat: -1
|
||||
textureCompression: 0
|
||||
compressionQuality: 50
|
||||
crunchedCompression: 0
|
||||
allowsAlphaSplitting: 0
|
||||
overridden: 0
|
||||
- buildTarget: Windows Store Apps
|
||||
maxTextureSize: 1024
|
||||
textureFormat: -1
|
||||
textureCompression: 0
|
||||
compressionQuality: 50
|
||||
crunchedCompression: 0
|
||||
allowsAlphaSplitting: 0
|
||||
overridden: 0
|
||||
- buildTarget: WebGL
|
||||
maxTextureSize: 1024
|
||||
textureFormat: -1
|
||||
textureCompression: 0
|
||||
compressionQuality: 50
|
||||
crunchedCompression: 0
|
||||
allowsAlphaSplitting: 0
|
||||
overridden: 0
|
||||
spriteSheet:
|
||||
serializedVersion: 2
|
||||
sprites: []
|
||||
outline: []
|
||||
spritePackingTag:
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
8
Editor/Window.meta
Normal file
8
Editor/Window.meta
Normal file
@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 72f6cddf7a63a9f4db60812679acf979
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
344
Editor/Window/GraphWindow.cs
Normal file
344
Editor/Window/GraphWindow.cs
Normal file
@ -0,0 +1,344 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using AlicizaX.AnimationFlow.Runtime;
|
||||
using UnityEditor;
|
||||
using UnityEngine;
|
||||
using UnityEngine.UIElements;
|
||||
|
||||
namespace AlicizaX.AnimationFlow.Editor
|
||||
{
|
||||
public class GraphWindow : EditorWindow
|
||||
{
|
||||
private GraphInspector graphInspector;
|
||||
private GraphView graphContentView;
|
||||
private Runtime.AnimationFlow animationFlowComponent;
|
||||
private float editorPreviousTime;
|
||||
|
||||
private bool _subScribeEditorEventState;
|
||||
|
||||
[MenuItem("Window/AnimationGraph")]
|
||||
public static void Open()
|
||||
{
|
||||
GetWindow<GraphWindow>("AnimationFlow");
|
||||
}
|
||||
|
||||
private void Update()
|
||||
{
|
||||
if (graphContentView == null || animationFlowComponent == null || Application.isPlaying)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (animationFlowComponent.InPlaying)
|
||||
{
|
||||
float delta = (Time.realtimeSinceStartup - editorPreviousTime) * Time.timeScale;
|
||||
editorPreviousTime = Time.realtimeSinceStartup;
|
||||
animationFlowComponent.Tick(delta);
|
||||
}
|
||||
|
||||
List<ActionNode> nodes = new List<ActionNode>();
|
||||
foreach (var VARIABLE in animationFlowComponent.AnimationNodes)
|
||||
{
|
||||
nodes.Add(VARIABLE);
|
||||
}
|
||||
|
||||
UpdateNodeState(nodes);
|
||||
}
|
||||
|
||||
private void UpdateNodeState(List<ActionNode> nodes)
|
||||
{
|
||||
foreach (var node in nodes)
|
||||
{
|
||||
switch (node.State)
|
||||
{
|
||||
case EState.Enter:
|
||||
graphContentView?.OnNodeEnter(node);
|
||||
break;
|
||||
case EState.Running:
|
||||
graphContentView?.OnNodeUpdate(node);
|
||||
break;
|
||||
case EState.Exit:
|
||||
graphContentView?.OnNodeExit(node);
|
||||
break;
|
||||
;
|
||||
}
|
||||
|
||||
if (node.Childs.Count > 0)
|
||||
{
|
||||
UpdateNodeState(node.Childs);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private void OnEnable()
|
||||
{
|
||||
animationFlowComponent = null;
|
||||
BuildView();
|
||||
CheckSelectionAnimationFlow();
|
||||
Selection.selectionChanged -= OnSelectionChanged;
|
||||
Selection.selectionChanged += OnSelectionChanged;
|
||||
Undo.undoRedoPerformed -= UndoRedoPerformed;
|
||||
Undo.undoRedoPerformed += UndoRedoPerformed;
|
||||
EditorApplication.playModeStateChanged -= OnModeStateChanged;
|
||||
EditorApplication.playModeStateChanged += OnModeStateChanged;
|
||||
}
|
||||
|
||||
|
||||
private void OnDisable()
|
||||
{
|
||||
Selection.selectionChanged -= OnSelectionChanged;
|
||||
Undo.undoRedoPerformed -= UndoRedoPerformed;
|
||||
EditorApplication.playModeStateChanged -= OnModeStateChanged;
|
||||
if (animationFlowComponent != null)
|
||||
{
|
||||
animationFlowComponent.ResetNode();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 生成View
|
||||
/// </summary>
|
||||
private void BuildView()
|
||||
{
|
||||
if (!EditorResourceTool.LocateEditorAssets())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
Texture2D btnPlayIcon = EditorGUIUtility.FindTexture("d_PlayButton");
|
||||
Texture2D btnPauseIcon = EditorGUIUtility.FindTexture("d_PauseButton");
|
||||
Texture2D btnStepIcon = EditorGUIUtility.FindTexture("d_StepButton");
|
||||
Texture2D btnSaveIcon = EditorGUIUtility.FindTexture("SaveActive");
|
||||
|
||||
VisualTreeAsset visual_tree = AssetDatabase.LoadAssetAtPath<VisualTreeAsset>(EditorResourceTool.editorAssets + "/UIGraphWindow.uxml");
|
||||
visual_tree.CloneTree(rootVisualElement);
|
||||
graphInspector = new GraphInspector();
|
||||
rootVisualElement.Q<VisualElement>("Inspector").Add(graphInspector);
|
||||
|
||||
VisualElement graph_parent = rootVisualElement.Q<VisualElement>("Graph");
|
||||
|
||||
|
||||
GUIStyle gui_style = new();
|
||||
Texture2D texture = new(1, 1);
|
||||
texture.SetPixel(0, 0, new Color(0.25f, 0.25f, 0.25f, 1f));
|
||||
texture.Apply();
|
||||
gui_style.normal.background = texture;
|
||||
gui_style.padding = new RectOffset(5, 5, 4, 4);
|
||||
int index_name = 0;
|
||||
IMGUIContainer imgui_container = new(() =>
|
||||
{
|
||||
if (animationFlowComponent == null)
|
||||
{
|
||||
graphContentView?.ClearGraph();
|
||||
return;
|
||||
}
|
||||
|
||||
GUILayout.BeginHorizontal(gui_style);
|
||||
|
||||
List<string> keys = new();
|
||||
foreach (ActionNode baseData in animationFlowComponent.AnimationNodes)
|
||||
{
|
||||
if (baseData is EntryNode root && !string.IsNullOrEmpty(root.Name))
|
||||
{
|
||||
keys.Add(root.Name);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
GUI.color = !animationFlowComponent.InPlaying && keys.Count > 0 ? Color.white : Color.gray;
|
||||
index_name = EditorGUILayout.Popup(index_name, keys.ToArray(), GUILayout.Width(100));
|
||||
if (GUILayout.Button(btnPlayIcon))
|
||||
{
|
||||
if (keys.Count > 0)
|
||||
{
|
||||
if (animationFlowComponent.InPlaying)
|
||||
{
|
||||
animationFlowComponent.Stop();
|
||||
return;
|
||||
}
|
||||
|
||||
OnBtnClickPlay(keys[index_name]);
|
||||
}
|
||||
}
|
||||
|
||||
GUI.color = animationFlowComponent.InPlaying ? Color.white : Color.gray;
|
||||
if (GUILayout.Button(btnPauseIcon))
|
||||
{
|
||||
OnBtnClickPause();
|
||||
}
|
||||
|
||||
GUI.color = animationFlowComponent.InPlaying || animationFlowComponent.InPause ? Color.white : Color.gray;
|
||||
if (GUILayout.Button(btnStepIcon))
|
||||
{
|
||||
OnBtnClickStep();
|
||||
}
|
||||
|
||||
|
||||
GUI.color = Color.white;
|
||||
GUILayout.EndHorizontal();
|
||||
});
|
||||
graph_parent.Add(imgui_container);
|
||||
imgui_container.style.position = Position.Absolute;
|
||||
imgui_container.style.bottom = 0;
|
||||
imgui_container.style.alignSelf = Align.Center;
|
||||
imgui_container.style.height = 40;
|
||||
|
||||
graphContentView = new(this);
|
||||
graph_parent.Insert(0, graphContentView);
|
||||
}
|
||||
|
||||
private void OnFocus()
|
||||
{
|
||||
CheckSelectionAnimationFlow();
|
||||
}
|
||||
|
||||
private void OnSelectionChanged()
|
||||
{
|
||||
CheckSelectionAnimationFlow();
|
||||
}
|
||||
|
||||
private void UndoRedoPerformed()
|
||||
{
|
||||
RePaintGraph();
|
||||
}
|
||||
|
||||
private void OnModeStateChanged(PlayModeStateChange _)
|
||||
{
|
||||
if (TryGetPlayerFromSelection())
|
||||
{
|
||||
RePaintGraph();
|
||||
}
|
||||
else
|
||||
{
|
||||
graphInspector.Clear();
|
||||
graphContentView.ClearGraph();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 检查当前选中的物体是否存在AnimationFlow组件
|
||||
/// </summary>
|
||||
private void CheckSelectionAnimationFlow()
|
||||
{
|
||||
if (TryGetPlayerFromSelection())
|
||||
{
|
||||
RePaintGraph();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private void RePaintGraph()
|
||||
{
|
||||
List<ActionNode> nodes = new List<ActionNode>();
|
||||
foreach (var VARIABLE in animationFlowComponent.AnimationNodes)
|
||||
{
|
||||
nodes.Add(VARIABLE);
|
||||
}
|
||||
|
||||
CheckEmptyNode(nodes);
|
||||
graphInspector.Clear();
|
||||
graphContentView.ClearGraph();
|
||||
graphContentView.SetAnimationFlow(animationFlowComponent);
|
||||
}
|
||||
|
||||
private void CheckEmptyNode(List<ActionNode> nodes)
|
||||
{
|
||||
for (int i = nodes.Count - 1; i >= 0; i--)
|
||||
{
|
||||
if (nodes[i] == null)
|
||||
{
|
||||
nodes.RemoveAt(i);
|
||||
}
|
||||
|
||||
if (nodes[i].Childs.Count > 0)
|
||||
{
|
||||
CheckEmptyNode(nodes[i].Childs);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private bool TryGetPlayerFromSelection()
|
||||
{
|
||||
if (Selection.activeGameObject != null)
|
||||
{
|
||||
Runtime.AnimationFlow new_animation_flow = Selection.activeGameObject.GetComponent<Runtime.AnimationFlow>();
|
||||
if (new_animation_flow != null && (animationFlowComponent == null || new_animation_flow != animationFlowComponent))
|
||||
{
|
||||
if (animationFlowComponent != null)
|
||||
{
|
||||
// DeleteAction();
|
||||
}
|
||||
|
||||
animationFlowComponent = new_animation_flow;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
#region 行为树底部菜单响应事件
|
||||
|
||||
private void OnBtnClickPlay(string name)
|
||||
{
|
||||
if (graphContentView == null || animationFlowComponent == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (animationFlowComponent.AnimationNodes.Exists(v => !v.Valid()))
|
||||
{
|
||||
EditorUtility.DisplayDialog("Warning", "Please make sure the required parameters are set.", "ok");
|
||||
return;
|
||||
}
|
||||
|
||||
editorPreviousTime = Time.realtimeSinceStartup;
|
||||
ResetView();
|
||||
animationFlowComponent.Play(name);
|
||||
}
|
||||
|
||||
private void OnBtnClickPause()
|
||||
{
|
||||
if (graphContentView == null || animationFlowComponent == null || !animationFlowComponent.InPlaying)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
animationFlowComponent.AnimationFlowPlayebleType = EAnimationFlowPlayebleType.Pause;
|
||||
}
|
||||
|
||||
private void OnBtnClickStep()
|
||||
{
|
||||
if (graphContentView == null || animationFlowComponent == null || !animationFlowComponent.InPlaying || !animationFlowComponent.InPause)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
animationFlowComponent.Tick(0.016f);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
|
||||
public void OnSelect(NodeView node_view)
|
||||
{
|
||||
graphInspector.DrawNode(node_view);
|
||||
}
|
||||
|
||||
public void OnNodeRemove()
|
||||
{
|
||||
graphInspector.Clear();
|
||||
}
|
||||
|
||||
|
||||
private void ResetView()
|
||||
{
|
||||
graphContentView?.ResetView();
|
||||
}
|
||||
}
|
||||
}
|
11
Editor/Window/GraphWindow.cs.meta
Normal file
11
Editor/Window/GraphWindow.cs.meta
Normal file
@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 0b445b46064d2e84695eb2caba51708f
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
201
LICENSE.md
Normal file
201
LICENSE.md
Normal file
@ -0,0 +1,201 @@
|
||||
Apache License
|
||||
Version 2.0, January 2004
|
||||
http://www.apache.org/licenses/
|
||||
|
||||
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
||||
|
||||
1. Definitions.
|
||||
|
||||
"License" shall mean the terms and conditions for use, reproduction,
|
||||
and distribution as defined by Sections 1 through 9 of this document.
|
||||
|
||||
"Licensor" shall mean the copyright owner or entity authorized by
|
||||
the copyright owner that is granting the License.
|
||||
|
||||
"Legal Entity" shall mean the union of the acting entity and all
|
||||
other entities that control, are controlled by, or are under common
|
||||
control with that entity. For the purposes of this definition,
|
||||
"control" means (i) the power, direct or indirect, to cause the
|
||||
direction or management of such entity, whether by contract or
|
||||
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
||||
outstanding shares, or (iii) beneficial ownership of such entity.
|
||||
|
||||
"You" (or "Your") shall mean an individual or Legal Entity
|
||||
exercising permissions granted by this License.
|
||||
|
||||
"Source" form shall mean the preferred form for making modifications,
|
||||
including but not limited to software source code, documentation
|
||||
source, and configuration files.
|
||||
|
||||
"Object" form shall mean any form resulting from mechanical
|
||||
transformation or translation of a Source form, including but
|
||||
not limited to compiled object code, generated documentation,
|
||||
and conversions to other media types.
|
||||
|
||||
"Work" shall mean the work of authorship, whether in Source or
|
||||
Object form, made available under the License, as indicated by a
|
||||
copyright notice that is included in or attached to the work
|
||||
(an example is provided in the Appendix below).
|
||||
|
||||
"Derivative Works" shall mean any work, whether in Source or Object
|
||||
form, that is based on (or derived from) the Work and for which the
|
||||
editorial revisions, annotations, elaborations, or other modifications
|
||||
represent, as a whole, an original work of authorship. For the purposes
|
||||
of this License, Derivative Works shall not include works that remain
|
||||
separable from, or merely link (or bind by name) to the interfaces of,
|
||||
the Work and Derivative Works thereof.
|
||||
|
||||
"Contribution" shall mean any work of authorship, including
|
||||
the original version of the Work and any modifications or additions
|
||||
to that Work or Derivative Works thereof, that is intentionally
|
||||
submitted to Licensor for inclusion in the Work by the copyright owner
|
||||
or by an individual or Legal Entity authorized to submit on behalf of
|
||||
the copyright owner. For the purposes of this definition, "submitted"
|
||||
means any form of electronic, verbal, or written communication sent
|
||||
to the Licensor or its representatives, including but not limited to
|
||||
communication on electronic mailing lists, source code control systems,
|
||||
and issue tracking systems that are managed by, or on behalf of, the
|
||||
Licensor for the purpose of discussing and improving the Work, but
|
||||
excluding communication that is conspicuously marked or otherwise
|
||||
designated in writing by the copyright owner as "Not a Contribution."
|
||||
|
||||
"Contributor" shall mean Licensor and any individual or Legal Entity
|
||||
on behalf of whom a Contribution has been received by Licensor and
|
||||
subsequently incorporated within the Work.
|
||||
|
||||
2. Grant of Copyright License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
copyright license to reproduce, prepare Derivative Works of,
|
||||
publicly display, publicly perform, sublicense, and distribute the
|
||||
Work and such Derivative Works in Source or Object form.
|
||||
|
||||
3. Grant of Patent License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
(except as stated in this section) patent license to make, have made,
|
||||
use, offer to sell, sell, import, and otherwise transfer the Work,
|
||||
where such license applies only to those patent claims licensable
|
||||
by such Contributor that are necessarily infringed by their
|
||||
Contribution(s) alone or by combination of their Contribution(s)
|
||||
with the Work to which such Contribution(s) was submitted. If You
|
||||
institute patent litigation against any entity (including a
|
||||
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
||||
or a Contribution incorporated within the Work constitutes direct
|
||||
or contributory patent infringement, then any patent licenses
|
||||
granted to You under this License for that Work shall terminate
|
||||
as of the date such litigation is filed.
|
||||
|
||||
4. Redistribution. You may reproduce and distribute copies of the
|
||||
Work or Derivative Works thereof in any medium, with or without
|
||||
modifications, and in Source or Object form, provided that You
|
||||
meet the following conditions:
|
||||
|
||||
(a) You must give any other recipients of the Work or
|
||||
Derivative Works a copy of this License; and
|
||||
|
||||
(b) You must cause any modified files to carry prominent notices
|
||||
stating that You changed the files; and
|
||||
|
||||
(c) You must retain, in the Source form of any Derivative Works
|
||||
that You distribute, all copyright, patent, trademark, and
|
||||
attribution notices from the Source form of the Work,
|
||||
excluding those notices that do not pertain to any part of
|
||||
the Derivative Works; and
|
||||
|
||||
(d) If the Work includes a "NOTICE" text file as part of its
|
||||
distribution, then any Derivative Works that You distribute must
|
||||
include a readable copy of the attribution notices contained
|
||||
within such NOTICE file, excluding those notices that do not
|
||||
pertain to any part of the Derivative Works, in at least one
|
||||
of the following places: within a NOTICE text file distributed
|
||||
as part of the Derivative Works; within the Source form or
|
||||
documentation, if provided along with the Derivative Works; or,
|
||||
within a display generated by the Derivative Works, if and
|
||||
wherever such third-party notices normally appear. The contents
|
||||
of the NOTICE file are for informational purposes only and
|
||||
do not modify the License. You may add Your own attribution
|
||||
notices within Derivative Works that You distribute, alongside
|
||||
or as an addendum to the NOTICE text from the Work, provided
|
||||
that such additional attribution notices cannot be construed
|
||||
as modifying the License.
|
||||
|
||||
You may add Your own copyright statement to Your modifications and
|
||||
may provide additional or different license terms and conditions
|
||||
for use, reproduction, or distribution of Your modifications, or
|
||||
for any such Derivative Works as a whole, provided Your use,
|
||||
reproduction, and distribution of the Work otherwise complies with
|
||||
the conditions stated in this License.
|
||||
|
||||
5. Submission of Contributions. Unless You explicitly state otherwise,
|
||||
any Contribution intentionally submitted for inclusion in the Work
|
||||
by You to the Licensor shall be under the terms and conditions of
|
||||
this License, without any additional terms or conditions.
|
||||
Notwithstanding the above, nothing herein shall supersede or modify
|
||||
the terms of any separate license agreement you may have executed
|
||||
with Licensor regarding such Contributions.
|
||||
|
||||
6. Trademarks. This License does not grant permission to use the trade
|
||||
names, trademarks, service marks, or product names of the Licensor,
|
||||
except as required for reasonable and customary use in describing the
|
||||
origin of the Work and reproducing the content of the NOTICE file.
|
||||
|
||||
7. Disclaimer of Warranty. Unless required by applicable law or
|
||||
agreed to in writing, Licensor provides the Work (and each
|
||||
Contributor provides its Contributions) on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
implied, including, without limitation, any warranties or conditions
|
||||
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
||||
PARTICULAR PURPOSE. You are solely responsible for determining the
|
||||
appropriateness of using or redistributing the Work and assume any
|
||||
risks associated with Your exercise of permissions under this License.
|
||||
|
||||
8. Limitation of Liability. In no event and under no legal theory,
|
||||
whether in tort (including negligence), contract, or otherwise,
|
||||
unless required by applicable law (such as deliberate and grossly
|
||||
negligent acts) or agreed to in writing, shall any Contributor be
|
||||
liable to You for damages, including any direct, indirect, special,
|
||||
incidental, or consequential damages of any character arising as a
|
||||
result of this License or out of the use or inability to use the
|
||||
Work (including but not limited to damages for loss of goodwill,
|
||||
work stoppage, computer failure or malfunction, or any and all
|
||||
other commercial damages or losses), even if such Contributor
|
||||
has been advised of the possibility of such damages.
|
||||
|
||||
9. Accepting Warranty or Additional Liability. While redistributing
|
||||
the Work or Derivative Works thereof, You may choose to offer,
|
||||
and charge a fee for, acceptance of support, warranty, indemnity,
|
||||
or other liability obligations and/or rights consistent with this
|
||||
License. However, in accepting such obligations, You may act only
|
||||
on Your own behalf and on Your sole responsibility, not on behalf
|
||||
of any other Contributor, and only if You agree to indemnify,
|
||||
defend, and hold each Contributor harmless for any liability
|
||||
incurred by, or claims asserted against, such Contributor by reason
|
||||
of your accepting any such warranty or additional liability.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
APPENDIX: How to apply the Apache License to your work.
|
||||
|
||||
To apply the Apache License to your work, attach the following
|
||||
boilerplate notice, with the fields enclosed by brackets "[]"
|
||||
replaced with your own identifying information. (Don't include
|
||||
the brackets!) The text should be enclosed in the appropriate
|
||||
comment syntax for the file format. We also recommend that a
|
||||
file or class name and description of purpose be included on the
|
||||
same "printed page" as the copyright notice for easier
|
||||
identification within third-party archives.
|
||||
|
||||
Copyright [2023] [ALianBlank of copyright owner][alianblank@outlook.com][https://alianblank.com/]
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
7
LICENSE.md.meta
Normal file
7
LICENSE.md.meta
Normal file
@ -0,0 +1,7 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 5a68ca6cac9f6bf4d879d41d6eed3744
|
||||
TextScriptImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
8
Runtime.meta
Normal file
8
Runtime.meta
Normal file
@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 464232d91c91b1848bdf08d6249dbf7e
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
14
Runtime/AlicizaX.AnimationFlow.Runtime.asmdef
Normal file
14
Runtime/AlicizaX.AnimationFlow.Runtime.asmdef
Normal file
@ -0,0 +1,14 @@
|
||||
{
|
||||
"name": "AlicizaX.AnimationFlow.Runtime",
|
||||
"rootNamespace": "AlicizaX.AnimationFlow.Runtime",
|
||||
"references": [],
|
||||
"includePlatforms": [],
|
||||
"excludePlatforms": [],
|
||||
"allowUnsafeCode": false,
|
||||
"overrideReferences": false,
|
||||
"precompiledReferences": [],
|
||||
"autoReferenced": true,
|
||||
"defineConstraints": [],
|
||||
"versionDefines": [],
|
||||
"noEngineReferences": false
|
||||
}
|
7
Runtime/AlicizaX.AnimationFlow.Runtime.asmdef.meta
Normal file
7
Runtime/AlicizaX.AnimationFlow.Runtime.asmdef.meta
Normal file
@ -0,0 +1,7 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 189d55e03d78888459720d730f4d2424
|
||||
AssemblyDefinitionImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
265
Runtime/AnimationFlow.cs
Normal file
265
Runtime/AnimationFlow.cs
Normal file
@ -0,0 +1,265 @@
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Sirenix.OdinInspector;
|
||||
using UnityEngine;
|
||||
|
||||
namespace AlicizaX.AnimationFlow.Runtime
|
||||
{
|
||||
public class AnimationFlow : MonoBehaviour
|
||||
{
|
||||
#region Editor相关
|
||||
|
||||
#if UNITY_EDITOR
|
||||
IEnumerable GetAllAnimationClips
|
||||
{
|
||||
get
|
||||
{
|
||||
List<string> keys = new();
|
||||
foreach (EntryNode root in AnimationNodes)
|
||||
{
|
||||
if (!string.IsNullOrEmpty(root.Name))
|
||||
{
|
||||
keys.Add(root.Name);
|
||||
}
|
||||
}
|
||||
|
||||
keys.Insert(0, "None");
|
||||
return keys;
|
||||
}
|
||||
}
|
||||
|
||||
[Button("节点编辑器", ButtonSizes.Large), GUIColor(0, 1, 0)]
|
||||
private void OpenGraphWindow()
|
||||
{
|
||||
UnityEditor.EditorApplication.ExecuteMenuItem("AlicizaFramework/Window/AnimationGraph");
|
||||
}
|
||||
#endif
|
||||
|
||||
#endregion
|
||||
|
||||
[HideInInspector] [SerializeReference] public List<EntryNode> AnimationNodes = new List<EntryNode>();
|
||||
|
||||
|
||||
[LabelText("动画片段")] [BoxGroup("基础设置", true)] [ValueDropdown("GetAllAnimationClips", ExpandAllMenuItems = true)] [SerializeField]
|
||||
private string _defaultPlayName = "None";
|
||||
|
||||
[LabelText("自动播放")] [BoxGroup("基础设置", true)] [SerializeField]
|
||||
private bool _enableAutoPlay;
|
||||
|
||||
|
||||
private List<ActionNode> _runningNodes = new List<ActionNode>();
|
||||
|
||||
private List<ActionNode> _resetNodes = new List<ActionNode>();
|
||||
|
||||
private ActionNode _curEntryNode;
|
||||
|
||||
private int _loopCount = 0;
|
||||
|
||||
/// <summary>
|
||||
/// 节点播放回调
|
||||
/// </summary>
|
||||
private Action _playFinishEvent;
|
||||
|
||||
/// <summary>
|
||||
/// 时间缩放系数 受Time.deltatime影响
|
||||
/// </summary>
|
||||
private float _timeScale = 1f;
|
||||
|
||||
public float TimeScale
|
||||
{
|
||||
get => _timeScale;
|
||||
set => _timeScale = value;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 当前节点状态
|
||||
/// </summary>
|
||||
private EAnimationFlowPlayebleType _playebleType = EAnimationFlowPlayebleType.Stop;
|
||||
|
||||
public EAnimationFlowPlayebleType AnimationFlowPlayebleType
|
||||
{
|
||||
get => _playebleType;
|
||||
set => _playebleType = value;
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 是否播放中
|
||||
/// </summary>
|
||||
public bool InPlaying => _playebleType == EAnimationFlowPlayebleType.Play;
|
||||
|
||||
/// <summary>
|
||||
/// 是否暂停中
|
||||
/// </summary>
|
||||
public bool InPause => _playebleType == EAnimationFlowPlayebleType.Pause;
|
||||
|
||||
|
||||
private void Start()
|
||||
{
|
||||
if (_enableAutoPlay)
|
||||
{
|
||||
Play(_defaultPlayName);
|
||||
}
|
||||
}
|
||||
|
||||
private void Update()
|
||||
{
|
||||
if (_playebleType == EAnimationFlowPlayebleType.Play)
|
||||
{
|
||||
Tick(Time.deltaTime * _timeScale);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public void Tick(float deltaTime)
|
||||
{
|
||||
List<ActionNode> runNodes = _runningNodes;
|
||||
int runCount = runNodes.Count;
|
||||
if (runCount == 0)
|
||||
{
|
||||
if (_loopCount > 0)
|
||||
{
|
||||
_loopCount--;
|
||||
ResetNode();
|
||||
PushNode(_curEntryNode);
|
||||
}
|
||||
else
|
||||
{
|
||||
StopFlow();
|
||||
}
|
||||
}
|
||||
|
||||
if (runCount > 0)
|
||||
{
|
||||
for (int i = runCount - 1; i >= 0; i--)
|
||||
{
|
||||
ActionNode node = _runningNodes[i];
|
||||
if (node.Condition())
|
||||
{
|
||||
PopNode(node);
|
||||
}
|
||||
else
|
||||
{
|
||||
node.elapsedTime = Mathf.Min(node.elapsedTime + deltaTime, node.Duration());
|
||||
node.OnUpdate(deltaTime);
|
||||
node.State = EState.Running;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public void ResetNode()
|
||||
{
|
||||
for (int i = _resetNodes.Count - 1; i >= 0; i--)
|
||||
{
|
||||
ActionNode node = _resetNodes[i];
|
||||
node.Reset();
|
||||
node.OnReset();
|
||||
}
|
||||
|
||||
_resetNodes.Clear();
|
||||
}
|
||||
|
||||
private void StopFlow(bool isInterrupt = false)
|
||||
{
|
||||
_playebleType = EAnimationFlowPlayebleType.Stop;
|
||||
_curEntryNode = null;
|
||||
_loopCount = 0;
|
||||
for (int i = _resetNodes.Count - 1; i >= 0; i--)
|
||||
{
|
||||
ActionNode node = _resetNodes[i];
|
||||
if (!Application.isPlaying)
|
||||
{
|
||||
node.OnReset();
|
||||
}
|
||||
|
||||
node.Reset();
|
||||
}
|
||||
|
||||
if (isInterrupt)
|
||||
{
|
||||
for (int i = _runningNodes.Count - 1; i >= 0; i--)
|
||||
{
|
||||
ActionNode node = _runningNodes[i];
|
||||
node.OnInterrupt();
|
||||
}
|
||||
}
|
||||
|
||||
if (_playFinishEvent != null) _playFinishEvent();
|
||||
|
||||
_resetNodes.Clear();
|
||||
_runningNodes.Clear();
|
||||
}
|
||||
|
||||
private void PopNode(ActionNode node)
|
||||
{
|
||||
node.OnExit();
|
||||
node.State = EState.Exit;
|
||||
_runningNodes.Remove(node);
|
||||
PushChildNode(node);
|
||||
}
|
||||
|
||||
private void PushChildNode(ActionNode node)
|
||||
{
|
||||
List<ActionNode> childNode = node.Childs;
|
||||
if (childNode.Count > 0)
|
||||
{
|
||||
foreach (var child in childNode)
|
||||
{
|
||||
PushNode(child);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void PushNode(ActionNode node)
|
||||
{
|
||||
node.OnInit();
|
||||
node.OnEnter();
|
||||
node.State = EState.Enter;
|
||||
_runningNodes.Add(node);
|
||||
_resetNodes.Add(node);
|
||||
}
|
||||
|
||||
|
||||
public void Play(string clipName = "", Action actionComplete = null)
|
||||
{
|
||||
if (_playebleType == EAnimationFlowPlayebleType.Play)
|
||||
{
|
||||
Debug.LogWarning($"animation flow is playing!");
|
||||
return;
|
||||
}
|
||||
|
||||
if (string.IsNullOrEmpty(clipName) || clipName == "None")
|
||||
{
|
||||
Debug.LogWarning($"animation name is empty!");
|
||||
return;
|
||||
}
|
||||
|
||||
_playFinishEvent = actionComplete;
|
||||
|
||||
EntryNode entryNode = AnimationNodes.Find(a => a.Name == clipName);
|
||||
if (entryNode == null)
|
||||
{
|
||||
Debug.LogWarning($"Can not find this Clip {clipName}!");
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
_loopCount = entryNode.LoopCount;
|
||||
_curEntryNode = entryNode;
|
||||
_playebleType = EAnimationFlowPlayebleType.Play;
|
||||
}
|
||||
|
||||
|
||||
public void Stop()
|
||||
{
|
||||
if (_playebleType == EAnimationFlowPlayebleType.Play)
|
||||
{
|
||||
StopFlow(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
11
Runtime/AnimationFlow.cs.meta
Normal file
11
Runtime/AnimationFlow.cs.meta
Normal file
@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: f7859f2b76d69e044b4e966f48a3607d
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
8
Runtime/Attribute.meta
Normal file
8
Runtime/Attribute.meta
Normal file
@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: eb9425389d58394438e9c298fb1be473
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
12
Runtime/Attribute/CategoryAttribute.cs
Normal file
12
Runtime/Attribute/CategoryAttribute.cs
Normal file
@ -0,0 +1,12 @@
|
||||
using System;
|
||||
using System.Diagnostics;
|
||||
|
||||
namespace AlicizaX.AnimationFlow.Runtime {
|
||||
[AttributeUsage(AttributeTargets.Class), Conditional("UNITY_EDITOR")]
|
||||
public class CategoryAttribute : Attribute {
|
||||
public readonly string category;
|
||||
public CategoryAttribute(string category) {
|
||||
this.category = category;
|
||||
}
|
||||
}
|
||||
}
|
11
Runtime/Attribute/CategoryAttribute.cs.meta
Normal file
11
Runtime/Attribute/CategoryAttribute.cs.meta
Normal file
@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 7c802bbbb85f92b46b9b8b25b7c60c6b
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
12
Runtime/Attribute/NameAttribute.cs
Normal file
12
Runtime/Attribute/NameAttribute.cs
Normal file
@ -0,0 +1,12 @@
|
||||
using System;
|
||||
using System.Diagnostics;
|
||||
|
||||
namespace AlicizaX.AnimationFlow.Runtime {
|
||||
[AttributeUsage(AttributeTargets.Class), Conditional("UNITY_EDITOR")]
|
||||
public class NameAttribute : Attribute {
|
||||
public readonly string name;
|
||||
public NameAttribute(string name) {
|
||||
this.name = name;
|
||||
}
|
||||
}
|
||||
}
|
11
Runtime/Attribute/NameAttribute.cs.meta
Normal file
11
Runtime/Attribute/NameAttribute.cs.meta
Normal file
@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 778aaafb0861e3c4db400e4c33dc196d
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
8
Runtime/Core.meta
Normal file
8
Runtime/Core.meta
Normal file
@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 3c6e796f19ed1b846af619435694f84c
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
8
Runtime/Core/Animation.meta
Normal file
8
Runtime/Core/Animation.meta
Normal file
@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: db4c0b464a82e5e41a5f34e2c8d16103
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
54
Runtime/Core/Animation/CanvasGroupAlphaTo.cs
Normal file
54
Runtime/Core/Animation/CanvasGroupAlphaTo.cs
Normal file
@ -0,0 +1,54 @@
|
||||
using UnityEngine;
|
||||
|
||||
namespace AlicizaX.AnimationFlow.Runtime {
|
||||
[Category("Animation")]
|
||||
public class CanvasGroupAlphaTo : ActionNode {
|
||||
public float duration = 1f;
|
||||
public EaseType easyType;
|
||||
public CanvasGroup target;
|
||||
public bool setFrom;
|
||||
public float from;
|
||||
public float to;
|
||||
|
||||
protected float orgValue;
|
||||
protected float enterValue;
|
||||
|
||||
public override void OnInit()
|
||||
{
|
||||
orgValue = target.alpha;
|
||||
}
|
||||
|
||||
public override void OnReset()
|
||||
{
|
||||
target.alpha = orgValue;
|
||||
}
|
||||
|
||||
public override void OnEnter() {
|
||||
if (setFrom) {
|
||||
target.alpha = from;
|
||||
}
|
||||
enterValue = target.alpha;
|
||||
}
|
||||
|
||||
public override void OnUpdate(float dt) {
|
||||
target.alpha = Easing.Ease(easyType, enterValue, to, elapsedTime / duration);
|
||||
}
|
||||
|
||||
public override bool Valid() {
|
||||
return target != null && duration > 0;
|
||||
}
|
||||
|
||||
public override float Duration() {
|
||||
return duration;
|
||||
}
|
||||
|
||||
public override bool HasSubTitle() {
|
||||
return true;
|
||||
}
|
||||
|
||||
public override string SubTitle() {
|
||||
return target != null ? target.name : null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
11
Runtime/Core/Animation/CanvasGroupAlphaTo.cs.meta
Normal file
11
Runtime/Core/Animation/CanvasGroupAlphaTo.cs.meta
Normal file
@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: c82daf623932c3345bf323b8896cb8ae
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
54
Runtime/Core/Animation/GraphicAlphaTo.cs
Normal file
54
Runtime/Core/Animation/GraphicAlphaTo.cs
Normal file
@ -0,0 +1,54 @@
|
||||
using UnityEngine;
|
||||
using UnityEngine.UI;
|
||||
|
||||
namespace AlicizaX.AnimationFlow.Runtime {
|
||||
[Category("Animation")]
|
||||
public class GraphicAlphaTo : ActionNode {
|
||||
public float duration = 1f;
|
||||
public EaseType easyType;
|
||||
public Graphic target;
|
||||
public bool setFrom;
|
||||
public float from;
|
||||
public float to;
|
||||
|
||||
protected float orgValue;
|
||||
protected float enterValue;
|
||||
|
||||
public override void OnInit() {
|
||||
orgValue = target.color.a;
|
||||
}
|
||||
|
||||
public override void OnReset() {
|
||||
target.color = new Color(target.color.r, target.color.g, target.color.b, orgValue);
|
||||
}
|
||||
|
||||
public override void OnEnter() {
|
||||
if (setFrom) {
|
||||
target.color = new Color(target.color.r, target.color.g, target.color.b, from);
|
||||
}
|
||||
enterValue = target.color.a;
|
||||
}
|
||||
|
||||
public override void OnUpdate(float dt) {
|
||||
float a = Easing.Ease(easyType, enterValue, to, elapsedTime / duration);
|
||||
target.color = new Color(target.color.r, target.color.g, target.color.b, a);
|
||||
}
|
||||
|
||||
public override bool Valid() {
|
||||
return target != null && duration > 0;
|
||||
}
|
||||
|
||||
public override float Duration() {
|
||||
return duration;
|
||||
}
|
||||
|
||||
public override bool HasSubTitle() {
|
||||
return true;
|
||||
}
|
||||
|
||||
public override string SubTitle() {
|
||||
return target != null ? target.name : null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
11
Runtime/Core/Animation/GraphicAlphaTo.cs.meta
Normal file
11
Runtime/Core/Animation/GraphicAlphaTo.cs.meta
Normal file
@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 0f361b6d0dd63444c90c7cf04cf4f1c8
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
64
Runtime/Core/Animation/GraphicColorTo.cs
Normal file
64
Runtime/Core/Animation/GraphicColorTo.cs
Normal file
@ -0,0 +1,64 @@
|
||||
using UnityEngine;
|
||||
using UnityEngine.UI;
|
||||
|
||||
namespace AlicizaX.AnimationFlow.Runtime
|
||||
{
|
||||
[Category("Animation")]
|
||||
public class GraphicColorTo : ActionNode
|
||||
{
|
||||
public float duration = 1f;
|
||||
public EaseType easyType;
|
||||
public Graphic target;
|
||||
public bool setFrom;
|
||||
public Color from = Color.white;
|
||||
public Color to = Color.white;
|
||||
|
||||
protected Color orgValue;
|
||||
protected Color enterValue;
|
||||
|
||||
public override void OnInit()
|
||||
{
|
||||
orgValue = target.color;
|
||||
}
|
||||
|
||||
public override void OnReset()
|
||||
{
|
||||
target.color = orgValue;
|
||||
}
|
||||
|
||||
public override void OnEnter()
|
||||
{
|
||||
if (setFrom)
|
||||
{
|
||||
target.color = from;
|
||||
}
|
||||
|
||||
enterValue = target.color;
|
||||
}
|
||||
|
||||
public override void OnUpdate(float dt)
|
||||
{
|
||||
target.color = Easing.Ease(easyType, enterValue, to, elapsedTime / duration);
|
||||
}
|
||||
|
||||
public override bool Valid()
|
||||
{
|
||||
return target != null && duration > 0;
|
||||
}
|
||||
|
||||
public override float Duration()
|
||||
{
|
||||
return duration;
|
||||
}
|
||||
|
||||
public override bool HasSubTitle()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
public override string SubTitle()
|
||||
{
|
||||
return target != null ? target.name : null;
|
||||
}
|
||||
}
|
||||
}
|
11
Runtime/Core/Animation/GraphicColorTo.cs.meta
Normal file
11
Runtime/Core/Animation/GraphicColorTo.cs.meta
Normal file
@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 9836fe491e0a4314fa94efc524735925
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
8
Runtime/Core/Animation/RotateBy.cs
Normal file
8
Runtime/Core/Animation/RotateBy.cs
Normal file
@ -0,0 +1,8 @@
|
||||
namespace AlicizaX.AnimationFlow.Runtime {
|
||||
public class RotateBy : RotateTo {
|
||||
public override void OnUpdate(float dt) {
|
||||
target.localEulerAngles = Easing.Ease(easyType, enterValue, enterValue + to, elapsedTime / duration);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
11
Runtime/Core/Animation/RotateBy.cs.meta
Normal file
11
Runtime/Core/Animation/RotateBy.cs.meta
Normal file
@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 0cce6a734565f484fba643dc361d3474
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
53
Runtime/Core/Animation/RotateTo.cs
Normal file
53
Runtime/Core/Animation/RotateTo.cs
Normal file
@ -0,0 +1,53 @@
|
||||
using UnityEngine;
|
||||
|
||||
namespace AlicizaX.AnimationFlow.Runtime {
|
||||
[Category("Animation")]
|
||||
public class RotateTo : ActionNode {
|
||||
public float duration = 1f;
|
||||
public EaseType easyType;
|
||||
public Transform target;
|
||||
public bool setFrom;
|
||||
public Vector3 from;
|
||||
public Vector3 to;
|
||||
|
||||
protected Vector3 orgValue;
|
||||
protected Vector3 enterValue;
|
||||
|
||||
public override void OnInit() {
|
||||
orgValue = target.localEulerAngles;
|
||||
}
|
||||
|
||||
|
||||
public override void OnReset() {
|
||||
target.localEulerAngles = orgValue;
|
||||
}
|
||||
|
||||
public override void OnEnter() {
|
||||
if (setFrom) {
|
||||
target.localEulerAngles = from;
|
||||
}
|
||||
enterValue = target.localEulerAngles;
|
||||
}
|
||||
|
||||
public override void OnUpdate(float dt) {
|
||||
target.localEulerAngles = Easing.Ease(easyType, enterValue, to, elapsedTime / duration);
|
||||
}
|
||||
|
||||
public override bool Valid() {
|
||||
return target != null && duration > 0;
|
||||
}
|
||||
|
||||
public override float Duration() {
|
||||
return duration;
|
||||
}
|
||||
|
||||
public override bool HasSubTitle() {
|
||||
return true;
|
||||
}
|
||||
|
||||
public override string SubTitle() {
|
||||
return target != null ? target.name : null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
11
Runtime/Core/Animation/RotateTo.cs.meta
Normal file
11
Runtime/Core/Animation/RotateTo.cs.meta
Normal file
@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 18a73287c11ce7940943c0bd25a874a6
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
7
Runtime/Core/Animation/ScaleBy.cs
Normal file
7
Runtime/Core/Animation/ScaleBy.cs
Normal file
@ -0,0 +1,7 @@
|
||||
namespace AlicizaX.AnimationFlow.Runtime {
|
||||
public class ScaleBy : ScaleTo {
|
||||
public override void OnUpdate(float dt) {
|
||||
target.localScale = Easing.Ease(easyType, enterValue, enterValue + to, elapsedTime / duration);
|
||||
}
|
||||
}
|
||||
}
|
11
Runtime/Core/Animation/ScaleBy.cs.meta
Normal file
11
Runtime/Core/Animation/ScaleBy.cs.meta
Normal file
@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 9f2109b4e7936fa4daa936c16631d872
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
53
Runtime/Core/Animation/ScaleTo.cs
Normal file
53
Runtime/Core/Animation/ScaleTo.cs
Normal file
@ -0,0 +1,53 @@
|
||||
using UnityEngine;
|
||||
|
||||
namespace AlicizaX.AnimationFlow.Runtime {
|
||||
[Category("Animation")]
|
||||
public class ScaleTo : ActionNode {
|
||||
public float duration = 1f;
|
||||
public EaseType easyType;
|
||||
public Transform target;
|
||||
public bool setFrom;
|
||||
public Vector3 from;
|
||||
public Vector3 to = Vector3.one;
|
||||
|
||||
protected Vector3 orgValue;
|
||||
protected Vector3 enterValue;
|
||||
|
||||
public override void OnInit() {
|
||||
orgValue = target.localScale;
|
||||
}
|
||||
|
||||
|
||||
|
||||
public override void OnReset() {
|
||||
target.localScale = orgValue;
|
||||
}
|
||||
|
||||
public override void OnEnter() {
|
||||
if (setFrom) {
|
||||
target.localScale = from;
|
||||
}
|
||||
enterValue = target.localScale;
|
||||
}
|
||||
|
||||
public override void OnUpdate(float dt) {
|
||||
target.localScale = Easing.Ease(easyType, enterValue, to, elapsedTime / duration);
|
||||
}
|
||||
|
||||
public override bool Valid() {
|
||||
return target != null && duration > 0;
|
||||
}
|
||||
|
||||
public override float Duration() {
|
||||
return duration;
|
||||
}
|
||||
|
||||
public override bool HasSubTitle() {
|
||||
return true;
|
||||
}
|
||||
|
||||
public override string SubTitle() {
|
||||
return target != null ? target.name : null;
|
||||
}
|
||||
}
|
||||
}
|
11
Runtime/Core/Animation/ScaleTo.cs.meta
Normal file
11
Runtime/Core/Animation/ScaleTo.cs.meta
Normal file
@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: ef75f4b0af6091c44a0e5379ce730cab
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
54
Runtime/Core/Animation/SpriteRendererAlphaTo.cs
Normal file
54
Runtime/Core/Animation/SpriteRendererAlphaTo.cs
Normal file
@ -0,0 +1,54 @@
|
||||
using UnityEngine;
|
||||
|
||||
namespace AlicizaX.AnimationFlow.Runtime {
|
||||
[Category("Animation")]
|
||||
public class SpriteRendererAlphaTo : ActionNode {
|
||||
public float duration = 1f;
|
||||
public EaseType easyType;
|
||||
public SpriteRenderer target;
|
||||
public bool setFrom;
|
||||
public float from;
|
||||
public float to;
|
||||
|
||||
protected float orgValue;
|
||||
protected float enterValue;
|
||||
|
||||
public override void OnInit() {
|
||||
orgValue = target.color.a;
|
||||
}
|
||||
|
||||
|
||||
public override void OnReset() {
|
||||
target.color = new Color(target.color.r, target.color.g, target.color.b, orgValue);
|
||||
}
|
||||
|
||||
public override void OnEnter() {
|
||||
if (setFrom) {
|
||||
target.color = target.color = new Color(target.color.r, target.color.g, target.color.b, from);
|
||||
}
|
||||
enterValue = target.color.a;
|
||||
}
|
||||
|
||||
public override void OnUpdate(float dt) {
|
||||
float a = Easing.Ease(easyType, enterValue, to, elapsedTime / duration);
|
||||
target.color = new Color(target.color.r, target.color.g, target.color.b, a);
|
||||
}
|
||||
|
||||
public override bool Valid() {
|
||||
return target != null && duration > 0;
|
||||
}
|
||||
|
||||
public override float Duration() {
|
||||
return duration;
|
||||
}
|
||||
|
||||
public override bool HasSubTitle() {
|
||||
return true;
|
||||
}
|
||||
|
||||
public override string SubTitle() {
|
||||
return target != null ? target.name : null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
11
Runtime/Core/Animation/SpriteRendererAlphaTo.cs.meta
Normal file
11
Runtime/Core/Animation/SpriteRendererAlphaTo.cs.meta
Normal file
@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: c9842477ac251bf42b93cc7b38b013e5
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
54
Runtime/Core/Animation/SpriteRendererColorTo.cs
Normal file
54
Runtime/Core/Animation/SpriteRendererColorTo.cs
Normal file
@ -0,0 +1,54 @@
|
||||
using UnityEngine;
|
||||
|
||||
|
||||
namespace AlicizaX.AnimationFlow.Runtime {
|
||||
[Category("Animation")]
|
||||
public class SpriteRendererColorTo : ActionNode {
|
||||
public float duration = 1f;
|
||||
public EaseType easyType;
|
||||
public SpriteRenderer target;
|
||||
public bool setFrom;
|
||||
public Color from = Color.white;
|
||||
public Color to = Color.white;
|
||||
|
||||
protected Color orgValue;
|
||||
protected Color enterValue;
|
||||
|
||||
public override void OnInit() {
|
||||
orgValue = target.color;
|
||||
}
|
||||
|
||||
|
||||
public override void OnReset() {
|
||||
target.color = orgValue;
|
||||
}
|
||||
|
||||
public override void OnEnter() {
|
||||
if (setFrom) {
|
||||
target.color = from;
|
||||
}
|
||||
enterValue = target.color;
|
||||
}
|
||||
|
||||
public override void OnUpdate(float dt) {
|
||||
target.color = Easing.Ease(easyType, enterValue, to, elapsedTime / duration);
|
||||
}
|
||||
|
||||
public override bool Valid() {
|
||||
return target != null && duration > 0;
|
||||
}
|
||||
|
||||
public override float Duration() {
|
||||
return duration;
|
||||
}
|
||||
|
||||
public override bool HasSubTitle() {
|
||||
return true;
|
||||
}
|
||||
|
||||
public override string SubTitle() {
|
||||
return target != null ? target.name : null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
11
Runtime/Core/Animation/SpriteRendererColorTo.cs.meta
Normal file
11
Runtime/Core/Animation/SpriteRendererColorTo.cs.meta
Normal file
@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 1327afe74b192734d89e2c8e5ba59bbc
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
7
Runtime/Core/Animation/TranslateBy.cs
Normal file
7
Runtime/Core/Animation/TranslateBy.cs
Normal file
@ -0,0 +1,7 @@
|
||||
namespace AlicizaX.AnimationFlow.Runtime {
|
||||
public class TranslateBy : TranslateTo {
|
||||
public override void OnUpdate(float dt) {
|
||||
target.localPosition = Easing.Ease(easyType, enterValue, enterValue + to, elapsedTime / duration);
|
||||
}
|
||||
}
|
||||
}
|
11
Runtime/Core/Animation/TranslateBy.cs.meta
Normal file
11
Runtime/Core/Animation/TranslateBy.cs.meta
Normal file
@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: f7c3f97c4ace7b949b5474584965ebbc
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
73
Runtime/Core/Animation/TranslateTo.cs
Normal file
73
Runtime/Core/Animation/TranslateTo.cs
Normal file
@ -0,0 +1,73 @@
|
||||
using Sirenix.OdinInspector;
|
||||
using UnityEngine;
|
||||
|
||||
namespace AlicizaX.AnimationFlow.Runtime
|
||||
{
|
||||
[Category("Animation")]
|
||||
[System.Serializable]
|
||||
public class TranslateTo : ActionNode
|
||||
{
|
||||
[LabelText("持续时间")] public float duration = 1f;
|
||||
[LabelText("过渡类型")] public EaseType easyType;
|
||||
|
||||
[ChildGameObjectsOnly] [LabelText("对象")]
|
||||
public Transform target;
|
||||
|
||||
[LabelText("设置起点")] public bool setFrom;
|
||||
|
||||
[LabelText("开始")] [ShowIf("setFrom", true)]
|
||||
public Vector3 from;
|
||||
|
||||
[LabelText("结束")] public Vector3 to;
|
||||
|
||||
protected Vector3 orgValue;
|
||||
protected Vector3 enterValue;
|
||||
|
||||
public override void OnInit()
|
||||
{
|
||||
orgValue = target.localPosition;
|
||||
}
|
||||
|
||||
|
||||
public override void OnReset()
|
||||
{
|
||||
target.localPosition = orgValue;
|
||||
}
|
||||
|
||||
public override void OnEnter()
|
||||
{
|
||||
if (setFrom)
|
||||
{
|
||||
target.localPosition = from;
|
||||
}
|
||||
|
||||
enterValue = target.localPosition;
|
||||
}
|
||||
|
||||
public override void OnUpdate(float dt)
|
||||
{
|
||||
target.localPosition = Easing.Ease(easyType, enterValue, to, elapsedTime / duration);
|
||||
}
|
||||
|
||||
public override bool Valid()
|
||||
{
|
||||
Debug.Log(target != null && duration > 0);
|
||||
return target != null && duration > 0;
|
||||
}
|
||||
|
||||
public override float Duration()
|
||||
{
|
||||
return duration;
|
||||
}
|
||||
|
||||
public override bool HasSubTitle()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
public override string SubTitle()
|
||||
{
|
||||
return target != null ? target.name : null;
|
||||
}
|
||||
}
|
||||
}
|
11
Runtime/Core/Animation/TranslateTo.cs.meta
Normal file
11
Runtime/Core/Animation/TranslateTo.cs.meta
Normal file
@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 9f8df2f2b18ba1045acda62e9de6944e
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
247
Runtime/Core/Easing.cs
Normal file
247
Runtime/Core/Easing.cs
Normal file
@ -0,0 +1,247 @@
|
||||
using System;
|
||||
using UnityEngine;
|
||||
|
||||
namespace AlicizaX.AnimationFlow.Runtime {
|
||||
public enum EaseType {
|
||||
Linear,
|
||||
QuadraticIn,
|
||||
QuadraticOut,
|
||||
QuadraticInOut,
|
||||
QuarticIn,
|
||||
QuarticOut,
|
||||
QuarticInOut,
|
||||
QuinticIn,
|
||||
QuinticOut,
|
||||
QuinticInOut,
|
||||
CubicIn,
|
||||
CubicOut,
|
||||
CubicInOut,
|
||||
ExponentialIn,
|
||||
ExponentialOut,
|
||||
ExponentialInOut,
|
||||
CircularIn,
|
||||
CircularOut,
|
||||
CircularInOut,
|
||||
SinusoidalIn,
|
||||
SinusoidalOut,
|
||||
SinusoidalInOut,
|
||||
ElasticIn,
|
||||
ElasticOut,
|
||||
ElasticInOut,
|
||||
BounceIn,
|
||||
BounceOut,
|
||||
BounceInOut,
|
||||
BackIn,
|
||||
BackOut,
|
||||
BackInOut
|
||||
}
|
||||
|
||||
public static class Easing {
|
||||
public static float Ease(EaseType type, float from, float to, float t) {
|
||||
if (t <= 0) { return from; }
|
||||
if (t >= 1) { return to; }
|
||||
return Mathf.LerpUnclamped(from, to, Function(type)(t));
|
||||
}
|
||||
|
||||
public static Vector3 Ease(EaseType type, Vector3 from, Vector3 to, float t) {
|
||||
if (t <= 0) { return from; }
|
||||
if (t >= 1) { return to; }
|
||||
return Vector3.LerpUnclamped(from, to, Function(type)(t));
|
||||
}
|
||||
|
||||
public static Quaternion Ease(EaseType type, Quaternion from, Quaternion to, float t) {
|
||||
if (t <= 0) { return from; }
|
||||
if (t >= 1) { return to; }
|
||||
return Quaternion.LerpUnclamped(from, to, Function(type)(t));
|
||||
}
|
||||
|
||||
public static Color Ease(EaseType type, Color from, Color to, float t) {
|
||||
if (t <= 0) { return from; }
|
||||
if (t >= 1) { return to; }
|
||||
return Color.LerpUnclamped(from, to, Function(type)(t));
|
||||
}
|
||||
|
||||
public static Func<float, float> Function(EaseType type) {
|
||||
return type switch {
|
||||
EaseType.Linear => Linear,
|
||||
EaseType.QuadraticIn => QuadraticIn,
|
||||
EaseType.QuadraticOut => QuadraticOut,
|
||||
EaseType.QuadraticInOut => QuadraticInOut,
|
||||
EaseType.QuarticIn => QuarticIn,
|
||||
EaseType.QuarticOut => QuarticOut,
|
||||
EaseType.QuarticInOut => QuarticInOut,
|
||||
EaseType.QuinticIn => QuinticIn,
|
||||
EaseType.QuinticOut => QuinticOut,
|
||||
EaseType.QuinticInOut => QuinticInOut,
|
||||
EaseType.CubicIn => CubicIn,
|
||||
EaseType.CubicOut => CubicOut,
|
||||
EaseType.CubicInOut => CubicInOut,
|
||||
EaseType.ExponentialIn => ExponentialIn,
|
||||
EaseType.ExponentialOut => ExponentialOut,
|
||||
EaseType.ExponentialInOut => ExponentialInOut,
|
||||
EaseType.CircularIn => CircularIn,
|
||||
EaseType.CircularOut => CircularOut,
|
||||
EaseType.CircularInOut => CircularInOut,
|
||||
EaseType.SinusoidalIn => SinusoidalIn,
|
||||
EaseType.SinusoidalOut => SinusoidalOut,
|
||||
EaseType.SinusoidalInOut => SinusoidalInOut,
|
||||
EaseType.ElasticIn => ElasticIn,
|
||||
EaseType.ElasticOut => ElasticOut,
|
||||
EaseType.ElasticInOut => ElasticInOut,
|
||||
EaseType.BounceIn => BounceIn,
|
||||
EaseType.BounceOut => BounceOut,
|
||||
EaseType.BounceInOut => BounceInOut,
|
||||
EaseType.BackIn => BackIn,
|
||||
EaseType.BackOut => BackOut,
|
||||
EaseType.BackInOut => BackInOut,
|
||||
_ => throw new ArgumentOutOfRangeException(),
|
||||
};
|
||||
}
|
||||
|
||||
public static float Linear(float t) {
|
||||
return t;
|
||||
}
|
||||
|
||||
public static float QuadraticIn(float t) {
|
||||
return t * t;
|
||||
}
|
||||
|
||||
public static float QuadraticOut(float t) {
|
||||
return 1f - (1f - t) * (1f - t);
|
||||
}
|
||||
|
||||
public static float QuadraticInOut(float t) {
|
||||
return t < 0.5f ? 2f * t * t : 1f - Mathf.Pow(-2f * t + 2f, 2f) / 2f;
|
||||
}
|
||||
|
||||
public static float QuarticIn(float t) {
|
||||
return t * t * t * t;
|
||||
}
|
||||
|
||||
public static float QuarticOut(float t) {
|
||||
return 1f - (--t * t * t * t);
|
||||
}
|
||||
|
||||
public static float QuarticInOut(float t) {
|
||||
if ((t *= 2f) < 1f)
|
||||
return 0.5f * t * t * t * t;
|
||||
return -0.5f * ((t -= 2f) * t * t * t - 2f);
|
||||
}
|
||||
|
||||
public static float QuinticIn(float t) {
|
||||
return t * t * t * t * t;
|
||||
}
|
||||
|
||||
public static float QuinticOut(float t) {
|
||||
return --t * t * t * t * t + 1f;
|
||||
}
|
||||
|
||||
public static float QuinticInOut(float t) {
|
||||
if ((t *= 2f) < 1)
|
||||
return 0.5f * t * t * t * t * t;
|
||||
return 0.5f * ((t -= 2f) * t * t * t * t + 2f);
|
||||
}
|
||||
|
||||
public static float CubicIn(float t) {
|
||||
return t * t * t;
|
||||
}
|
||||
|
||||
public static float CubicOut(float t) {
|
||||
return --t * t * t + 1f;
|
||||
}
|
||||
|
||||
public static float CubicInOut(float t) {
|
||||
return t < 0.5 ? 4f * t * t * t : 1f - Mathf.Pow(-2f * t + 2f, 3f) / 2f;
|
||||
}
|
||||
|
||||
public static float SinusoidalIn(float t) {
|
||||
return 1f - Mathf.Cos(t * Mathf.PI / 2f);
|
||||
}
|
||||
|
||||
public static float SinusoidalOut(float t) {
|
||||
return Mathf.Sin(t * Mathf.PI / 2f);
|
||||
}
|
||||
|
||||
public static float SinusoidalInOut(float t) {
|
||||
return 0.5f * (1f - Mathf.Cos(Mathf.PI * t));
|
||||
}
|
||||
|
||||
public static float ExponentialIn(float t) {
|
||||
return t == 0f ? 0f : Mathf.Pow(2f, 10f * t - 10f);
|
||||
}
|
||||
|
||||
public static float ExponentialOut(float t) {
|
||||
return t == 1f ? 1f : 1f - Mathf.Pow(2f, -10f * t);
|
||||
}
|
||||
|
||||
public static float ExponentialInOut(float t) {
|
||||
return t < 0.5f ? Mathf.Pow(2f, 20f * t - 10f) / 2f : (2f - Mathf.Pow(2f, -20f * t + 10f)) / 2f;
|
||||
}
|
||||
|
||||
public static float CircularIn(float t) {
|
||||
return 1f - Mathf.Sqrt(1f - t * t);
|
||||
}
|
||||
|
||||
public static float CircularOut(float t) {
|
||||
return Mathf.Sqrt(1f - (--t * t));
|
||||
}
|
||||
|
||||
public static float CircularInOut(float t) {
|
||||
return t < 0.5f ? (Mathf.Sqrt(1f - t * t) - 1f) / 2 : (Mathf.Sqrt(1f - (t -= 2f) * t) + 1f) / 2;
|
||||
}
|
||||
|
||||
public static float ElasticIn(float t) {
|
||||
float x = (2f * Mathf.PI) / 3f;
|
||||
return -Mathf.Pow(2f, 10f * t - 10f) * Mathf.Sin((t * 10f - 10.75f) * x);
|
||||
}
|
||||
|
||||
public static float ElasticOut(float t) {
|
||||
float x = (2f * Mathf.PI) / 3f;
|
||||
return Mathf.Pow(2f, -10f * t) * Mathf.Sin((t * 10f - 0.75f) * x) + 1f;
|
||||
}
|
||||
|
||||
public static float ElasticInOut(float t) {
|
||||
float x = (2f * Mathf.PI) / 4.5f;
|
||||
if (t < 0.5f)
|
||||
return -(Mathf.Pow(2f, 20f * t - 10f) * Mathf.Sin((20f * t - 11.125f) * x)) / 2f;
|
||||
return (Mathf.Pow(2f, -20f * t + 10f) * Mathf.Sin((20f * t - 11.125f) * x)) / 2f + 1f;
|
||||
}
|
||||
|
||||
public static float BounceIn(float t) {
|
||||
return 1f - BounceOut(1f - t);
|
||||
}
|
||||
|
||||
public static float BounceOut(float t) {
|
||||
if (t < (1f / 2.75f)) {
|
||||
return 7.5625f * t * t;
|
||||
} else if (t < (2f / 2.75f)) {
|
||||
return 7.5625f * (t -= (1.5f / 2.75f)) * t + 0.75f;
|
||||
} else if (t < (2.5f / 2.75f)) {
|
||||
return 7.5625f * (t -= (2.25f / 2.75f)) * t + 0.9375f;
|
||||
} else {
|
||||
return 7.5625f * (t -= (2.625f / 2.75f)) * t + 0.984375f;
|
||||
}
|
||||
}
|
||||
|
||||
public static float BounceInOut(float t) {
|
||||
return t < 0.5f ? BounceIn(t * 2f) * 0.5f : BounceOut(t * 2f - 1f) * 0.5f + 0.5f;
|
||||
}
|
||||
|
||||
public static float BackIn(float t) {
|
||||
float s = 1.70158f;
|
||||
return t * t * ((s + 1f) * t - s);
|
||||
}
|
||||
|
||||
public static float BackOut(float t) {
|
||||
float s = 1.70158f;
|
||||
return --t * t * ((s + 1f) * t + s) + 1f;
|
||||
}
|
||||
|
||||
public static float BackInOut(float t) {
|
||||
float s = 1.70158f * 1.525f;
|
||||
if ((t *= 2f) < 1f)
|
||||
return 0.5f * (t * t * ((s + 1) * t - s));
|
||||
return 0.5f * ((t -= 2f) * t * ((s + 1f) * t + s) + 2f);
|
||||
}
|
||||
}
|
||||
}
|
11
Runtime/Core/Easing.cs.meta
Normal file
11
Runtime/Core/Easing.cs.meta
Normal file
@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 89bfa9261b873cf4aba9ca58ccb40156
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
8
Runtime/Core/Event.meta
Normal file
8
Runtime/Core/Event.meta
Normal file
@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 2410b6af4b749be48adc490e6c1f24a3
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
12
Runtime/Core/Event/UnityEventNode.cs
Normal file
12
Runtime/Core/Event/UnityEventNode.cs
Normal file
@ -0,0 +1,12 @@
|
||||
using UnityEngine.Events;
|
||||
|
||||
namespace AlicizaX.AnimationFlow.Runtime {
|
||||
[Category("Event"), Name("UnityEvent")]
|
||||
public class UnityEventNode : ActionNode {
|
||||
public UnityEvent unityEvent;
|
||||
|
||||
public override void OnEnter() {
|
||||
unityEvent?.Invoke();
|
||||
}
|
||||
}
|
||||
}
|
11
Runtime/Core/Event/UnityEventNode.cs.meta
Normal file
11
Runtime/Core/Event/UnityEventNode.cs.meta
Normal file
@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 8fd856bb9f217e04c8f200ff54477a9b
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
3
Runtime/Core/Node.meta
Normal file
3
Runtime/Core/Node.meta
Normal file
@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 2bd5293bdf6fd52439390bafec491b0e
|
||||
timeCreated: 1731292591
|
141
Runtime/Core/Node/ActionNode.cs
Normal file
141
Runtime/Core/Node/ActionNode.cs
Normal file
@ -0,0 +1,141 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Numerics;
|
||||
using Sirenix.OdinInspector;
|
||||
using UnityEngine;
|
||||
|
||||
namespace AlicizaX.AnimationFlow.Runtime
|
||||
{
|
||||
public enum EState
|
||||
{
|
||||
None,
|
||||
Enter,
|
||||
Running,
|
||||
Exit,
|
||||
}
|
||||
|
||||
|
||||
[System.Serializable]
|
||||
public class EntryNode : ActionNode
|
||||
{
|
||||
[LabelText("循环次数")] public int LoopCount = 1; // 控制流程循环的次数
|
||||
[LabelText("入口名称")] public string Name; // 节点名称(可以是技能名称、关卡名称等)
|
||||
}
|
||||
|
||||
[System.Serializable]
|
||||
public abstract partial class ActionNode
|
||||
{
|
||||
[HideInInspector] public float elapsedTime;
|
||||
|
||||
[HideInInspector] [SerializeReference] [SerializeField]
|
||||
public List<ActionNode> Childs = new List<ActionNode>(); // 邻接节点(图中的边)
|
||||
|
||||
[HideInInspector] public EState State;
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 该类型是否允许接受输入口
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public virtual bool HasInputPort()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 是否有多输入口
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public virtual bool MultiInputPort()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 是否有输出口
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public virtual bool HasOutPort()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 是否有多输出口
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public virtual bool MultiOutPort()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 持续时间
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public virtual float Duration()
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 前置条件 如果满足 则进入下一分支
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public virtual bool Condition()
|
||||
{
|
||||
return elapsedTime >= Duration();
|
||||
}
|
||||
|
||||
public virtual bool HasSubTitle()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
public virtual string SubTitle()
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 效验通过 编辑器使用
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public virtual bool Valid()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
public virtual void OnInit()
|
||||
{
|
||||
}
|
||||
|
||||
public virtual void OnEnter()
|
||||
{
|
||||
}
|
||||
|
||||
public virtual void OnExit()
|
||||
{
|
||||
}
|
||||
|
||||
public virtual void OnUpdate(float dt)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
public virtual void OnInterrupt()
|
||||
{
|
||||
}
|
||||
|
||||
public virtual void OnReset()
|
||||
{
|
||||
}
|
||||
|
||||
public void Reset()
|
||||
{
|
||||
elapsedTime = 0;
|
||||
State = EState.None;
|
||||
}
|
||||
}
|
||||
}
|
3
Runtime/Core/Node/ActionNode.cs.meta
Normal file
3
Runtime/Core/Node/ActionNode.cs.meta
Normal file
@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 1329507424583a6498dd62a900edaf76
|
||||
timeCreated: 1731065028
|
17
Runtime/Core/Node/Editor_ActionNode.cs
Normal file
17
Runtime/Core/Node/Editor_ActionNode.cs
Normal file
@ -0,0 +1,17 @@
|
||||
|
||||
|
||||
using UnityEngine;
|
||||
|
||||
namespace AlicizaX.AnimationFlow.Runtime
|
||||
{
|
||||
#if UNITY_EDITOR
|
||||
public abstract partial class ActionNode
|
||||
{
|
||||
[HideInInspector]
|
||||
public Vector2 nodePos; //GraphView使用
|
||||
[HideInInspector]
|
||||
public string uuid; //GraphView映射的Id
|
||||
}
|
||||
|
||||
#endif
|
||||
}
|
3
Runtime/Core/Node/Editor_ActionNode.cs.meta
Normal file
3
Runtime/Core/Node/Editor_ActionNode.cs.meta
Normal file
@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: b3a49f0f1e2c1e942a472ab2d6574c10
|
||||
timeCreated: 1731292612
|
8
Runtime/Core/Property.meta
Normal file
8
Runtime/Core/Property.meta
Normal file
@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 1be47789456052f48b22caa8b33648f0
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
35
Runtime/Core/Property/ButtonInteractable.cs
Normal file
35
Runtime/Core/Property/ButtonInteractable.cs
Normal file
@ -0,0 +1,35 @@
|
||||
using UnityEngine;
|
||||
using UnityEngine.UI;
|
||||
|
||||
namespace AlicizaX.AnimationFlow.Runtime {
|
||||
[Category("Property")]
|
||||
public class ButtonInteractable : ActionNode {
|
||||
public Button target;
|
||||
public bool interactable;
|
||||
protected bool orgValue;
|
||||
|
||||
public override void OnInit() {
|
||||
orgValue = target.interactable;
|
||||
}
|
||||
|
||||
public override void OnReset() {
|
||||
target.interactable = orgValue;
|
||||
}
|
||||
|
||||
public override void OnEnter() {
|
||||
target.interactable = interactable;
|
||||
}
|
||||
|
||||
public override bool Valid() {
|
||||
return target != null;
|
||||
}
|
||||
|
||||
public override bool HasSubTitle() {
|
||||
return true;
|
||||
}
|
||||
|
||||
public override string SubTitle() {
|
||||
return target != null ? target.name : null;
|
||||
}
|
||||
}
|
||||
}
|
11
Runtime/Core/Property/ButtonInteractable.cs.meta
Normal file
11
Runtime/Core/Property/ButtonInteractable.cs.meta
Normal file
@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 8c130e3aa2d1ba24f8efb203c21341ca
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
59
Runtime/Core/Property/CanvasGroupProperty.cs
Normal file
59
Runtime/Core/Property/CanvasGroupProperty.cs
Normal file
@ -0,0 +1,59 @@
|
||||
using UnityEngine;
|
||||
|
||||
namespace AlicizaX.AnimationFlow.Runtime {
|
||||
[Category("Property"), Name("CanvasGroup")]
|
||||
public class CanvasGroupProperty : ActionNode {
|
||||
public CanvasGroup target;
|
||||
public bool setAlpha = true;
|
||||
public float alpha;
|
||||
public bool setInteractable;
|
||||
public bool interactable;
|
||||
public bool setBlocksRaycasts;
|
||||
public bool blocksRaycasts;
|
||||
private float orgAlpha;
|
||||
private bool orgInteractable;
|
||||
private bool orgBlocksRaycasts;
|
||||
|
||||
public override void OnInit() {
|
||||
orgAlpha = target.alpha;
|
||||
orgInteractable = target.interactable;
|
||||
orgBlocksRaycasts = target.blocksRaycasts;
|
||||
}
|
||||
|
||||
public override void OnReset() {
|
||||
if (setAlpha) {
|
||||
target.alpha = orgAlpha;
|
||||
}
|
||||
if (setInteractable) {
|
||||
target.interactable = orgInteractable;
|
||||
}
|
||||
if (setBlocksRaycasts) {
|
||||
target.blocksRaycasts = orgBlocksRaycasts;
|
||||
}
|
||||
}
|
||||
|
||||
public override void OnEnter() {
|
||||
if (setAlpha) {
|
||||
target.alpha = alpha;
|
||||
}
|
||||
if (setInteractable) {
|
||||
target.interactable = interactable;
|
||||
}
|
||||
if (setBlocksRaycasts) {
|
||||
target.blocksRaycasts = blocksRaycasts;
|
||||
}
|
||||
}
|
||||
|
||||
public override bool Valid() {
|
||||
return target != null;
|
||||
}
|
||||
|
||||
public override bool HasSubTitle() {
|
||||
return true;
|
||||
}
|
||||
|
||||
public override string SubTitle() {
|
||||
return target != null ? target.name : null;
|
||||
}
|
||||
}
|
||||
}
|
11
Runtime/Core/Property/CanvasGroupProperty.cs.meta
Normal file
11
Runtime/Core/Property/CanvasGroupProperty.cs.meta
Normal file
@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 4faaec8fb78ccc548a66ab12ef17783f
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
34
Runtime/Core/Property/GameObjectActive.cs
Normal file
34
Runtime/Core/Property/GameObjectActive.cs
Normal file
@ -0,0 +1,34 @@
|
||||
using UnityEngine;
|
||||
|
||||
namespace AlicizaX.AnimationFlow.Runtime {
|
||||
[Category("Property")]
|
||||
public class GameObjectActive : ActionNode {
|
||||
public GameObject target;
|
||||
public bool active;
|
||||
protected bool orgValue;
|
||||
|
||||
public override void OnInit() {
|
||||
orgValue = target.activeSelf;
|
||||
}
|
||||
|
||||
public override void OnReset() {
|
||||
target.SetActive(orgValue);
|
||||
}
|
||||
|
||||
public override void OnEnter() {
|
||||
target.SetActive(active);
|
||||
}
|
||||
|
||||
public override bool Valid() {
|
||||
return target != null;
|
||||
}
|
||||
|
||||
public override bool HasSubTitle() {
|
||||
return true;
|
||||
}
|
||||
|
||||
public override string SubTitle() {
|
||||
return target != null ? target.name : null;
|
||||
}
|
||||
}
|
||||
}
|
11
Runtime/Core/Property/GameObjectActive.cs.meta
Normal file
11
Runtime/Core/Property/GameObjectActive.cs.meta
Normal file
@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: d42bfaaa1c095e048918365a2f3961cb
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
36
Runtime/Core/Property/GraphicAlpha.cs
Normal file
36
Runtime/Core/Property/GraphicAlpha.cs
Normal file
@ -0,0 +1,36 @@
|
||||
using UnityEngine;
|
||||
using UnityEngine.UI;
|
||||
|
||||
namespace AlicizaX.AnimationFlow.Runtime {
|
||||
[Category("Property")]
|
||||
public class GraphicAlpha : ActionNode {
|
||||
public Graphic target;
|
||||
public float alpha;
|
||||
|
||||
protected float orgValue;
|
||||
|
||||
public override void OnInit() {
|
||||
orgValue = target.color.a;
|
||||
}
|
||||
|
||||
public override void OnReset() {
|
||||
target.color = new Color(target.color.r, target.color.g, target.color.b, orgValue);
|
||||
}
|
||||
|
||||
public override void OnEnter() {
|
||||
target.color = new Color(target.color.r, target.color.g, target.color.b, alpha);
|
||||
}
|
||||
|
||||
public override bool Valid() {
|
||||
return target != null;
|
||||
}
|
||||
|
||||
public override bool HasSubTitle() {
|
||||
return true;
|
||||
}
|
||||
|
||||
public override string SubTitle() {
|
||||
return target != null ? target.name : null;
|
||||
}
|
||||
}
|
||||
}
|
11
Runtime/Core/Property/GraphicAlpha.cs.meta
Normal file
11
Runtime/Core/Property/GraphicAlpha.cs.meta
Normal file
@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 26999d2beaeb18045ad1f3876b739644
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
37
Runtime/Core/Property/GraphicColor.cs
Normal file
37
Runtime/Core/Property/GraphicColor.cs
Normal file
@ -0,0 +1,37 @@
|
||||
using UnityEngine;
|
||||
using UnityEngine.UI;
|
||||
|
||||
namespace AlicizaX.AnimationFlow.Runtime {
|
||||
[Category("Property")]
|
||||
public class GraphicColor : ActionNode {
|
||||
public Graphic target;
|
||||
public Color color = Color.white;
|
||||
|
||||
protected Color orgValue;
|
||||
|
||||
public override void OnInit() {
|
||||
orgValue = target.color;
|
||||
}
|
||||
|
||||
|
||||
public override void OnReset() {
|
||||
target.color = orgValue;
|
||||
}
|
||||
|
||||
public override void OnEnter() {
|
||||
target.color = color;
|
||||
}
|
||||
|
||||
public override bool Valid() {
|
||||
return target != null;
|
||||
}
|
||||
|
||||
public override bool HasSubTitle() {
|
||||
return true;
|
||||
}
|
||||
|
||||
public override string SubTitle() {
|
||||
return target != null ? target.name : null;
|
||||
}
|
||||
}
|
||||
}
|
11
Runtime/Core/Property/GraphicColor.cs.meta
Normal file
11
Runtime/Core/Property/GraphicColor.cs.meta
Normal file
@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 1ced79fffdfa1e94b80381771318ee16
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
37
Runtime/Core/Property/ImageSprite.cs
Normal file
37
Runtime/Core/Property/ImageSprite.cs
Normal file
@ -0,0 +1,37 @@
|
||||
using UnityEngine;
|
||||
using UnityEngine.UI;
|
||||
|
||||
namespace AlicizaX.AnimationFlow.Runtime {
|
||||
[Category("Property")]
|
||||
public class ImageSprite : ActionNode {
|
||||
public Image target;
|
||||
public Sprite sprite;
|
||||
|
||||
protected Sprite orgValue;
|
||||
|
||||
public override void OnInit() {
|
||||
orgValue = target.sprite;
|
||||
}
|
||||
|
||||
|
||||
public override void OnReset() {
|
||||
target.sprite = orgValue;
|
||||
}
|
||||
|
||||
public override void OnEnter() {
|
||||
target.sprite = sprite;
|
||||
}
|
||||
|
||||
public override bool Valid() {
|
||||
return target != null;
|
||||
}
|
||||
|
||||
public override bool HasSubTitle() {
|
||||
return true;
|
||||
}
|
||||
|
||||
public override string SubTitle() {
|
||||
return target != null ? target.name : null;
|
||||
}
|
||||
}
|
||||
}
|
11
Runtime/Core/Property/ImageSprite.cs.meta
Normal file
11
Runtime/Core/Property/ImageSprite.cs.meta
Normal file
@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: b2383f65101b8be4db8b58ae723f96aa
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
35
Runtime/Core/Property/SiblingIndex.cs
Normal file
35
Runtime/Core/Property/SiblingIndex.cs
Normal file
@ -0,0 +1,35 @@
|
||||
using UnityEngine;
|
||||
|
||||
namespace AlicizaX.AnimationFlow.Runtime {
|
||||
[Category("Property")]
|
||||
public class SiblingIndex : ActionNode {
|
||||
public Transform target;
|
||||
public int index;
|
||||
|
||||
protected int orgIndex;
|
||||
|
||||
public override void OnInit() {
|
||||
orgIndex = target.GetSiblingIndex();
|
||||
}
|
||||
|
||||
public override void OnReset() {
|
||||
target.SetSiblingIndex(orgIndex);
|
||||
}
|
||||
|
||||
public override void OnEnter() {
|
||||
target.SetSiblingIndex(index);
|
||||
}
|
||||
|
||||
public override bool Valid() {
|
||||
return target != null;
|
||||
}
|
||||
|
||||
public override bool HasSubTitle() {
|
||||
return true;
|
||||
}
|
||||
|
||||
public override string SubTitle() {
|
||||
return target != null ? target.name : null;
|
||||
}
|
||||
}
|
||||
}
|
11
Runtime/Core/Property/SiblingIndex.cs.meta
Normal file
11
Runtime/Core/Property/SiblingIndex.cs.meta
Normal file
@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: c3810a3c63fa8e64d8b1506ef2c5bdd3
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
60
Runtime/Core/Property/SpriteRendererProperty.cs
Normal file
60
Runtime/Core/Property/SpriteRendererProperty.cs
Normal file
@ -0,0 +1,60 @@
|
||||
using UnityEngine;
|
||||
|
||||
namespace AlicizaX.AnimationFlow.Runtime {
|
||||
[Category("Property")]
|
||||
public class SpriteRendererProperty : ActionNode {
|
||||
public SpriteRenderer target;
|
||||
public bool setSprite = true;
|
||||
public Sprite sprite;
|
||||
public bool setColor;
|
||||
public Color color;
|
||||
public bool setLayer;
|
||||
public int layer;
|
||||
|
||||
protected Sprite orgSprite;
|
||||
protected Color orgColor;
|
||||
protected int orgLayer;
|
||||
|
||||
public override void OnInit() {
|
||||
orgSprite = target.sprite;
|
||||
orgColor = target.color;
|
||||
orgLayer = target.sortingLayerID;
|
||||
}
|
||||
|
||||
public override void OnReset() {
|
||||
if (setSprite) {
|
||||
target.sprite = orgSprite;
|
||||
}
|
||||
if (setColor) {
|
||||
target.color = orgColor;
|
||||
}
|
||||
if (setLayer) {
|
||||
target.sortingLayerID = orgLayer;
|
||||
}
|
||||
}
|
||||
|
||||
public override void OnEnter() {
|
||||
if (setSprite) {
|
||||
target.sprite = sprite;
|
||||
}
|
||||
if (setColor) {
|
||||
target.color = color;
|
||||
}
|
||||
if (setLayer) {
|
||||
target.sortingLayerID = layer;
|
||||
}
|
||||
}
|
||||
|
||||
public override bool Valid() {
|
||||
return target != null;
|
||||
}
|
||||
|
||||
public override bool HasSubTitle() {
|
||||
return true;
|
||||
}
|
||||
|
||||
public override string SubTitle() {
|
||||
return target != null ? target.name : null;
|
||||
}
|
||||
}
|
||||
}
|
11
Runtime/Core/Property/SpriteRendererProperty.cs.meta
Normal file
11
Runtime/Core/Property/SpriteRendererProperty.cs.meta
Normal file
@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 73e269ad4e3d1fb4d8f7ed4a84d09d9a
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
59
Runtime/Core/Property/TransformProperty.cs
Normal file
59
Runtime/Core/Property/TransformProperty.cs
Normal file
@ -0,0 +1,59 @@
|
||||
using UnityEngine;
|
||||
|
||||
namespace AlicizaX.AnimationFlow.Runtime {
|
||||
[Category("Property"), Name("Transform")]
|
||||
public class TransformProperty : ActionNode {
|
||||
public Transform target;
|
||||
public bool setPosition = true;
|
||||
public Vector3 position;
|
||||
public bool setScale;
|
||||
public Vector3 scale;
|
||||
public bool setRotation;
|
||||
public Vector3 rotation;
|
||||
private Vector3 orgPosition;
|
||||
private Vector3 orgScale;
|
||||
private Vector3 orgRotation;
|
||||
|
||||
public override void OnInit() {
|
||||
orgPosition = target.localPosition;
|
||||
orgScale = target.localScale;
|
||||
orgRotation = target.eulerAngles;
|
||||
}
|
||||
|
||||
public override void OnReset() {
|
||||
if (setPosition) {
|
||||
target.localPosition = orgPosition;
|
||||
}
|
||||
if (setScale) {
|
||||
target.localScale = orgScale;
|
||||
}
|
||||
if (setRotation) {
|
||||
target.eulerAngles = orgRotation;
|
||||
}
|
||||
}
|
||||
|
||||
public override void OnEnter() {
|
||||
if (setPosition) {
|
||||
target.localPosition = position;
|
||||
}
|
||||
if (setScale) {
|
||||
target.localScale = scale;
|
||||
}
|
||||
if (setRotation) {
|
||||
target.eulerAngles = rotation;
|
||||
}
|
||||
}
|
||||
|
||||
public override bool Valid() {
|
||||
return target != null;
|
||||
}
|
||||
|
||||
public override bool HasSubTitle() {
|
||||
return true;
|
||||
}
|
||||
|
||||
public override string SubTitle() {
|
||||
return target != null ? target.name : null;
|
||||
}
|
||||
}
|
||||
}
|
11
Runtime/Core/Property/TransformProperty.cs.meta
Normal file
11
Runtime/Core/Property/TransformProperty.cs.meta
Normal file
@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 96fe9eab07c128340890e3acf79a9ca7
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user