Compare commits

..

No commits in common. 'd6e5175a0bf790c5e87b47883045b5d600e4cb74' and '032288c379797cf567d88d65e9643f894ee9226d' have entirely different histories.

  1. 54
      Samples/New HelloGraph.asset
  2. 11
      Samples/Nodes/AddNode.cs
  3. 20
      Samples/Nodes/CheckSizeNode.cs
  4. 3
      TNodeCore/Runtime/Components/ConditionalGraph.cs
  5. 2
      TNodeCore/Runtime/Logger/NodeLogger.cs
  6. 13
      TNodeCore/Runtime/Models/ConditionalNode.cs
  7. 2
      TNodeCore/Runtime/RuntimeCache/IModelPortAccessor.cs
  8. 33
      TNodeCore/Runtime/RuntimeCache/RuntimeCache.cs
  9. 13
      TNodeCore/Runtime/RuntimeModels/ConditionalRuntimeNode.cs
  10. 7
      TNodeCore/Runtime/RuntimeModels/RuntimeNode.cs
  11. 4
      TNodeCore/Runtime/RuntimeModels/StaticGraph.cs
  12. 3
      TNodeCore/Runtime/Tools/GraphTool.cs
  13. 5
      TNodeGraphViewImpl/Editor/GraphBlackboard/DefaultGraphBlackboardView.cs
  14. 4
      TNodeGraphViewImpl/Editor/GraphWatcherView/GraphWatcherView.cs
  15. 3
      Tests/StaticGraphTest.cs

@ -18,7 +18,6 @@ MonoBehaviour:
- id: 2 - id: 2
- id: 3 - id: 3
- id: 4 - id: 4
- id: 5
nodeLinks: nodeLinks:
- inPort: - inPort:
portEntryName: A portEntryName: A
@ -38,18 +37,12 @@ MonoBehaviour:
outPort: outPort:
portEntryName: C portEntryName: C
nodeDataId: 4300534d-023d-4b56-a0cb-39e197e68845 nodeDataId: 4300534d-023d-4b56-a0cb-39e197e68845
- inPort:
portEntryName: B
nodeDataId: 926f2eea-3403-4663-88bd-7ed16ce029fa
outPort:
portEntryName: Value
nodeDataId: 7faced8f-0880-4fc3-b26b-aac148024af8
blackboardData: blackboardData:
id: 6 id: 5
sceneReference: sceneReference:
editorModels: [] editorModels: []
graphViewModel: graphViewModel:
id: 7 id: 6
references: references:
version: 1 version: 1
00000000: 00000000:
@ -58,7 +51,7 @@ MonoBehaviour:
positionInView: positionInView:
serializedVersion: 2 serializedVersion: 2
x: 674 x: 674
y: 239 y: 261
width: 0 width: 0
height: 0 height: 0
id: 6dba1aab-0db9-45a0-b3f7-e8fe9c47c168 id: 6dba1aab-0db9-45a0-b3f7-e8fe9c47c168
@ -74,8 +67,8 @@ MonoBehaviour:
data: data:
positionInView: positionInView:
serializedVersion: 2 serializedVersion: 2
x: 676 x: 674
y: 281 y: 330
width: 0 width: 0
height: 0 height: 0
id: 5fd53e10-e727-45e3-8458-04a6ec8581c4 id: 5fd53e10-e727-45e3-8458-04a6ec8581c4
@ -91,8 +84,8 @@ MonoBehaviour:
data: data:
positionInView: positionInView:
serializedVersion: 2 serializedVersion: 2
x: 786 x: 781
y: 228 y: 252
width: 0 width: 0
height: 0 height: 0
id: 4300534d-023d-4b56-a0cb-39e197e68845 id: 4300534d-023d-4b56-a0cb-39e197e68845
@ -104,8 +97,8 @@ MonoBehaviour:
data: data:
positionInView: positionInView:
serializedVersion: 2 serializedVersion: 2
x: 928 x: 908
y: 189 y: 252
width: 0 width: 0
height: 0 height: 0
id: f236a611-cc64-4fce-88d2-40baf7f4a490 id: f236a611-cc64-4fce-88d2-40baf7f4a490
@ -117,8 +110,8 @@ MonoBehaviour:
data: data:
positionInView: positionInView:
serializedVersion: 2 serializedVersion: 2
x: 1168 x: 1119
y: 188 y: 210
width: 0 width: 0
height: 0 height: 0
id: 926f2eea-3403-4663-88bd-7ed16ce029fa id: 926f2eea-3403-4663-88bd-7ed16ce029fa
@ -126,23 +119,6 @@ MonoBehaviour:
entryPoint: 0 entryPoint: 0
isTest: 0 isTest: 0
00000005: 00000005:
type: {class: BlackboardDragNode, ns: TNodeCore.Runtime.Models, asm: Taoria.TNodeCore.Runtime}
data:
positionInView:
serializedVersion: 2
x: 1056.5
y: 315
width: 0
height: 0
id: 7faced8f-0880-4fc3-b26b-aac148024af8
nodeName:
entryPoint: 0
isTest: 0
blackboardDragTypeString: System.Single, mscorlib, Version=4.0.0.0, Culture=neutral,
PublicKeyToken=b77a5c561934e089
blackDragData: Value.0
isListElement: 1
00000006:
type: {class: HelloBlackboard, ns: TNode.Samples, asm: Assembly-CSharp} type: {class: HelloBlackboard, ns: TNode.Samples, asm: Assembly-CSharp}
data: data:
positionInView: positionInView:
@ -155,9 +131,9 @@ MonoBehaviour:
HelloString: HelloString:
HelloGameObject: {fileID: 0} HelloGameObject: {fileID: 0}
Value: Value:
- 23.9 - 11
- 102.1 - 102.1
00000007: 00000006:
type: {class: GraphViewModel, ns: TNode.TNodeCore.Editor.Models, asm: Taoria.TNodeCore.Runtime} type: {class: GraphViewModel, ns: TNode.TNodeCore.Editor.Models, asm: Taoria.TNodeCore.Runtime}
data: data:
positionInView: positionInView:
@ -167,6 +143,6 @@ MonoBehaviour:
width: 0 width: 0
height: 0 height: 0
id: id:
persistScale: 0.57175326 persistScale: 1
persistOffset: {x: -366, y: 193} persistOffset: {x: -212, y: 19}
isBlackboardOn: 1 isBlackboardOn: 1

@ -1,18 +1,15 @@
using TNodeCore.Runtime; using TNodeCore.Runtime.Attributes;
using TNodeCore.Runtime.Attributes;
using TNodeCore.Runtime.Attributes.Ports; using TNodeCore.Runtime.Attributes.Ports;
using TNodeCore.Runtime.Models; using TNodeCore.Runtime.Models;
namespace Samples.Nodes{ namespace Samples.Nodes{
[GraphUsage(typeof(HelloGraph),"Math")] [GraphUsage(typeof(HelloGraph),"Math")]
public class AddNode:NodeData{ public class AddNode:NodeData{
[Input] public float A{ get; set; } = default;
[Input] [Input]
public float B{ get; set; }= default; public float A{ get; set; }
[Input]
public float B{ get; set; }
[Output] public float C => A + B; [Output] public float C => A + B;
public override void Process(){
this.Log($"{C}");
}
} }
} }

@ -1,8 +1,7 @@
using TNodeCore.Runtime; using TNode.TNodeCore.Runtime.Models;
using TNodeCore.Runtime.Attributes; using TNodeCore.Runtime.Attributes;
using TNodeCore.Runtime.Attributes.Ports; using TNodeCore.Runtime.Attributes.Ports;
using TNodeCore.Runtime.Models; using TNodeCore.Runtime.Models;
using UnityEngine;
namespace Samples.Nodes{ namespace Samples.Nodes{
[GraphUsage(typeof(HelloGraph),"Math")] [GraphUsage(typeof(HelloGraph),"Math")]
@ -11,24 +10,19 @@ namespace Samples.Nodes{
public float A{ get; set; } public float A{ get; set; }
[Output] [Output]
public TransitionCondition<float> Bigger(){ public TransitionCondition Bigger(){
return new TransitionCondition<float>(){ return new TransitionCondition(){
Condition = A>0, Condition = A>0,
Priority = 0, Priority = 0
DataFunc = ()=>A
}; };
} }
[Output] [Output]
public TransitionCondition<float> SmallerOrEqual(){ public TransitionCondition SmallerOrEqual(){
return new TransitionCondition<float>(){ return new TransitionCondition(){
Condition = A<=0, Condition = A<=0,
Priority = 0, Priority = 0
DataFunc = ()=>A
}; };
} }
public override void Process(){
this.Log($"{A}");
}
} }
} }

@ -17,6 +17,9 @@ namespace TNode.TNodeCore.Runtime.Components{
} }
EntryNode = entry.FirstOrDefault() as ConditionalRuntimeNode; EntryNode = entry.FirstOrDefault() as ConditionalRuntimeNode;
} }
public void Run(){ public void Run(){
var res = StepForward(); var res = StepForward();
while (StepForward().MoveNext()){ while (StepForward().MoveNext()){

@ -10,7 +10,7 @@ namespace TNodeCore.Runtime{
if (!Loggers.ContainsKey(t.id)) return; if (!Loggers.ContainsKey(t.id)) return;
var nodeLoggerImpl = Loggers[t.id]; var nodeLoggerImpl = Loggers[t.id];
nodeLoggerImpl.Log(message); nodeLoggerImpl.Log(message);
Debug.Log(message);
} }
} }

@ -1,8 +1,9 @@
 using TNodeCore.Runtime;
using TNodeCore.Runtime.Attributes.Ports;
using TNodeCore.Runtime.Models;
using Unity.Plastic.Newtonsoft.Json.Serialization;
using System; namespace TNode.TNodeCore.Runtime.Models{
namespace TNodeCore.Runtime.Models{
public class ConditionalNode:NodeData{ public class ConditionalNode:NodeData{
} }
@ -24,10 +25,6 @@ namespace TNodeCore.Runtime.Models{
public object GetValue(){ public object GetValue(){
return DataFunc.Invoke(); return DataFunc.Invoke();
} }
public static implicit operator T(TransitionCondition<T> condition){
return condition.DataFunc.Invoke();
}
} }
public interface IBaseTransition{ public interface IBaseTransition{
public bool Condition{ get; set; } public bool Condition{ get; set; }

@ -6,8 +6,6 @@ namespace TNodeCore.Runtime.RuntimeCache{
object GetValue(object model); object GetValue(object model);
void SetValue(object model, object value); void SetValue(object model, object value);
void Reset(object model);
public Type Type{ get; set; } public Type Type{ get; set; }

@ -13,8 +13,6 @@ namespace TNodeCore.Runtime.RuntimeCache{
public class PortAccessor<T1, T2>:IModelPortAccessor{ public class PortAccessor<T1, T2>:IModelPortAccessor{
public readonly Func<T1, T2> Get; public readonly Func<T1, T2> Get;
public readonly Action<T1, T2> Set; public readonly Action<T1, T2> Set;
private readonly Action<T1> _resetFunc;
private readonly T2 _defaultValue;
public PortAccessor(string name,bool property){ public PortAccessor(string name,bool property){
if (property){ if (property){
Type t = typeof(T1); Type t = typeof(T1);
@ -22,21 +20,10 @@ namespace TNodeCore.Runtime.RuntimeCache{
MethodInfo getter = t.GetMethod("get_" + name); MethodInfo getter = t.GetMethod("get_" + name);
MethodInfo setter = t.GetMethod("set_" + name); MethodInfo setter = t.GetMethod("set_" + name);
Type = getter?.ReturnType??setter?.GetParameters()[0].ParameterType; Type = getter?.ReturnType??setter?.GetParameters()[0].ParameterType;
if(getter!=null) if(getter!=null)
Get = (Func<T1, T2>)Delegate.CreateDelegate(typeof(Func<T1, T2>), null, getter); Get = (Func<T1, T2>)Delegate.CreateDelegate(typeof(Func<T1, T2>), null, getter);
if(setter!=null) if(setter!=null)
Set = (Action<T1, T2>)Delegate.CreateDelegate(typeof(Action<T1, T2>), null, setter); Set = (Action<T1, T2>)Delegate.CreateDelegate(typeof(Action<T1, T2>), null, setter);
if (Set != null){
var dummy = Activator.CreateInstance<T1>();
if (Get != null)
_defaultValue = Get(dummy);
_resetFunc += (obj) => {
Set(obj, _defaultValue);
};
}
} }
else{ else{
Type t = typeof(T1); Type t = typeof(T1);
@ -59,12 +46,6 @@ namespace TNodeCore.Runtime.RuntimeCache{
public void SetValue(object model, object value){ public void SetValue(object model, object value){
Set((T1)model,(T2)value); Set((T1)model,(T2)value);
} }
public void Reset(object model){
//Get
_resetFunc?.Invoke((T1)model);
}
public Type Type{ get; set; } public Type Type{ get; set; }
} }
@ -233,21 +214,19 @@ namespace TNodeCore.Runtime.RuntimeCache{
private void CachingImplicitConversion(Type baseType, Type targetType){ private void CachingImplicitConversion(Type baseType, Type targetType){
if (!HasImplicitConversion(baseType, targetType)) return; if (HasImplicitConversion(baseType, targetType)) return;
if (CachedPortConverters.ContainsKey(baseType)&&CachedPortConverters[baseType].ContainsKey(targetType)) return;
//Create Implicit Conversion Helper that caches the implicit cast function //Create Implicit Conversion Helper that caches the implicit cast function
var typeConverter = Activator.CreateInstance(typeof(ImplicitConversionHelper<,>).MakeGenericType(baseType, targetType)) as IPortConverterHelper; var typeConverter = Activator.CreateInstance(typeof(ImplicitConversionHelper<,>).MakeGenericType(baseType, targetType)) as IPortConverterHelper;
if (!CachedPortConverters.ContainsKey(baseType)){ if (!CachedPortConverters.ContainsKey(baseType)){
CachedPortConverters.Add(baseType,new Dictionary<Type,IPortConverterHelper>()); CachedPortConverters.Add(baseType,new Dictionary<Type,IPortConverterHelper>());
} }
CachedPortConverters[baseType].Add(targetType,typeConverter); CachedPortConverters[baseType].Add(targetType,typeConverter);
} }
public object GetConvertedValue(Type from,Type to,object value){ public object GetConvertedValue(Type from,Type to,object value){
if(!CachedPortConverters.ContainsKey(from)){ if(!CachedPortConverters.ContainsKey(from)){
//Find the cached port failed ,check if there is an implicit conversion //Find the cached port failed ,check if there is an implicit conversion
//This inner cache method would only run once,so add a guard to prevent it run again,even though the function itself has a guard statement. //This inner cache method would only run once,so add a guard to prevent it run again,even though the function itself has a guard statement.
@ -405,20 +384,14 @@ namespace TNodeCore.Runtime.RuntimeCache{
var method = typeof(T2).GetMethod("op_Implicit", BindingFlags.Public | BindingFlags.Static, null, new[] { typeof(T1) }, null); var method = typeof(T2).GetMethod("op_Implicit", BindingFlags.Public | BindingFlags.Static, null, new[] { typeof(T1) }, null);
if (method == null){ if (method == null){
//Search it in T1 //Search it in T1
Debug.Log($"{typeof(T1)}"); method = typeof(T1).GetMethod("op_Implicit", BindingFlags.Public | BindingFlags.Static, null, new[] { typeof(T2) }, null);
method = typeof(T1).GetMethods(BindingFlags.Public | BindingFlags.Static).FirstOrDefault(x => x.ReturnType==typeof(T2) && x.Name=="op_Implicit");
} }
//Create the delegate //Create the delegate
if (method != null) if (method != null)
ConvertFunc = (Func<T1, T2>) Delegate.CreateDelegate(typeof(Func<T1, T2>), method); ConvertFunc = (Func<T1, T2>) Delegate.CreateDelegate(typeof(Func<T1, T2>), method);
if (ConvertFunc == null){
Debug.Log($"{method==null}");
}
} }
public object Convert(object value){ public object Convert(object value){
return ConvertFunc((T1) value); return ConvertFunc((T1) value);
} }
} }

@ -1,17 +1,18 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using TNode.TNodeCore.Runtime.Models;
using TNodeCore.Runtime.Models; using TNodeCore.Runtime.Models;
using UnityEngine; using UnityEngine;
namespace TNodeCore.Runtime{ namespace TNodeCore.Runtime{
public class ConditionalRuntimeNode:RuntimeNode{ public class ConditionalRuntimeNode:RuntimeNode{
private readonly List<Tuple<string,Func<IBaseTransition>>> _possibleTransition; private readonly List<Tuple<string,Func<TransitionCondition>>> _possibleTransition;
public ConditionalRuntimeNode(NodeData nodeData) : base(nodeData){ public ConditionalRuntimeNode(NodeData nodeData) : base(nodeData){
if (nodeData is ConditionalNode conditionalNode){ if (nodeData is ConditionalNode conditionalNode){
var transitionPort = GetPortsOfType<IBaseTransition>(); var transitionPort = GetPortsOfType<TransitionCondition>();
_possibleTransition = new List<Tuple<string,Func<IBaseTransition>>>(); _possibleTransition = new List<Tuple<string,Func<TransitionCondition>>>();
var allOutput = GetPortsOfType<object>().Where(x => GetPortDirection(x) == Direction.Output); var allOutput = GetPortsOfType<object>().Where(x => GetPortDirection(x) == Direction.Output);
var enumerable = allOutput as string[] ?? allOutput.ToArray(); var enumerable = allOutput as string[] ?? allOutput.ToArray();
if (enumerable.Count() != transitionPort.Length){ if (enumerable.Count() != transitionPort.Length){
@ -21,7 +22,7 @@ namespace TNodeCore.Runtime{
} }
foreach (var port in transitionPort){ foreach (var port in transitionPort){
if(GetPortDirection(port)==Direction.Input) continue; if(GetPortDirection(port)==Direction.Input) continue;
_possibleTransition.Add(new Tuple<string, Func<IBaseTransition>>(port,() => (IBaseTransition)GetOutput(port)) ); _possibleTransition.Add(new Tuple<string, Func<TransitionCondition>>(port,() => (TransitionCondition)GetOutput(port)) );
} }
} }
else{ else{
@ -38,8 +39,8 @@ namespace TNodeCore.Runtime{
} }
public string GetNextNodeId(){ public string GetNextNodeId(){
List<Tuple<string,IBaseTransition>> possibleCondition = _possibleTransition List<Tuple<string,TransitionCondition>> possibleCondition = _possibleTransition
.Select(x=>new Tuple<string,IBaseTransition>(x.Item1,x.Item2())) .Select(x=>new Tuple<string,TransitionCondition>(x.Item1,x.Item2()))
.Where(x=>x.Item2.Condition).ToList(); .Where(x=>x.Item2.Condition).ToList();
possibleCondition.Sort((a, b) => { possibleCondition.Sort((a, b) => {
var compareTo = b.Item2.Priority.CompareTo(a.Item2.Priority); var compareTo = b.Item2.Priority.CompareTo(a.Item2.Priority);

@ -121,12 +121,6 @@ namespace TNodeCore.Runtime{
_portAccessors = RuntimeCache.RuntimeCache.Instance.CachedPortAccessors[_type]; _portAccessors = RuntimeCache.RuntimeCache.Instance.CachedPortAccessors[_type];
} }
public void ResetPortValue(){
foreach (var modelPortAccessor in _portAccessors){
modelPortAccessor.Value.Reset(this.NodeData);
}
}
public List<string> GetInputNodesId(){ public List<string> GetInputNodesId(){
List<string> dependencies = new List<string>(); List<string> dependencies = new List<string>();
foreach (NodeLink link in InputLinks) foreach (NodeLink link in InputLinks)
@ -135,6 +129,7 @@ namespace TNodeCore.Runtime{
} }
return dependencies; return dependencies;
} }
} }
public enum Direction{ public enum Direction{
Input, Input,

@ -1,6 +1,7 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using TNode.TNodeCore.Runtime.Models;
using TNode.TNodeCore.Runtime.Tools; using TNode.TNodeCore.Runtime.Tools;
using TNodeCore.Runtime.Models; using TNodeCore.Runtime.Models;
using UnityEngine; using UnityEngine;
@ -20,6 +21,7 @@ namespace TNodeCore.Runtime.RuntimeModels{
var inNodeId = linkData.inPort.nodeDataId; var inNodeId = linkData.inPort.nodeDataId;
var inNode = _nodes[inNodeId]; var inNode = _nodes[inNodeId];
Debug.Log($"{inNode},{outNode}");
inNode.InputLinks.Add(linkData); inNode.InputLinks.Add(linkData);
} }
public StaticGraph(GraphData graphData){ public StaticGraph(GraphData graphData){
@ -27,6 +29,8 @@ namespace TNodeCore.Runtime.RuntimeModels{
var nodes = graphData.NodeDictionary.Values.ToList(); var nodes = graphData.NodeDictionary.Values.ToList();
var links = graphData.NodeLinks; var links = graphData.NodeLinks;
_nodes = new Dictionary<string, RuntimeNode>(); _nodes = new Dictionary<string, RuntimeNode>();
foreach (var nodeData in nodes){ foreach (var nodeData in nodes){
if(_nodes.ContainsKey(nodeData.id)) continue; if(_nodes.ContainsKey(nodeData.id)) continue;

@ -297,8 +297,7 @@ namespace TNode.TNodeCore.Runtime.Tools{
//TODO looks like this string would be too long to make a cache //TODO looks like this string would be too long to make a cache
var cachedKey = $"{outNode.NodeData.id}-{nodeLink.inPort.portEntryName}"; var cachedKey = $"{outNode.NodeData.id}-{nodeLink.inPort.portEntryName}";
var outValue = OutputCached.ContainsKey(cachedKey) ? OutputCached[cachedKey] : outNode.GetOutput(nodeLink.outPort.portEntryName); var outValue = OutputCached.ContainsKey(cachedKey) ? OutputCached[cachedKey] : outNode.GetOutput(nodeLink.outPort.portEntryName);;
if (_isCachingOutput){ if (_isCachingOutput){
OutputCached[cachedKey] = outValue; OutputCached[cachedKey] = outValue;
} }

@ -88,11 +88,8 @@ namespace TNodeGraphViewImpl.Editor.GraphBlackboard{
bool isRuntimeGraph, bool isRuntimeGraph,
BlackboardSection blackboardSection, int index){ BlackboardSection blackboardSection, int index){
var property = serializedObject.FindProperty("data"); var property = serializedObject.FindProperty("data");
property = property.FindPropertyRelative(field.Name)?.GetArrayElementAtIndex(index); property = property.FindPropertyRelative(field.Name).GetArrayElementAtIndex(index);
if (property == null){
Debug.LogError($"Can not find property {field.Name} in {serializedObject.targetObject.name}");
}
BlackboardDataEntry entry = new BlackboardDataEntry(field.FieldType){ BlackboardDataEntry entry = new BlackboardDataEntry(field.FieldType){
propertyPath = field.Name+"."+index, propertyPath = field.Name+"."+index,
}; };

@ -28,6 +28,7 @@ namespace TNodeGraphViewImpl.Editor.GraphWatcherView{
} }
var baseNodeViews = gv.nodes.ToList().Select(x=>(IBaseNodeView)x); var baseNodeViews = gv.nodes.ToList().Select(x=>(IBaseNodeView)x);
var node = baseNodeViews.First(x=>x.GetNodeData().id==runtimeNodeGraph.CurrentNode().id); var node = baseNodeViews.First(x=>x.GetNodeData().id==runtimeNodeGraph.CurrentNode().id);
Debug.Log(node.GetNodeData().id);
var nodeView = (Node)node; var nodeView = (Node)node;
_highlightedNode = nodeView; _highlightedNode = nodeView;
_highlightedNode.AddToClassList("highlightNode"); _highlightedNode.AddToClassList("highlightNode");
@ -49,9 +50,6 @@ namespace TNodeGraphViewImpl.Editor.GraphWatcherView{
_highlightedNode.style.borderRightWidth = _highlightedNode.style.borderTopWidth = 0; _highlightedNode.style.borderRightWidth = _highlightedNode.style.borderTopWidth = 0;
} }
runtimeNodeGraph.ResetState(); runtimeNodeGraph.ResetState();
foreach (var runtimeNode in runtimeNodeGraph.GetRuntimeNodes()){
runtimeNode.ResetPortValue();
}
} }
}; };

@ -1,12 +1,13 @@
using System.Linq; using System.Linq;
using NUnit.Framework; using NUnit.Framework;
using TNode.TNodeCore.Runtime.Models;
using TNodeCore.Editor.Tools.NodeCreator; using TNodeCore.Editor.Tools.NodeCreator;
using TNodeCore.Runtime; using TNodeCore.Runtime;
using TNodeCore.Runtime.Attributes; using TNodeCore.Runtime.Attributes;
using TNodeCore.Runtime.Attributes.Ports; using TNodeCore.Runtime.Attributes.Ports;
using TNodeCore.Runtime.Models; using TNodeCore.Runtime.Models;
using TNodeCore.Runtime.RuntimeModels; using TNodeCore.Runtime.RuntimeModels;
using UnityEditor.VersionControl;
using UnityEngine; using UnityEngine;
namespace Tests{ namespace Tests{

Loading…
Cancel
Save