From 7fc1ebafdb41117c8d32b272e3725836e50deeb7 Mon Sep 17 00:00:00 2001 From: taoria <445625470@qq.com> Date: Fri, 5 Aug 2022 23:48:20 +0800 Subject: [PATCH] fix:fix a blackboard error --- TNode/Samples/AddNode.cs | 23 ++++ TNode/Samples/AddNode.cs.meta | 3 + TNode/Samples/Editor/HelloEditor.cs | 5 +- TNode/Samples/HelloBlackboard.cs | 17 +++ TNode/Samples/HelloBlackboard.cs.meta | 3 + TNode/Samples/HelloGraph.cs | 11 +- TNode/Samples/New HelloGraph.asset | 100 +++++++++++++++++- TNode/TNodeCore/Editor/GraphEditor.cs | 1 + .../Runtime/Models/BlackboardData.cs | 7 +- .../Runtime/RuntimeCache/RuntimeCache.cs | 7 +- .../Editor/Cache/NodeEditorExtensions.cs | 26 ++++- .../DefaultGraphBlackboardView.cs | 13 +-- .../Editor/NodeGraphView/DataGraphView.cs | 73 ++++++++++--- .../Editor/NodeViews/DragNodeView.cs | 1 + .../Search/BlackboardSearchWindowProvider.cs | 10 +- 15 files changed, 254 insertions(+), 46 deletions(-) create mode 100644 TNode/Samples/AddNode.cs create mode 100644 TNode/Samples/AddNode.cs.meta create mode 100644 TNode/Samples/HelloBlackboard.cs create mode 100644 TNode/Samples/HelloBlackboard.cs.meta diff --git a/TNode/Samples/AddNode.cs b/TNode/Samples/AddNode.cs new file mode 100644 index 0000000..2c22e58 --- /dev/null +++ b/TNode/Samples/AddNode.cs @@ -0,0 +1,23 @@ + +using TNodeCore.Runtime; +using TNodeCore.Runtime.Attributes; +using TNodeCore.Runtime.Attributes.Ports; +using TNodeCore.Runtime.Models; +using UnityEngine; + +namespace Samples{ + [GraphUsage(typeof(HelloGraph),"Math")] + public class AddNode:NodeData{ + [Input] + public Vector3 A{ get; set; } + [Input] + public Vector2 B{ get; set; } + [Output] + public Vector3 Res{ get; set; } + + public override void Process(){ + Res = A + (Vector3)B; + this.Log(Res.ToString()); + } + } +} \ No newline at end of file diff --git a/TNode/Samples/AddNode.cs.meta b/TNode/Samples/AddNode.cs.meta new file mode 100644 index 0000000..89b3d0d --- /dev/null +++ b/TNode/Samples/AddNode.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: f9814ff421124feda824b77793cf24f2 +timeCreated: 1659705932 \ No newline at end of file diff --git a/TNode/Samples/Editor/HelloEditor.cs b/TNode/Samples/Editor/HelloEditor.cs index f7e4219..055890b 100644 --- a/TNode/Samples/Editor/HelloEditor.cs +++ b/TNode/Samples/Editor/HelloEditor.cs @@ -1,3 +1,4 @@ +using Samples; using UnityEditor; using UnityEditor.Callbacks; using UnityEngine; @@ -8,7 +9,7 @@ public class HelloEditor : GraphEditor{ var graph = EditorUtility.InstanceIDToObject(instanceID) as HelloGraph; if (graph != null) { var wnd = GetWindow(); - wnd.titleContent = new GUIContent("EasyGraph Editor"); + wnd.titleContent = new GUIContent("HelloGraph Editor"); wnd.Show(); wnd.SetupNonRuntime(graph); return true; @@ -18,7 +19,7 @@ public class HelloEditor : GraphEditor{ [MenuItem("Window/HelloEditor")] public static void ShowWindow(){ var res = GetWindow(); - res.titleContent = new GUIContent("EasyGraph Editor"); + res.titleContent = new GUIContent("HelloGraph Editor"); res.Show(); } diff --git a/TNode/Samples/HelloBlackboard.cs b/TNode/Samples/HelloBlackboard.cs new file mode 100644 index 0000000..0b1f787 --- /dev/null +++ b/TNode/Samples/HelloBlackboard.cs @@ -0,0 +1,17 @@ +using System; +using System.Collections.Generic; +using Samples; +using TNodeCore.Runtime.Attributes; +using TNodeCore.Runtime.Models; +using UnityEngine; + +namespace TNode.Samples{ + [GraphUsage(typeof(HelloGraph))] + public class HelloBlackboard:BlackboardData{ + public string HelloString = "Hello World"; + + public List V3S; + public List V2S; + + } +} \ No newline at end of file diff --git a/TNode/Samples/HelloBlackboard.cs.meta b/TNode/Samples/HelloBlackboard.cs.meta new file mode 100644 index 0000000..81c6994 --- /dev/null +++ b/TNode/Samples/HelloBlackboard.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: edaf56bfb57443eb85ecadd142c4ce7d +timeCreated: 1659706002 \ No newline at end of file diff --git a/TNode/Samples/HelloGraph.cs b/TNode/Samples/HelloGraph.cs index 9c4dd64..779c75d 100644 --- a/TNode/Samples/HelloGraph.cs +++ b/TNode/Samples/HelloGraph.cs @@ -1,8 +1,11 @@ -using UnityEngine; using System; using TNodeCore.Runtime.Models; -[CreateAssetMenu(fileName = "New HelloGraph", menuName = "TNode/HelloGraph")] -[Serializable] -public class HelloGraph : GraphData{ +using UnityEngine; + +namespace Samples{ + [CreateAssetMenu(fileName = "New HelloGraph", menuName = "TNode/HelloGraph")] + [Serializable] + public class HelloGraph : GraphData{ + } } \ No newline at end of file diff --git a/TNode/Samples/New HelloGraph.asset b/TNode/Samples/New HelloGraph.asset index 58a1457..687fdaa 100644 --- a/TNode/Samples/New HelloGraph.asset +++ b/TNode/Samples/New HelloGraph.asset @@ -12,13 +12,103 @@ MonoBehaviour: m_Script: {fileID: 11500000, guid: 2051a0adbd1ba974084a535dd06ab7d7, type: 3} m_Name: New HelloGraph m_EditorClassIdentifier: - nodeList: [] - nodeLinks: [] + nodeList: + - rid: 4804121563801583862 + - rid: 4804121563801583898 + - rid: 4804121563801583870 + - rid: 4804121563801583866 + nodeLinks: + - inPort: + portEntryName: A + nodeDataId: 6ceba867-fe0d-40c3-9d30-2d5d12803b52 + outPort: + portEntryName: Value + nodeDataId: ac84573e-638d-45fa-b4e2-1a81c31fa9e7 + - inPort: + portEntryName: B + nodeDataId: 6ceba867-fe0d-40c3-9d30-2d5d12803b52 + outPort: + portEntryName: Value + nodeDataId: b2ab4a52-e65d-4104-8891-dc316af217d9 blackboardData: - rid: -2 + rid: 4804121563801583854 sceneReference: references: version: 2 RefIds: - - rid: -2 - type: {class: , ns: , asm: } + - rid: 4804121563801583854 + type: {class: HelloBlackboard, ns: TNode.Samples, asm: Assembly-CSharp} + data: + positionInView: + serializedVersion: 2 + x: 0 + y: 0 + width: 0 + height: 0 + HelloString: Hello World + V3S: + - {x: 0, y: 0, z: 0} + - {x: 0, y: 0, z: 0} + - {x: 0, y: 0, z: 0} + V2S: + - {x: 0, y: 0} + - {x: 0, y: 0} + - {x: 0, y: 0} + - rid: 4804121563801583862 + type: {class: BlackboardDragNodeData, ns: TNodeCore.Runtime.Models, asm: NewAssembly} + data: + positionInView: + serializedVersion: 2 + x: 256 + y: 264 + width: 0 + height: 0 + id: bae506a7-58ec-4b79-9c21-747fa2b6a7ba + nodeName: + entryPoint: 0 + isTest: 0 + blackDragData: HelloString + isListElement: 0 + - rid: 4804121563801583866 + type: {class: AddNode, ns: Samples, asm: Assembly-CSharp} + data: + positionInView: + serializedVersion: 2 + x: 620 + y: 234 + width: 0 + height: 0 + id: 6ceba867-fe0d-40c3-9d30-2d5d12803b52 + nodeName: AddNode + entryPoint: 0 + isTest: 0 + - rid: 4804121563801583870 + type: {class: BlackboardDragNodeData, ns: TNodeCore.Runtime.Models, asm: NewAssembly} + data: + positionInView: + serializedVersion: 2 + x: 469.00006 + y: 336 + width: 0 + height: 0 + id: b2ab4a52-e65d-4104-8891-dc316af217d9 + nodeName: + entryPoint: 0 + isTest: 0 + blackDragData: V2S.0 + isListElement: 1 + - rid: 4804121563801583898 + type: {class: BlackboardDragNodeData, ns: TNodeCore.Runtime.Models, asm: NewAssembly} + data: + positionInView: + serializedVersion: 2 + x: 469 + y: 213 + width: 0 + height: 0 + id: ac84573e-638d-45fa-b4e2-1a81c31fa9e7 + nodeName: + entryPoint: 0 + isTest: 0 + blackDragData: V3S.0 + isListElement: 1 diff --git a/TNode/TNodeCore/Editor/GraphEditor.cs b/TNode/TNodeCore/Editor/GraphEditor.cs index d035c65..b4c339b 100644 --- a/TNode/TNodeCore/Editor/GraphEditor.cs +++ b/TNode/TNodeCore/Editor/GraphEditor.cs @@ -80,6 +80,7 @@ namespace TNodeCore.Editor{ GraphView.IsRuntimeGraph = false; } private void BuildGraphView(){ + GraphView = graphEditorData.GetGraphView(); GraphView.Owner = this; diff --git a/TNode/TNodeCore/Runtime/Models/BlackboardData.cs b/TNode/TNodeCore/Runtime/Models/BlackboardData.cs index 4d67b50..4ca2528 100644 --- a/TNode/TNodeCore/Runtime/Models/BlackboardData.cs +++ b/TNode/TNodeCore/Runtime/Models/BlackboardData.cs @@ -7,10 +7,7 @@ namespace TNodeCore.Runtime.Models{ /// [Serializable] - public class BlackboardData:Model,ICloneable{ - - - - + public abstract class BlackboardData:Model{ + } } \ No newline at end of file diff --git a/TNode/TNodeCore/Runtime/RuntimeCache/RuntimeCache.cs b/TNode/TNodeCore/Runtime/RuntimeCache/RuntimeCache.cs index bb5046e..a3d0f69 100644 --- a/TNode/TNodeCore/Runtime/RuntimeCache/RuntimeCache.cs +++ b/TNode/TNodeCore/Runtime/RuntimeCache/RuntimeCache.cs @@ -175,7 +175,7 @@ namespace TNodeCore.Runtime.RuntimeCache{ } } private readonly Dictionary,bool> _possibleImplicitConversions = new (); - private bool HasImplicitConversion(Type baseType, Type targetType){ + public bool HasImplicitConversion(Type baseType, Type targetType){ var tuple = new Tuple(baseType, targetType); if (_possibleImplicitConversions.ContainsKey(tuple)){ return _possibleImplicitConversions[tuple]; @@ -188,6 +188,7 @@ namespace TNodeCore.Runtime.RuntimeCache{ }); return _possibleImplicitConversions[tuple] = res; } + private void CachingImplicitConversion(Type baseType, Type targetType){ if (HasImplicitConversion(baseType, targetType)) return; @@ -201,8 +202,8 @@ namespace TNodeCore.Runtime.RuntimeCache{ CachedPortConverters[baseType].Add(targetType,typeConverter); } + public object GetConvertedValue(Type from,Type to,object value){ - if(!CachedPortConverters.ContainsKey(from)){ //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. @@ -226,7 +227,7 @@ namespace TNodeCore.Runtime.RuntimeCache{ public List GetSupportedTypes(Type type){ if(!CachedPortConverters.ContainsKey(type)){ - return null; + return new List(); } return CachedPortConverters[type].Keys.ToList(); } diff --git a/TNode/TNodeGraphViewImpl/Editor/Cache/NodeEditorExtensions.cs b/TNode/TNodeGraphViewImpl/Editor/Cache/NodeEditorExtensions.cs index 738cd85..4c996ec 100644 --- a/TNode/TNodeGraphViewImpl/Editor/Cache/NodeEditorExtensions.cs +++ b/TNode/TNodeGraphViewImpl/Editor/Cache/NodeEditorExtensions.cs @@ -10,7 +10,9 @@ using TNodeCore.Editor.EditorPersistence; using TNodeCore.Editor.NodeGraphView; using TNodeCore.Runtime.Attributes; using TNodeCore.Runtime.Models; +using Unity.VisualScripting; using UnityEditor; +using UnityEngine; namespace TNode.TNodeGraphViewImpl.Editor.Cache{ /// @@ -40,7 +42,12 @@ namespace TNode.TNodeGraphViewImpl.Editor.Cache{ get{ return _instance ??= new NodeEditorSingleton(); } } - private static readonly string[] ExcludedAssemblies = new string[]{"Microsoft", "UnityEngine","UnityEditor","mscorlib","System"}; + + private static readonly string[] ExcludedAssemblies = new[]{ + "Microsoft", "UnityEngine","UnityEditor","mscorlib", + "System","Mono","PlasticPipe","unityplastic","ExCSS", + "Unity","PlayerBuildProgramLibrary","netstandard","log4net","Newtonsoft","Bee","nunit","PsdPlugin" + }; public static T CreateViewComponentFromBaseType(){ var implementedType = NodeEditorSingleton.Instance.FromGenericToSpecific[typeof(T)]; var instance = (T)Activator.CreateInstance(implementedType); @@ -63,10 +70,12 @@ namespace TNode.TNodeGraphViewImpl.Editor.Cache{ private NodeEditorSingleton(){ //exclude unity ,system ,and microsoft types - var assemblies = AppDomain. - CurrentDomain.GetAssemblies() - .Where(x=>ExcludedAssemblies.All(y=>!x.GetName().Name.Split(".")[0].Equals(y))); - + var assemblies = AppDomain.CurrentDomain.GetAssemblies(); + + + assemblies = assemblies.Where(x => !ExcludedAssemblies.Contains(x.FullName.Split('.',',',' ')[0])).ToArray(); + foreach (var ass in assemblies){ + } foreach(var assembly in assemblies){ foreach(var type in assembly.GetTypes()){ if(type.IsClass && !type.IsAbstract){ @@ -91,6 +100,7 @@ namespace TNode.TNodeGraphViewImpl.Editor.Cache{ return instance; } private void SetGraphUsageAttribute(Type type){ + foreach (var attribute in type.GetCustomAttributes(typeof(GraphUsageAttribute), true)){ var parent = type.BaseType; if (typeof(Model).IsAssignableFrom(type.BaseType)){ @@ -205,11 +215,15 @@ namespace TNode.TNodeGraphViewImpl.Editor.Cache{ } public static List GetGraphCategories(Type t){ + if(!NodeEditorSingleton.Instance.GraphDataUsage.ContainsKey(t)){ + return new List(); + } var list = NodeEditorSingleton.Instance.GraphDataUsage[t]; //Merge same category var res = list.Select(x=>x.GetCustomAttribute().Category).Distinct().ToList(); return res; } + //TODO Move this method to runtime place public static BlackboardData GetAppropriateBlackboardData(Type t){ if (NodeEditorSingleton.Instance.GraphBlackboard.ContainsKey(t)){ return (BlackboardData)Activator.CreateInstance(NodeEditorSingleton.Instance.GraphBlackboard[t]); @@ -261,8 +275,10 @@ namespace TNode.TNodeGraphViewImpl.Editor.Cache{ } } [InitializeOnLoad] + public class Launcher{ static Launcher(){ + Debug.Log("NES Launched"); NodeEditorSingleton.Instance.Initialize(); } } diff --git a/TNode/TNodeGraphViewImpl/Editor/GraphBlackboard/DefaultGraphBlackboardView.cs b/TNode/TNodeGraphViewImpl/Editor/GraphBlackboard/DefaultGraphBlackboardView.cs index ac89773..649d74d 100644 --- a/TNode/TNodeGraphViewImpl/Editor/GraphBlackboard/DefaultGraphBlackboardView.cs +++ b/TNode/TNodeGraphViewImpl/Editor/GraphBlackboard/DefaultGraphBlackboardView.cs @@ -50,24 +50,24 @@ namespace TNode.TNodeGraphViewImpl.Editor.GraphBlackboard{ blackboardList.Add(foldout); Add(blackboardList); + if(field.GetValue(data)==null) continue; if (field.GetValue(data) is IList list){ for (var i = 0; i < list.Count; i++){ CreateBlackboardDataEntryForListItem(field, serializedObject, isRuntimeGraph, blackboardList, i); } } - if (field.GetValue(data).GetType().IsArray){ var array = (Array)field.GetValue(data); + if(array==null) continue; for (var i = 0; i < array.Length; i++){ CreateBlackboardDataEntryForListItem(field, serializedObject, isRuntimeGraph, blackboardList, i); } } } } - addItemRequested += (sender) => { + addItemRequested = (sender) => { var res = ScriptableObject.CreateInstance(); - - + Debug.Log(res); //Get right top corner of the blackboard var blackboardPos = GetPosition().position+OwnerWindow.position.position; @@ -79,7 +79,6 @@ namespace TNode.TNodeGraphViewImpl.Editor.GraphBlackboard{ res.Setup(Owner.GetGraphData().GetType(),Owner,OwnerWindow,this); SearchWindow.Open(searchWindowContext, res); - }; } @@ -87,7 +86,8 @@ namespace TNode.TNodeGraphViewImpl.Editor.GraphBlackboard{ private static void CreateBlackboardDataEntryForListItem(FieldInfo field, SerializedObject serializedObject, bool isRuntimeGraph, BlackboardSection blackboardSection, int index){ - var property =serializedObject.FindProperty("data").FindPropertyRelative(field.Name).GetArrayElementAtIndex(index); + var property = serializedObject.FindProperty("data"); + property = property.FindPropertyRelative(field.Name).GetArrayElementAtIndex(index); BlackboardDataEntry entry = new BlackboardDataEntry(field.FieldType){ propertyPath = field.Name+"."+index, @@ -102,6 +102,7 @@ namespace TNode.TNodeGraphViewImpl.Editor.GraphBlackboard{ } + private static void CreateBlackboardDataEntry(FieldInfo field, SerializedObject serializedObject, bool isRuntimeGraph, BlackboardSection blackboardSection){ BlackboardDataEntry entry = new BlackboardDataEntry(field.FieldType){ diff --git a/TNode/TNodeGraphViewImpl/Editor/NodeGraphView/DataGraphView.cs b/TNode/TNodeGraphViewImpl/Editor/NodeGraphView/DataGraphView.cs index 8a1459d..4eef460 100644 --- a/TNode/TNodeGraphViewImpl/Editor/NodeGraphView/DataGraphView.cs +++ b/TNode/TNodeGraphViewImpl/Editor/NodeGraphView/DataGraphView.cs @@ -145,6 +145,7 @@ namespace TNode.TNodeGraphViewImpl.Editor.NodeGraphView{ if (Data != null){ visualElement.RemoveFromHierarchy(); } + CreateMenu(); }; } @@ -218,8 +219,7 @@ namespace TNode.TNodeGraphViewImpl.Editor.NodeGraphView{ _loaded = true; SetDetachedFromPanel(); - - + } private void SetDetachedFromPanel(){ @@ -241,6 +241,7 @@ namespace TNode.TNodeGraphViewImpl.Editor.NodeGraphView{ } protected void CreateMenu(){ + if (this.Q("TopMenu") != null) return; var visualElement = new VisualElement{ name = "TopMenu" }; @@ -278,6 +279,16 @@ namespace TNode.TNodeGraphViewImpl.Editor.NodeGraphView{ } }); visualElement.Add(runButton); + + var blackboardButton = new Button{ + name = "blackboardButton", + text = "Blackboard" + }; + blackboardButton.RegisterCallback(evt => { + if(_blackboard==null) + CreateBlackboard(); + }); + visualElement.Add(blackboardButton); } public void RegisterDragEvent(){ @@ -399,12 +410,14 @@ namespace TNode.TNodeGraphViewImpl.Editor.NodeGraphView{ } - private void BlackboardUpdate(){ + private void UpdateBlackboardData(){ + if (_data == null) return; + if (_data.blackboardData == null || _data.blackboardData.GetType()==(typeof(BlackboardData))){ + _data.blackboardData = NodeEditorExtensions.GetAppropriateBlackboardData(_data.GetType()); - + Debug.Log(_data.blackboardData); if (_data.blackboardData == null) return; - } _blackboard.SetBlackboardData(GetBlackboardData()); } @@ -506,15 +519,45 @@ namespace TNode.TNodeGraphViewImpl.Editor.NodeGraphView{ }); } public override List GetCompatiblePorts(Port startPort, NodeAdapter nodeAdapter){ - var supportedTypes = RuntimeCache.Instance.GetSupportedTypes(startPort.portType); - + + var compatiblePorts = ports.Where(x => startPort != x && - (x.portType == startPort.portType || - x.portType.IsAssignableFrom(startPort.portType) - )).ToList(); - if (supportedTypes != null){ - compatiblePorts.AddRange(ports.Where(x => supportedTypes.Contains(x.portType)).ToList()); + (x.portType == startPort.portType || + x.portType.IsAssignableFrom(startPort.portType) + )).ToList(); + if(startPort.direction==Direction.Input){ + //Search output to find ports with type that have implicit conversion or define converter that convert to type of the startPort + var outputPorts = ports.Where(x => x.direction == Direction.Output).ToList(); + foreach (var outputPort in outputPorts){ + //Want a port type that can convert to to the type of the startPort + if (HasImplicitConversion(outputPort.portType,startPort.portType)){ + compatiblePorts.Add(outputPort); + } + if (RuntimeCache.Instance.GetSupportedTypes(outputPort.portType).Contains(startPort.portType)){ + compatiblePorts.Add(outputPort); + } + } + } + else{ + var inputPorts = ports.Where(x => x.direction == Direction.Input).ToList(); + + foreach (var inputPort in inputPorts){ + //check if start port could implicitly convert to input port type + if (HasImplicitConversion(startPort.portType,inputPort.portType)){ + compatiblePorts.Add(inputPort); + } + //Check if input port type is supported by output port type + if (RuntimeCache.Instance.GetSupportedTypes(startPort.portType).Contains(inputPort.portType)){ + compatiblePorts.Add(inputPort); + } + } } + + + + + + return compatiblePorts; @@ -607,6 +650,7 @@ namespace TNode.TNodeGraphViewImpl.Editor.NodeGraphView{ get=>Owner.graphEditorData.autoUpdate; set=>Owner.graphEditorData.autoUpdate = value; } + public override EventPropagation DeleteSelection(){ Undo.RegisterCompleteObjectUndo(_data,"Delete Selection"); var res = base.DeleteSelection(); @@ -616,13 +660,14 @@ namespace TNode.TNodeGraphViewImpl.Editor.NodeGraphView{ } public void CreateBlackboard(){ - _blackboard = NodeEditorExtensions.CreateBlackboardWithGraphData(typeof(T)); + _blackboard = NodeEditorExtensions.CreateBlackboardWithGraphData(typeof(T)) ; _blackboard.Setup(this,Owner); var castedBlackboard = _blackboard as Blackboard; Add(castedBlackboard); Rect blackboardPos = new Rect(0,0,300,700); castedBlackboard?.SetPosition(blackboardPos); - OnDataChanged+= (sender, e) => { BlackboardUpdate(); }; + UpdateBlackboardData(); + OnDataChanged+= (sender, e) => { UpdateBlackboardData(); }; } public GraphData GetGraphData(){ diff --git a/TNode/TNodeGraphViewImpl/Editor/NodeViews/DragNodeView.cs b/TNode/TNodeGraphViewImpl/Editor/NodeViews/DragNodeView.cs index f95f424..4f417f8 100644 --- a/TNode/TNodeGraphViewImpl/Editor/NodeViews/DragNodeView.cs +++ b/TNode/TNodeGraphViewImpl/Editor/NodeViews/DragNodeView.cs @@ -33,6 +33,7 @@ namespace TNode.TNodeGraphViewImpl.Editor.NodeViews{ label.text = ObjectNames.NicifyVariableName(obj.BlackDragData); //Get serialized property's icon Texture2D icon = null; + if (serializedProperty == null) return; if (serializedProperty.boxedValue is Object value){ icon = AssetPreview.GetMiniThumbnail(value); } diff --git a/TNode/TNodeGraphViewImpl/Editor/Search/BlackboardSearchWindowProvider.cs b/TNode/TNodeGraphViewImpl/Editor/Search/BlackboardSearchWindowProvider.cs index fe01ff4..be8e56d 100644 --- a/TNode/TNodeGraphViewImpl/Editor/Search/BlackboardSearchWindowProvider.cs +++ b/TNode/TNodeGraphViewImpl/Editor/Search/BlackboardSearchWindowProvider.cs @@ -31,17 +31,21 @@ namespace TNode.TNodeGraphViewImpl.Editor.Search{ if (list == null) throw new ArgumentNullException(nameof(list)); //search fields with List type Texture2D icon = new Texture2D(2,2); - foreach (var field in type.GetFields()){ if (field.FieldType.IsGenericType){ var genericType = field.FieldType.GetGenericTypeDefinition(); if (genericType == typeof(List<>)){ + var castedList = field.GetValue(blackboardData) as IList; + if (castedList == null){ + field.SetValue(blackboardData, Activator.CreateInstance(field.FieldType)); + } list.Add(new SearchTreeEntry(new GUIContent(field.Name,icon)){ level = 1, userData = new InternalSearchTreeUserData(){ List = field.GetValue(blackboardData) as IList, Type = field.FieldType.GetGenericArguments()[0] } + }); } } @@ -64,7 +68,9 @@ namespace TNode.TNodeGraphViewImpl.Editor.Search{ if (userData is InternalSearchTreeUserData){ var list = ((InternalSearchTreeUserData) userData).List; - Debug.Log(list); + if (list == null){ + + } var type = ((InternalSearchTreeUserData) userData).Type; if (!typeof(Object).IsAssignableFrom(type)){ var newItem = Activator.CreateInstance(type);