test
This commit is contained in:
@@ -0,0 +1,43 @@
|
||||
namespace Unity.VisualScripting
|
||||
{
|
||||
/// <summary>
|
||||
/// A special state that can trigger transitions to other states,
|
||||
/// no matter which state is currently active. This state cannot receive
|
||||
/// transitions.
|
||||
/// </summary>
|
||||
public sealed class AnyState : State
|
||||
{
|
||||
[DoNotSerialize]
|
||||
public override bool canBeDestination => false;
|
||||
|
||||
public AnyState() : base()
|
||||
{
|
||||
isStart = true;
|
||||
}
|
||||
|
||||
public override void OnExit(Flow flow, StateExitReason reason)
|
||||
{
|
||||
// Don't exit this state from branching.
|
||||
if (reason == StateExitReason.Branch)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
base.OnExit(flow, reason);
|
||||
}
|
||||
|
||||
public override void OnBranchTo(Flow flow, IState destination)
|
||||
{
|
||||
// Before entering the destination destination state,
|
||||
// exit all other connected states.
|
||||
|
||||
foreach (var outgoingTransition in outgoingTransitionsNoAlloc)
|
||||
{
|
||||
if (outgoingTransition.destination != destination)
|
||||
{
|
||||
outgoingTransition.destination.OnExit(flow, StateExitReason.AnyBranch);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 713158a56b1f044b988caf50dd09eedf
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@@ -0,0 +1,94 @@
|
||||
using System.ComponentModel;
|
||||
using UnityEngine;
|
||||
|
||||
namespace Unity.VisualScripting
|
||||
{
|
||||
[SerializationVersion("A")]
|
||||
[TypeIcon(typeof(FlowGraph))]
|
||||
[DisplayName("Script State")]
|
||||
public sealed class FlowState : NesterState<FlowGraph, ScriptGraphAsset>, IGraphEventListener
|
||||
{
|
||||
public FlowState() { }
|
||||
|
||||
public FlowState(ScriptGraphAsset macro) : base(macro) { }
|
||||
|
||||
|
||||
#region Lifecycle
|
||||
|
||||
protected override void OnEnterImplementation(Flow flow)
|
||||
{
|
||||
if (flow.stack.TryEnterParentElement(this))
|
||||
{
|
||||
nest.graph.StartListening(flow.stack);
|
||||
flow.stack.TriggerEventHandler(hook => hook == StateEventHooks.OnEnterState, new EmptyEventArgs(), parent => parent is SubgraphUnit, false);
|
||||
flow.stack.ExitParentElement();
|
||||
}
|
||||
}
|
||||
|
||||
protected override void OnExitImplementation(Flow flow)
|
||||
{
|
||||
if (flow.stack.TryEnterParentElement(this))
|
||||
{
|
||||
flow.stack.TriggerEventHandler(hook => hook == StateEventHooks.OnExitState, new EmptyEventArgs(), parent => parent is SubgraphUnit, false);
|
||||
nest.graph.StopListening(flow.stack);
|
||||
flow.stack.ExitParentElement();
|
||||
}
|
||||
}
|
||||
|
||||
public void StartListening(GraphStack stack)
|
||||
{
|
||||
if (stack.TryEnterParentElement(this))
|
||||
{
|
||||
nest.graph.StartListening(stack);
|
||||
stack.ExitParentElement();
|
||||
}
|
||||
}
|
||||
|
||||
public void StopListening(GraphStack stack)
|
||||
{
|
||||
if (stack.TryEnterParentElement(this))
|
||||
{
|
||||
nest.graph.StopListening(stack);
|
||||
stack.ExitParentElement();
|
||||
}
|
||||
}
|
||||
|
||||
public bool IsListening(GraphPointer pointer)
|
||||
{
|
||||
return pointer.GetElementData<Data>(this).isActive;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
|
||||
#region Factory
|
||||
|
||||
public override FlowGraph DefaultGraph()
|
||||
{
|
||||
return GraphWithEnterUpdateExit();
|
||||
}
|
||||
|
||||
public static FlowState WithEnterUpdateExit()
|
||||
{
|
||||
var flowState = new FlowState();
|
||||
flowState.nest.source = GraphSource.Embed;
|
||||
flowState.nest.embed = GraphWithEnterUpdateExit();
|
||||
return flowState;
|
||||
}
|
||||
|
||||
public static FlowGraph GraphWithEnterUpdateExit()
|
||||
{
|
||||
return new FlowGraph
|
||||
{
|
||||
units =
|
||||
{
|
||||
new OnEnterState { position = new Vector2(-205, -215) },
|
||||
new Update { position = new Vector2(-161, -38) },
|
||||
new OnExitState { position = new Vector2(-205, 145) }
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 36f9aad66340e42e98a0d64fb043351f
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@@ -0,0 +1,95 @@
|
||||
using System;
|
||||
using UnityEngine;
|
||||
|
||||
namespace Unity.VisualScripting
|
||||
{
|
||||
[SerializationVersion("A")]
|
||||
public sealed class FlowStateTransition : NesterStateTransition<FlowGraph, ScriptGraphAsset>, IGraphEventListener
|
||||
{
|
||||
public FlowStateTransition() : base() { }
|
||||
|
||||
public FlowStateTransition(IState source, IState destination) : base(source, destination)
|
||||
{
|
||||
if (!source.canBeSource)
|
||||
{
|
||||
throw new InvalidOperationException("Source state cannot emit transitions.");
|
||||
}
|
||||
|
||||
if (!destination.canBeDestination)
|
||||
{
|
||||
throw new InvalidOperationException("Destination state cannot receive transitions.");
|
||||
}
|
||||
}
|
||||
|
||||
public static FlowStateTransition WithDefaultTrigger(IState source, IState destination)
|
||||
{
|
||||
var flowStateTransition = new FlowStateTransition(source, destination);
|
||||
flowStateTransition.nest.source = GraphSource.Embed;
|
||||
flowStateTransition.nest.embed = GraphWithDefaultTrigger();
|
||||
return flowStateTransition;
|
||||
}
|
||||
|
||||
public static FlowGraph GraphWithDefaultTrigger()
|
||||
{
|
||||
return new FlowGraph()
|
||||
{
|
||||
units =
|
||||
{
|
||||
new TriggerStateTransition() { position = new Vector2(100, -50) }
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
#region Lifecycle
|
||||
|
||||
public override void OnEnter(Flow flow)
|
||||
{
|
||||
if (flow.stack.TryEnterParentElement(this))
|
||||
{
|
||||
flow.stack.TriggerEventHandler(hook => hook == StateEventHooks.OnEnterState, new EmptyEventArgs(), parent => parent is SubgraphUnit, false);
|
||||
flow.stack.ExitParentElement();
|
||||
}
|
||||
}
|
||||
|
||||
public override void OnExit(Flow flow)
|
||||
{
|
||||
if (flow.stack.TryEnterParentElement(this))
|
||||
{
|
||||
flow.stack.TriggerEventHandler(hook => hook == StateEventHooks.OnExitState, new EmptyEventArgs(), parent => parent is SubgraphUnit, false);
|
||||
nest.graph.StopListening(flow.stack);
|
||||
flow.stack.ExitParentElement();
|
||||
}
|
||||
}
|
||||
|
||||
public void StartListening(GraphStack stack)
|
||||
{
|
||||
if (stack.TryEnterParentElement(this))
|
||||
{
|
||||
nest.graph.StartListening(stack);
|
||||
stack.ExitParentElement();
|
||||
}
|
||||
}
|
||||
|
||||
public void StopListening(GraphStack stack)
|
||||
{
|
||||
if (stack.TryEnterParentElement(this))
|
||||
{
|
||||
nest.graph.StopListening(stack);
|
||||
stack.ExitParentElement();
|
||||
}
|
||||
}
|
||||
|
||||
public bool IsListening(GraphPointer pointer)
|
||||
{
|
||||
return pointer.GetElementData<State.Data>(source).isActive;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
|
||||
public override FlowGraph DefaultGraph()
|
||||
{
|
||||
return GraphWithDefaultTrigger();
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 0bd6d62c34b19457e82fc142fc1a6093
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: e7f4f3642c70f4650b86c2d023e47c3b
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 80d5cd46de8ca404692849f4a46c2306
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@@ -0,0 +1,22 @@
|
||||
using System;
|
||||
using JetBrains.Annotations;
|
||||
using UnityEngine;
|
||||
|
||||
namespace Unity.VisualScripting
|
||||
{
|
||||
/// <summary>
|
||||
/// Check if a GameObject or StateMachine has a StateGraph
|
||||
/// </summary>
|
||||
[TypeIcon(typeof(StateGraph))]
|
||||
[UnitCategory("Graphs/Graph Nodes")]
|
||||
public sealed class HasStateGraph : HasGraph<StateGraph, StateGraphAsset, StateMachine>
|
||||
{
|
||||
/// <summary>
|
||||
/// The type of object that handles the graph.
|
||||
/// </summary>
|
||||
[Serialize, Inspectable, UnitHeaderInspectable, UsedImplicitly]
|
||||
public StateGraphContainerType containerType { get; set; }
|
||||
|
||||
protected override bool isGameObject => containerType == StateGraphContainerType.GameObject;
|
||||
}
|
||||
}
|
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: fbd7b60c4f4a7497584ee8214f088e6e
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@@ -0,0 +1,4 @@
|
||||
namespace Unity.VisualScripting
|
||||
{
|
||||
public interface INesterState : IState, IGraphNesterElement { }
|
||||
}
|
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 282cb8ec0af2e4987af050cc49330b34
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@@ -0,0 +1,4 @@
|
||||
namespace Unity.VisualScripting
|
||||
{
|
||||
public interface INesterStateTransition : IStateTransition, IGraphNesterElement { }
|
||||
}
|
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: f409aafa57ad9451ab40c8c245eb8ed5
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@@ -0,0 +1,36 @@
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
|
||||
namespace Unity.VisualScripting
|
||||
{
|
||||
public interface IState : IGraphElementWithDebugData, IGraphElementWithData
|
||||
{
|
||||
new StateGraph graph { get; }
|
||||
|
||||
bool isStart { get; set; }
|
||||
|
||||
bool canBeSource { get; }
|
||||
|
||||
bool canBeDestination { get; }
|
||||
|
||||
void OnBranchTo(Flow flow, IState destination);
|
||||
|
||||
IEnumerable<IStateTransition> outgoingTransitions { get; }
|
||||
|
||||
IEnumerable<IStateTransition> incomingTransitions { get; }
|
||||
|
||||
IEnumerable<IStateTransition> transitions { get; }
|
||||
|
||||
void OnEnter(Flow flow, StateEnterReason reason);
|
||||
|
||||
void OnExit(Flow flow, StateExitReason reason);
|
||||
|
||||
#region Widget
|
||||
|
||||
Vector2 position { get; set; }
|
||||
|
||||
float width { get; set; }
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 0d4c8c0a5be6245e2aad918069f79df5
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@@ -0,0 +1,9 @@
|
||||
namespace Unity.VisualScripting
|
||||
{
|
||||
public interface IStateDebugData : IGraphElementDebugData
|
||||
{
|
||||
int lastEnterFrame { get; }
|
||||
|
||||
float lastExitTime { get; }
|
||||
}
|
||||
}
|
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 96720bb3a1ee0448b8de15584f45ad51
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@@ -0,0 +1,11 @@
|
||||
namespace Unity.VisualScripting
|
||||
{
|
||||
public interface IStateTransition : IGraphElementWithDebugData, IConnection<IState, IState>
|
||||
{
|
||||
void Branch(Flow flow);
|
||||
|
||||
void OnEnter(Flow flow);
|
||||
|
||||
void OnExit(Flow flow);
|
||||
}
|
||||
}
|
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: c62d7cadff98b452b84915368d99ef5d
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@@ -0,0 +1,9 @@
|
||||
namespace Unity.VisualScripting
|
||||
{
|
||||
public interface IStateTransitionDebugData : IGraphElementDebugData
|
||||
{
|
||||
int lastBranchFrame { get; }
|
||||
|
||||
float lastBranchTime { get; }
|
||||
}
|
||||
}
|
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 115b9acbeb0934c0daf0875f2eb28b61
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@@ -0,0 +1,60 @@
|
||||
using System.Collections.Generic;
|
||||
using UnityObject = UnityEngine.Object;
|
||||
|
||||
namespace Unity.VisualScripting
|
||||
{
|
||||
public abstract class NesterState<TGraph, TMacro> : State, INesterState
|
||||
where TGraph : class, IGraph, new()
|
||||
where TMacro : Macro<TGraph>
|
||||
{
|
||||
protected NesterState()
|
||||
{
|
||||
nest.nester = this;
|
||||
}
|
||||
|
||||
protected NesterState(TMacro macro)
|
||||
{
|
||||
nest.nester = this;
|
||||
nest.macro = macro;
|
||||
nest.source = GraphSource.Macro;
|
||||
}
|
||||
|
||||
[Serialize]
|
||||
public GraphNest<TGraph, TMacro> nest { get; private set; } = new GraphNest<TGraph, TMacro>();
|
||||
|
||||
[DoNotSerialize]
|
||||
IGraphNest IGraphNester.nest => nest;
|
||||
|
||||
[DoNotSerialize]
|
||||
IGraph IGraphParent.childGraph => nest.graph;
|
||||
|
||||
[DoNotSerialize]
|
||||
bool IGraphParent.isSerializationRoot => nest.source == GraphSource.Macro;
|
||||
|
||||
[DoNotSerialize]
|
||||
UnityObject IGraphParent.serializedObject => nest.macro;
|
||||
|
||||
[DoNotSerialize]
|
||||
public override IEnumerable<ISerializationDependency> deserializationDependencies => nest.deserializationDependencies;
|
||||
|
||||
protected void CopyFrom(NesterState<TGraph, TMacro> source)
|
||||
{
|
||||
base.CopyFrom(source);
|
||||
|
||||
nest = source.nest;
|
||||
}
|
||||
|
||||
public override IEnumerable<object> GetAotStubs(HashSet<object> visited)
|
||||
{
|
||||
return LinqUtility.Concat<object>(base.GetAotStubs(visited), nest.GetAotStubs(visited));
|
||||
}
|
||||
|
||||
public abstract TGraph DefaultGraph();
|
||||
|
||||
IGraph IGraphParent.DefaultGraph() => DefaultGraph();
|
||||
|
||||
void IGraphNester.InstantiateNest() => InstantiateNest();
|
||||
|
||||
void IGraphNester.UninstantiateNest() => UninstantiateNest();
|
||||
}
|
||||
}
|
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 13dd86e0bca1a407a84da6c49b4dda21
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@@ -0,0 +1,58 @@
|
||||
using System.Collections.Generic;
|
||||
using UnityObject = UnityEngine.Object;
|
||||
|
||||
namespace Unity.VisualScripting
|
||||
{
|
||||
public abstract class NesterStateTransition<TGraph, TMacro> : StateTransition, INesterStateTransition
|
||||
where TGraph : class, IGraph, new()
|
||||
where TMacro : Macro<TGraph>
|
||||
{
|
||||
protected NesterStateTransition()
|
||||
{
|
||||
nest.nester = this;
|
||||
}
|
||||
|
||||
protected NesterStateTransition(IState source, IState destination) : base(source, destination)
|
||||
{
|
||||
nest.nester = this;
|
||||
}
|
||||
|
||||
[Serialize]
|
||||
public GraphNest<TGraph, TMacro> nest { get; private set; } = new GraphNest<TGraph, TMacro>();
|
||||
|
||||
[DoNotSerialize]
|
||||
IGraphNest IGraphNester.nest => nest;
|
||||
|
||||
[DoNotSerialize]
|
||||
IGraph IGraphParent.childGraph => nest.graph;
|
||||
|
||||
[DoNotSerialize]
|
||||
bool IGraphParent.isSerializationRoot => nest.source == GraphSource.Macro;
|
||||
|
||||
[DoNotSerialize]
|
||||
UnityObject IGraphParent.serializedObject => nest.macro;
|
||||
|
||||
[DoNotSerialize]
|
||||
public override IEnumerable<ISerializationDependency> deserializationDependencies => nest.deserializationDependencies;
|
||||
|
||||
public override IEnumerable<object> GetAotStubs(HashSet<object> visited)
|
||||
{
|
||||
return LinqUtility.Concat<object>(base.GetAotStubs(visited), nest.GetAotStubs(visited));
|
||||
}
|
||||
|
||||
protected void CopyFrom(NesterStateTransition<TGraph, TMacro> source)
|
||||
{
|
||||
base.CopyFrom(source);
|
||||
|
||||
nest = source.nest;
|
||||
}
|
||||
|
||||
public abstract TGraph DefaultGraph();
|
||||
|
||||
IGraph IGraphParent.DefaultGraph() => DefaultGraph();
|
||||
|
||||
void IGraphNester.InstantiateNest() => InstantiateNest();
|
||||
|
||||
void IGraphNester.UninstantiateNest() => UninstantiateNest();
|
||||
}
|
||||
}
|
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: dddbc361923f641f38ce78381c990d01
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@@ -0,0 +1,11 @@
|
||||
namespace Unity.VisualScripting
|
||||
{
|
||||
/// <summary>
|
||||
/// Called in flow graphs nested in state graphs when the parent state node is entered.
|
||||
/// </summary>
|
||||
[UnitCategory("Events/State")]
|
||||
public class OnEnterState : ManualEventUnit<EmptyEventArgs>
|
||||
{
|
||||
protected override string hookName => StateEventHooks.OnEnterState;
|
||||
}
|
||||
}
|
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 648cef6cb6da648ab892e274f45a1fe0
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@@ -0,0 +1,11 @@
|
||||
namespace Unity.VisualScripting
|
||||
{
|
||||
/// <summary>
|
||||
/// Called in flow graphs nested in state graphs before the parent state node is exited.
|
||||
/// </summary>
|
||||
[UnitCategory("Events/State")]
|
||||
public class OnExitState : ManualEventUnit<EmptyEventArgs>
|
||||
{
|
||||
protected override string hookName => StateEventHooks.OnExitState;
|
||||
}
|
||||
}
|
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: d46940e58965841858c395958b43001e
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: a8356fd10cc2a4a52bb860a13dd47a52
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@@ -0,0 +1,48 @@
|
||||
using System.Runtime.CompilerServices;
|
||||
|
||||
#if DISTRIBUTE_ASSEMBLIES
|
||||
using System.Reflection;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
// General Information about an assembly is controlled through the following
|
||||
// set of attributes. Change these attribute values to modify the information
|
||||
// associated with an assembly.
|
||||
|
||||
[assembly: AssemblyTitle("Visual Scripting State (Runtime)")]
|
||||
[assembly: AssemblyDescription("")]
|
||||
[assembly: AssemblyConfiguration("")]
|
||||
[assembly: AssemblyCompany("Unity")]
|
||||
[assembly: AssemblyProduct("Visual Scripting")]
|
||||
[assembly: AssemblyCopyright("Copyright © 2017")]
|
||||
[assembly: AssemblyTrademark("")]
|
||||
[assembly: AssemblyCulture("")]
|
||||
|
||||
// Setting ComVisible to false makes the types in this assembly not visible
|
||||
// to COM components. If you need to access a type in this assembly from
|
||||
// COM, set the ComVisible attribute to true on that type.
|
||||
|
||||
[assembly: ComVisible(false)]
|
||||
|
||||
// The following GUID is for the ID of the typelib if this project is exposed to COM
|
||||
|
||||
[assembly: Guid("3a1cfa72-fea6-4963-83a5-bcf1deee18c5")]
|
||||
|
||||
// Version information for an assembly consists of the following four values:
|
||||
//
|
||||
// Major Version
|
||||
// Minor Version
|
||||
// Build Number
|
||||
// Revision
|
||||
//
|
||||
// You can specify all the values or you can default the Build and Revision Numbers
|
||||
// by using the '*' as shown below:
|
||||
// [assembly: AssemblyVersion("1.0.*")]
|
||||
|
||||
[assembly: AssemblyVersion("1.0.0.0")]
|
||||
[assembly: AssemblyFileVersion("1.0.0.0")]
|
||||
#endif
|
||||
|
||||
[assembly: InternalsVisibleTo("Unity.VisualScripting.State.Editor")]
|
||||
[assembly: InternalsVisibleTo("Unity.VisualScripting.SettingsProvider.Editor")]
|
||||
[assembly: InternalsVisibleTo("Unity.VisualScripting.Tests.Editor")]
|
||||
[assembly: InternalsVisibleTo("Unity.VisualScripting.Tests")]
|
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: d1dd41397b69847bba137dfd15980ece
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@@ -0,0 +1,235 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using UnityEngine;
|
||||
|
||||
namespace Unity.VisualScripting
|
||||
{
|
||||
public abstract class State : GraphElement<StateGraph>, IState
|
||||
{
|
||||
public class Data : IGraphElementData
|
||||
{
|
||||
public bool isActive;
|
||||
|
||||
public bool hasEntered;
|
||||
}
|
||||
|
||||
public class DebugData : IStateDebugData
|
||||
{
|
||||
public int lastEnterFrame { get; set; }
|
||||
|
||||
public float lastExitTime { get; set; }
|
||||
|
||||
public Exception runtimeException { get; set; }
|
||||
}
|
||||
|
||||
public IGraphElementData CreateData()
|
||||
{
|
||||
return new Data();
|
||||
}
|
||||
|
||||
public IGraphElementDebugData CreateDebugData()
|
||||
{
|
||||
return new DebugData();
|
||||
}
|
||||
|
||||
[Serialize]
|
||||
public bool isStart { get; set; }
|
||||
|
||||
[DoNotSerialize]
|
||||
public virtual bool canBeSource => true;
|
||||
|
||||
[DoNotSerialize]
|
||||
public virtual bool canBeDestination => true;
|
||||
|
||||
public override void BeforeRemove()
|
||||
{
|
||||
base.BeforeRemove();
|
||||
|
||||
Disconnect();
|
||||
}
|
||||
|
||||
public override void Instantiate(GraphReference instance)
|
||||
{
|
||||
base.Instantiate(instance);
|
||||
|
||||
var data = instance.GetElementData<Data>(this);
|
||||
|
||||
if (this is IGraphEventListener listener && data.isActive)
|
||||
{
|
||||
listener.StartListening(instance);
|
||||
}
|
||||
else if (isStart && !data.hasEntered && graph.IsListening(instance))
|
||||
{
|
||||
using (var flow = Flow.New(instance))
|
||||
{
|
||||
OnEnter(flow, StateEnterReason.Start);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public override void Uninstantiate(GraphReference instance)
|
||||
{
|
||||
if (this is IGraphEventListener listener)
|
||||
{
|
||||
listener.StopListening(instance);
|
||||
}
|
||||
|
||||
base.Uninstantiate(instance);
|
||||
}
|
||||
|
||||
#region Poutine
|
||||
|
||||
protected void CopyFrom(State source)
|
||||
{
|
||||
base.CopyFrom(source);
|
||||
|
||||
isStart = source.isStart;
|
||||
width = source.width;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Transitions
|
||||
|
||||
public IEnumerable<IStateTransition> outgoingTransitions => graph?.transitions.WithSource(this) ?? Enumerable.Empty<IStateTransition>();
|
||||
|
||||
public IEnumerable<IStateTransition> incomingTransitions => graph?.transitions.WithDestination(this) ?? Enumerable.Empty<IStateTransition>();
|
||||
|
||||
protected List<IStateTransition> outgoingTransitionsNoAlloc => graph?.transitions.WithSourceNoAlloc(this) ?? Empty<IStateTransition>.list;
|
||||
|
||||
public IEnumerable<IStateTransition> transitions => LinqUtility.Concat<IStateTransition>(outgoingTransitions, incomingTransitions);
|
||||
|
||||
public void Disconnect()
|
||||
{
|
||||
foreach (var transition in transitions.ToArray())
|
||||
{
|
||||
graph.transitions.Remove(transition);
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Lifecycle
|
||||
|
||||
public virtual void OnEnter(Flow flow, StateEnterReason reason)
|
||||
{
|
||||
var data = flow.stack.GetElementData<Data>(this);
|
||||
|
||||
if (data.isActive) // Prevent re-entry from Any State
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
data.isActive = true;
|
||||
|
||||
data.hasEntered = true;
|
||||
|
||||
foreach (var transition in outgoingTransitionsNoAlloc)
|
||||
{
|
||||
// Start listening for the transition's events
|
||||
// before entering the state in case OnEnterState
|
||||
// actually instantly triggers a transition via event
|
||||
// http://support.ludiq.io/topics/261-event-timing-issue/
|
||||
(transition as IGraphEventListener)?.StartListening(flow.stack);
|
||||
}
|
||||
|
||||
if (flow.enableDebug)
|
||||
{
|
||||
var editorData = flow.stack.GetElementDebugData<DebugData>(this);
|
||||
|
||||
editorData.lastEnterFrame = EditorTimeBinding.frame;
|
||||
}
|
||||
|
||||
OnEnterImplementation(flow);
|
||||
|
||||
foreach (var transition in outgoingTransitionsNoAlloc)
|
||||
{
|
||||
try
|
||||
{
|
||||
transition.OnEnter(flow);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
transition.HandleException(flow.stack, ex);
|
||||
throw;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public virtual void OnExit(Flow flow, StateExitReason reason)
|
||||
{
|
||||
var data = flow.stack.GetElementData<Data>(this);
|
||||
|
||||
if (!data.isActive)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
OnExitImplementation(flow);
|
||||
|
||||
data.isActive = false;
|
||||
|
||||
if (flow.enableDebug)
|
||||
{
|
||||
var editorData = flow.stack.GetElementDebugData<DebugData>(this);
|
||||
|
||||
editorData.lastExitTime = EditorTimeBinding.time;
|
||||
}
|
||||
|
||||
foreach (var transition in outgoingTransitionsNoAlloc)
|
||||
{
|
||||
try
|
||||
{
|
||||
transition.OnExit(flow);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
transition.HandleException(flow.stack, ex);
|
||||
throw;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected virtual void OnEnterImplementation(Flow flow) { }
|
||||
|
||||
protected virtual void UpdateImplementation(Flow flow) { }
|
||||
|
||||
protected virtual void FixedUpdateImplementation(Flow flow) { }
|
||||
|
||||
protected virtual void LateUpdateImplementation(Flow flow) { }
|
||||
|
||||
protected virtual void OnExitImplementation(Flow flow) { }
|
||||
|
||||
public virtual void OnBranchTo(Flow flow, IState destination) { }
|
||||
|
||||
#endregion
|
||||
|
||||
#region Widget
|
||||
|
||||
public const float DefaultWidth = 170;
|
||||
|
||||
[Serialize]
|
||||
public Vector2 position { get; set; }
|
||||
|
||||
[Serialize]
|
||||
public float width { get; set; } = DefaultWidth;
|
||||
|
||||
#endregion
|
||||
|
||||
#region Analytics
|
||||
|
||||
public override AnalyticsIdentifier GetAnalyticsIdentifier()
|
||||
{
|
||||
var aid = new AnalyticsIdentifier
|
||||
{
|
||||
Identifier = GetType().FullName,
|
||||
Namespace = GetType().Namespace,
|
||||
};
|
||||
aid.Hashcode = aid.Identifier.GetHashCode();
|
||||
return aid;
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 4218da2cc7b0547f2a287e752116fd68
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@@ -0,0 +1,9 @@
|
||||
namespace Unity.VisualScripting
|
||||
{
|
||||
public enum StateEnterReason
|
||||
{
|
||||
Start,
|
||||
Branch,
|
||||
Forced
|
||||
}
|
||||
}
|
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 7b87087bffe3b43618771b432448cd88
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@@ -0,0 +1,8 @@
|
||||
namespace Unity.VisualScripting
|
||||
{
|
||||
public static class StateEventHooks
|
||||
{
|
||||
public const string OnEnterState = nameof(OnEnterState);
|
||||
public const string OnExitState = nameof(OnExitState);
|
||||
}
|
||||
}
|
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: ff487154bf5ec41f1b830b780c2a8b0a
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@@ -0,0 +1,10 @@
|
||||
namespace Unity.VisualScripting
|
||||
{
|
||||
public enum StateExitReason
|
||||
{
|
||||
Stop,
|
||||
Branch,
|
||||
AnyBranch,
|
||||
Forced
|
||||
}
|
||||
}
|
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: b9937e27525304cf483c1c226a66aace
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@@ -0,0 +1,164 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using UnityEngine;
|
||||
|
||||
namespace Unity.VisualScripting
|
||||
{
|
||||
[SerializationVersion("A")]
|
||||
public sealed class StateGraph : Graph, IGraphEventListener
|
||||
{
|
||||
public StateGraph()
|
||||
{
|
||||
states = new GraphElementCollection<IState>(this);
|
||||
transitions = new GraphConnectionCollection<IStateTransition, IState, IState>(this);
|
||||
groups = new GraphElementCollection<GraphGroup>(this);
|
||||
sticky = new GraphElementCollection<StickyNote>(this);
|
||||
|
||||
elements.Include(states);
|
||||
elements.Include(transitions);
|
||||
elements.Include(groups);
|
||||
elements.Include(sticky);
|
||||
}
|
||||
|
||||
public override IGraphData CreateData()
|
||||
{
|
||||
return new StateGraphData(this);
|
||||
}
|
||||
|
||||
public void StartListening(GraphStack stack)
|
||||
{
|
||||
stack.GetGraphData<StateGraphData>().isListening = true;
|
||||
|
||||
var activeStates = GetActiveStatesNoAlloc(stack);
|
||||
|
||||
foreach (var state in activeStates)
|
||||
{
|
||||
(state as IGraphEventListener)?.StartListening(stack);
|
||||
}
|
||||
|
||||
activeStates.Free();
|
||||
}
|
||||
|
||||
public void StopListening(GraphStack stack)
|
||||
{
|
||||
var activeStates = GetActiveStatesNoAlloc(stack);
|
||||
|
||||
foreach (var state in activeStates)
|
||||
{
|
||||
(state as IGraphEventListener)?.StopListening(stack);
|
||||
}
|
||||
|
||||
activeStates.Free();
|
||||
|
||||
stack.GetGraphData<StateGraphData>().isListening = false;
|
||||
}
|
||||
|
||||
public bool IsListening(GraphPointer pointer)
|
||||
{
|
||||
return pointer.GetGraphData<StateGraphData>().isListening;
|
||||
}
|
||||
|
||||
#region Elements
|
||||
|
||||
[DoNotSerialize]
|
||||
public GraphElementCollection<IState> states { get; internal set; }
|
||||
|
||||
[DoNotSerialize]
|
||||
public GraphConnectionCollection<IStateTransition, IState, IState> transitions { get; internal set; }
|
||||
|
||||
[DoNotSerialize]
|
||||
public GraphElementCollection<GraphGroup> groups { get; internal set; }
|
||||
|
||||
[DoNotSerialize]
|
||||
public GraphElementCollection<StickyNote> sticky { get; private set; }
|
||||
#endregion
|
||||
|
||||
|
||||
#region Lifecycle
|
||||
|
||||
// Active state detection happens twice:
|
||||
//
|
||||
// 1. Before the enumeration, because any state
|
||||
// that becomes active during an update shouldn't
|
||||
// be updated until the next update
|
||||
//
|
||||
// 2. Inside the update method, because a state
|
||||
// that was active during enumeration and no longer
|
||||
// is shouldn't be updated.
|
||||
|
||||
private HashSet<IState> GetActiveStatesNoAlloc(GraphPointer pointer)
|
||||
{
|
||||
var activeStates = HashSetPool<IState>.New();
|
||||
|
||||
foreach (var state in states)
|
||||
{
|
||||
var stateData = pointer.GetElementData<State.Data>(state);
|
||||
|
||||
if (stateData.isActive)
|
||||
{
|
||||
activeStates.Add(state);
|
||||
}
|
||||
}
|
||||
|
||||
return activeStates;
|
||||
}
|
||||
|
||||
public void Start(Flow flow)
|
||||
{
|
||||
flow.stack.GetGraphData<StateGraphData>().isListening = true;
|
||||
|
||||
foreach (var state in states.Where(s => s.isStart))
|
||||
{
|
||||
try
|
||||
{
|
||||
state.OnEnter(flow, StateEnterReason.Start);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
state.HandleException(flow.stack, ex);
|
||||
throw;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void Stop(Flow flow)
|
||||
{
|
||||
var activeStates = GetActiveStatesNoAlloc(flow.stack);
|
||||
|
||||
foreach (var state in activeStates)
|
||||
{
|
||||
try
|
||||
{
|
||||
state.OnExit(flow, StateExitReason.Stop);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
state.HandleException(flow.stack, ex);
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
activeStates.Free();
|
||||
|
||||
flow.stack.GetGraphData<StateGraphData>().isListening = false;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
|
||||
public static StateGraph WithStart()
|
||||
{
|
||||
var stateGraph = new StateGraph();
|
||||
|
||||
var startState = FlowState.WithEnterUpdateExit();
|
||||
startState.isStart = true;
|
||||
startState.nest.embed.title = "Start";
|
||||
startState.position = new Vector2(-86, -15);
|
||||
|
||||
stateGraph.states.Add(startState);
|
||||
|
||||
return stateGraph;
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: d20b55e1b62454c3cb8261290858b417
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@@ -0,0 +1,21 @@
|
||||
using UnityEngine;
|
||||
|
||||
namespace Unity.VisualScripting
|
||||
{
|
||||
[TypeIcon(typeof(StateGraph))]
|
||||
[CreateAssetMenu(menuName = "Visual Scripting/State Graph", fileName = "New State Graph", order = 81)]
|
||||
[HelpURL("https://docs.unity3d.com/Packages/com.unity.visualscripting@latest/index.html?subfolder=/manual/vs-state-graphs-intro.html")]
|
||||
public sealed class StateGraphAsset : Macro<StateGraph>
|
||||
{
|
||||
[ContextMenu("Show Data...")]
|
||||
protected override void ShowData()
|
||||
{
|
||||
base.ShowData();
|
||||
}
|
||||
|
||||
public override StateGraph DefaultGraph()
|
||||
{
|
||||
return StateGraph.WithStart();
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,15 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 530e556d4407947dcae7102ff497587d
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon:
|
||||
fileID: 2800000
|
||||
guid: f02ed452c3e0d1e448429a89e1773fd7
|
||||
type: 3
|
||||
userData: ''
|
||||
assetBundleName: ''
|
||||
assetBundleVariant: ''
|
||||
...
|
@@ -0,0 +1,11 @@
|
||||
namespace Unity.VisualScripting
|
||||
{
|
||||
public sealed class StateGraphData : GraphData<StateGraph>, IGraphEventListenerData
|
||||
{
|
||||
public bool isListening { get; set; }
|
||||
|
||||
public StateGraphData(StateGraph definition) : base(definition)
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 39a4b0bc9629144cba9983be40f9b8c4
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@@ -0,0 +1,74 @@
|
||||
using UnityEngine;
|
||||
|
||||
namespace Unity.VisualScripting
|
||||
{
|
||||
[AddComponentMenu("Visual Scripting/State Machine")]
|
||||
[RequireComponent(typeof(Variables))]
|
||||
[DisableAnnotation]
|
||||
[VisualScriptingHelpURL(typeof(StateMachine))]
|
||||
public sealed class StateMachine : EventMachine<StateGraph, StateGraphAsset>
|
||||
{
|
||||
protected override void OnEnable()
|
||||
{
|
||||
if (hasGraph)
|
||||
{
|
||||
using (var flow = Flow.New(reference))
|
||||
{
|
||||
graph.Start(flow);
|
||||
}
|
||||
}
|
||||
|
||||
base.OnEnable();
|
||||
}
|
||||
|
||||
protected override void OnInstantiateWhileEnabled()
|
||||
{
|
||||
if (hasGraph)
|
||||
{
|
||||
using (var flow = Flow.New(reference))
|
||||
{
|
||||
graph.Start(flow);
|
||||
}
|
||||
}
|
||||
|
||||
base.OnInstantiateWhileEnabled();
|
||||
}
|
||||
|
||||
protected override void OnUninstantiateWhileEnabled()
|
||||
{
|
||||
base.OnUninstantiateWhileEnabled();
|
||||
|
||||
if (hasGraph)
|
||||
{
|
||||
using (var flow = Flow.New(reference))
|
||||
{
|
||||
graph.Stop(flow);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected override void OnDisable()
|
||||
{
|
||||
base.OnDisable();
|
||||
|
||||
if (hasGraph)
|
||||
{
|
||||
using (var flow = Flow.New(reference))
|
||||
{
|
||||
graph.Stop(flow);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
[ContextMenu("Show Data...")]
|
||||
protected override void ShowData()
|
||||
{
|
||||
base.ShowData();
|
||||
}
|
||||
|
||||
public override StateGraph DefaultGraph()
|
||||
{
|
||||
return StateGraph.WithStart();
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,15 @@
|
||||
fileFormatVersion: 2
|
||||
guid: efe58df89b5b74a97a123b5ed2b70422
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon:
|
||||
fileID: 2800000
|
||||
guid: f144232ea2c6046438f6cda6c1bad1af
|
||||
type: 3
|
||||
userData: ''
|
||||
assetBundleName: ''
|
||||
assetBundleVariant: ''
|
||||
...
|
@@ -0,0 +1,115 @@
|
||||
using System;
|
||||
|
||||
namespace Unity.VisualScripting
|
||||
{
|
||||
public abstract class StateTransition : GraphElement<StateGraph>, IStateTransition
|
||||
{
|
||||
public class DebugData : IStateTransitionDebugData
|
||||
{
|
||||
public Exception runtimeException { get; set; }
|
||||
|
||||
public int lastBranchFrame { get; set; }
|
||||
|
||||
public float lastBranchTime { get; set; }
|
||||
}
|
||||
|
||||
protected StateTransition() { }
|
||||
|
||||
protected StateTransition(IState source, IState destination)
|
||||
{
|
||||
Ensure.That(nameof(source)).IsNotNull(source);
|
||||
Ensure.That(nameof(destination)).IsNotNull(destination);
|
||||
|
||||
if (source.graph != destination.graph)
|
||||
{
|
||||
throw new NotSupportedException("Cannot create transitions across state graphs.");
|
||||
}
|
||||
|
||||
this.source = source;
|
||||
this.destination = destination;
|
||||
}
|
||||
|
||||
public IGraphElementDebugData CreateDebugData()
|
||||
{
|
||||
return new DebugData();
|
||||
}
|
||||
|
||||
public override int dependencyOrder => 1;
|
||||
|
||||
[Serialize]
|
||||
public IState source { get; internal set; }
|
||||
|
||||
[Serialize]
|
||||
public IState destination { get; internal set; }
|
||||
|
||||
public override void Instantiate(GraphReference instance)
|
||||
{
|
||||
base.Instantiate(instance);
|
||||
|
||||
if (this is IGraphEventListener listener && instance.GetElementData<State.Data>(source).isActive)
|
||||
{
|
||||
listener.StartListening(instance);
|
||||
}
|
||||
}
|
||||
|
||||
public override void Uninstantiate(GraphReference instance)
|
||||
{
|
||||
if (this is IGraphEventListener listener)
|
||||
{
|
||||
listener.StopListening(instance);
|
||||
}
|
||||
|
||||
base.Uninstantiate(instance);
|
||||
}
|
||||
|
||||
#region Lifecycle
|
||||
|
||||
public void Branch(Flow flow)
|
||||
{
|
||||
if (flow.enableDebug)
|
||||
{
|
||||
var editorData = flow.stack.GetElementDebugData<DebugData>(this);
|
||||
|
||||
editorData.lastBranchFrame = EditorTimeBinding.frame;
|
||||
editorData.lastBranchTime = EditorTimeBinding.time;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
source.OnExit(flow, StateExitReason.Branch);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
source.HandleException(flow.stack, ex);
|
||||
throw;
|
||||
}
|
||||
|
||||
source.OnBranchTo(flow, destination);
|
||||
|
||||
try
|
||||
{
|
||||
destination.OnEnter(flow, StateEnterReason.Branch);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
destination.HandleException(flow.stack, ex);
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
public abstract void OnEnter(Flow flow);
|
||||
|
||||
public abstract void OnExit(Flow flow);
|
||||
|
||||
#endregion
|
||||
|
||||
#region Analytics
|
||||
|
||||
public override AnalyticsIdentifier GetAnalyticsIdentifier()
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user