1.now graph can create node automatically

main
taoria 3 years ago
parent a24331dc2e
commit a8b5020e69
  1. 6
      Sample/Editor/HelloGraphView.cs
  2. 0
      Sample/HelloGraph.cs
  3. 0
      Sample/HelloGraph.cs.meta
  4. 10
      Sample/HelloNode.cs
  5. 3
      Sample/HelloNode.cs.meta
  6. 337
      Scenes/SampleScene.unity
  7. 12
      TNode/Attribute/AssetMenuCreateAsGraphEditor.cs
  8. 3
      TNode/Attribute/AssetMenuCreateAsGraphEditor.cs.meta
  9. 26
      TNode/Attribute/GraphUsageAttribute.cs
  10. 3
      TNode/Attribute/GraphUsageAttribute.cs.meta
  11. 1
      TNode/Editor/BaseViews/SimpleGraphSubWindow.cs
  12. 96
      TNode/Editor/Cache/NodeEditorExtensions.cs
  13. 8
      TNode/Editor/DefaultNodeView.cs
  14. 3
      TNode/Editor/DefaultNodeView.cs.meta
  15. 7
      TNode/Editor/GraphEditor.cs
  16. 2
      TNode/Editor/Inspector/DefaultInspectorItemFactory.cs
  17. 2
      TNode/Editor/Inspector/NodeInspector.cs
  18. 0
      TNode/Editor/Resources/NodeInspector.uxml
  19. 0
      TNode/Editor/Resources/NodeInspector.uxml.meta
  20. 42
      TNode/Editor/SearchWindowProvider.cs
  21. 3
      TNode/TNodeSample.meta
  22. 8
      TNode/TNodeSample/GraphViewTest.cs
  23. 3
      TNode/TNodeSample/GraphViewTest.cs.meta
  24. 15
      TNode/TNodeSample/NodeDataTest.cs
  25. 3
      TNode/TNodeSample/NodeDataTest.cs.meta

@ -1,9 +1,13 @@
using TNode.Attribute;
using TNode.Editor.BaseViews;
using TNode.Editor.Inspector;
namespace Sample.Editor{
[NodeComponent]
public class HelloGraphView : DataGraphView<HelloGraph>{
public override void OnGraphViewCreate(){
NodeInspector inspector = new NodeInspector();
this.Add(inspector);
}
}
}

@ -0,0 +1,10 @@
using Sample.Editor;
using TNode.Attribute;
using TNode.Models;
namespace Sample{
[GraphUsage(typeof(HelloGraph))]
public class HelloNode:NodeData{
}
}

@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 928bb3292c464ae0b811455e9f4e8667
timeCreated: 1656391464

@ -123,6 +123,107 @@ NavMeshSettings:
debug:
m_Flags: 0
m_NavMeshData: {fileID: 0}
--- !u!1 &507038906
GameObject:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
serializedVersion: 6
m_Component:
- component: {fileID: 507038910}
- component: {fileID: 507038909}
- component: {fileID: 507038908}
- component: {fileID: 507038907}
m_Layer: 5
m_Name: Canvas
m_TagString: Untagged
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 1
--- !u!114 &507038907
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 507038906}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: dc42784cf147c0c48a680349fa168899, type: 3}
m_Name:
m_EditorClassIdentifier:
m_IgnoreReversedGraphics: 1
m_BlockingObjects: 0
m_BlockingMask:
serializedVersion: 2
m_Bits: 4294967295
--- !u!114 &507038908
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 507038906}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: 0cd44c1031e13a943bb63640046fad76, type: 3}
m_Name:
m_EditorClassIdentifier:
m_UiScaleMode: 0
m_ReferencePixelsPerUnit: 100
m_ScaleFactor: 1
m_ReferenceResolution: {x: 800, y: 600}
m_ScreenMatchMode: 0
m_MatchWidthOrHeight: 0
m_PhysicalUnit: 3
m_FallbackScreenDPI: 96
m_DefaultSpriteDPI: 96
m_DynamicPixelsPerUnit: 1
m_PresetInfoIsWorld: 0
--- !u!223 &507038909
Canvas:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 507038906}
m_Enabled: 1
serializedVersion: 3
m_RenderMode: 0
m_Camera: {fileID: 0}
m_PlaneDistance: 100
m_PixelPerfect: 0
m_ReceivesEvents: 1
m_OverrideSorting: 0
m_OverridePixelPerfect: 0
m_SortingBucketNormalizedSize: 0
m_AdditionalShaderChannelsFlag: 0
m_UpdateRectTransformForStandalone: 0
m_SortingLayerID: 0
m_SortingOrder: 0
m_TargetDisplay: 0
--- !u!224 &507038910
RectTransform:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 507038906}
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
m_LocalPosition: {x: 0, y: 0, z: 0}
m_LocalScale: {x: 0, y: 0, z: 0}
m_ConstrainProportionsScale: 0
m_Children: []
m_Father: {fileID: 0}
m_RootOrder: 1
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
m_AnchorMin: {x: 0, y: 0}
m_AnchorMax: {x: 0, y: 0}
m_AnchoredPosition: {x: 0, y: 0}
m_SizeDelta: {x: 0, y: 0}
m_Pivot: {x: 0, y: 0}
--- !u!1 &519420028
GameObject:
m_ObjectHideFlags: 0
@ -202,7 +303,243 @@ Transform:
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
m_LocalPosition: {x: 0, y: 0, z: -10}
m_LocalScale: {x: 1, y: 1, z: 1}
m_ConstrainProportionsScale: 0
m_Children: []
m_Father: {fileID: 0}
m_RootOrder: 0
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
--- !u!1 &691266389
GameObject:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
serializedVersion: 6
m_Component:
- component: {fileID: 691266390}
- component: {fileID: 691266391}
m_Layer: 0
m_Name: Circle
m_TagString: Untagged
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 1
--- !u!4 &691266390
Transform:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 691266389}
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
m_LocalPosition: {x: 0, y: 0, z: 0}
m_LocalScale: {x: 0.79506373, y: 0.7908081, z: 1}
m_ConstrainProportionsScale: 0
m_Children: []
m_Father: {fileID: 1608359614}
m_RootOrder: -1
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
--- !u!331 &691266391
SpriteMask:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 691266389}
m_Enabled: 1
m_CastShadows: 1
m_ReceiveShadows: 1
m_DynamicOccludee: 1
m_StaticShadowCaster: 0
m_MotionVectors: 1
m_LightProbeUsage: 1
m_ReflectionProbeUsage: 1
m_RayTracingMode: 0
m_RayTraceProcedural: 0
m_RenderingLayerMask: 1
m_RendererPriority: 0
m_Materials:
- {fileID: 10758, guid: 0000000000000000f000000000000000, type: 0}
m_StaticBatchInfo:
firstSubMesh: 0
subMeshCount: 0
m_StaticBatchRoot: {fileID: 0}
m_ProbeAnchor: {fileID: 0}
m_LightProbeVolumeOverride: {fileID: 0}
m_ScaleInLightmap: 1
m_ReceiveGI: 1
m_PreserveUVs: 0
m_IgnoreNormalsForChartDetection: 0
m_ImportantGI: 0
m_StitchLightmapSeams: 1
m_SelectedEditorRenderState: 3
m_MinimumChartSize: 4
m_AutoUVMaxDistance: 0.5
m_AutoUVMaxAngle: 89
m_LightmapParameters: {fileID: 0}
m_SortingLayerID: 0
m_SortingLayer: 0
m_SortingOrder: 0
m_Sprite: {fileID: -2413806693520163455, guid: a86470a33a6bf42c4b3595704624658b, type: 3}
m_MaskAlphaCutoff: 0.2
m_FrontSortingLayerID: 0
m_BackSortingLayerID: 0
m_FrontSortingLayer: 0
m_BackSortingLayer: 0
m_FrontSortingOrder: 0
m_BackSortingOrder: 0
m_IsCustomRangeActive: 0
m_SpriteSortPoint: 0
--- !u!1 &1608359612
GameObject:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
serializedVersion: 6
m_Component:
- component: {fileID: 1608359614}
- component: {fileID: 1608359613}
m_Layer: 0
m_Name: Circle
m_TagString: Untagged
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 1
--- !u!212 &1608359613
SpriteRenderer:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 1608359612}
m_Enabled: 1
m_CastShadows: 0
m_ReceiveShadows: 0
m_DynamicOccludee: 1
m_StaticShadowCaster: 0
m_MotionVectors: 1
m_LightProbeUsage: 1
m_ReflectionProbeUsage: 1
m_RayTracingMode: 0
m_RayTraceProcedural: 0
m_RenderingLayerMask: 1
m_RendererPriority: 0
m_Materials:
- {fileID: 10754, guid: 0000000000000000f000000000000000, type: 0}
m_StaticBatchInfo:
firstSubMesh: 0
subMeshCount: 0
m_StaticBatchRoot: {fileID: 0}
m_ProbeAnchor: {fileID: 0}
m_LightProbeVolumeOverride: {fileID: 0}
m_ScaleInLightmap: 1
m_ReceiveGI: 1
m_PreserveUVs: 0
m_IgnoreNormalsForChartDetection: 0
m_ImportantGI: 0
m_StitchLightmapSeams: 1
m_SelectedEditorRenderState: 0
m_MinimumChartSize: 4
m_AutoUVMaxDistance: 0.5
m_AutoUVMaxAngle: 89
m_LightmapParameters: {fileID: 0}
m_SortingLayerID: 0
m_SortingLayer: 0
m_SortingOrder: 0
m_Sprite: {fileID: -2413806693520163455, guid: a86470a33a6bf42c4b3595704624658b, type: 3}
m_Color: {r: 1, g: 1, b: 1, a: 1}
m_FlipX: 0
m_FlipY: 0
m_DrawMode: 0
m_Size: {x: 1, y: 1}
m_AdaptiveModeThreshold: 0.5
m_SpriteTileMode: 0
m_WasSpriteAssigned: 1
m_MaskInteraction: 2
m_SpriteSortPoint: 0
--- !u!4 &1608359614
Transform:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 1608359612}
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
m_LocalPosition: {x: 16.183, y: 14.154, z: 0}
m_LocalScale: {x: 1, y: 1, z: 1}
m_ConstrainProportionsScale: 0
m_Children:
- {fileID: 691266390}
m_Father: {fileID: 0}
m_RootOrder: 3
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
--- !u!1 &1701140682
GameObject:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
serializedVersion: 6
m_Component:
- component: {fileID: 1701140685}
- component: {fileID: 1701140684}
- component: {fileID: 1701140683}
m_Layer: 0
m_Name: EventSystem
m_TagString: Untagged
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 1
--- !u!114 &1701140683
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 1701140682}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: 4f231c4fb786f3946a6b90b886c48677, type: 3}
m_Name:
m_EditorClassIdentifier:
m_HorizontalAxis: Horizontal
m_VerticalAxis: Vertical
m_SubmitButton: Submit
m_CancelButton: Cancel
m_InputActionsPerSecond: 10
m_RepeatDelay: 0.5
m_ForceModuleActive: 0
--- !u!114 &1701140684
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 1701140682}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: 76c392e42b5098c458856cdf6ecaaaa1, type: 3}
m_Name:
m_EditorClassIdentifier:
m_FirstSelected: {fileID: 0}
m_sendNavigationEvents: 1
m_DragThreshold: 10
--- !u!4 &1701140685
Transform:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 1701140682}
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
m_LocalPosition: {x: 0, y: 0, z: 0}
m_LocalScale: {x: 1, y: 1, z: 1}
m_ConstrainProportionsScale: 0
m_Children: []
m_Father: {fileID: 0}
m_RootOrder: 2
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}

@ -1,12 +0,0 @@
using System;
using JetBrains.Annotations;
using UnityEngine;
namespace TNode.Attribute{
[MeansImplicitUse]
[AttributeUsage(AttributeTargets.Class, AllowMultiple = true)]
[BaseTypeRequired(typeof(ScriptableObject))]
public class AssetMenuCreateAsGraphEditorAttribute:System.Attribute{
}
}

@ -1,3 +0,0 @@
fileFormatVersion: 2
guid: 536eae3bd21b49609d88e3bd24b4d7d0
timeCreated: 1656038984

@ -0,0 +1,26 @@
using System;
using JetBrains.Annotations;
using TNode.Models;
using Unity.VisualScripting;
namespace TNode.Attribute{
/// <summary>
/// Use this attribute to claim the usage of a type of node on the derived NodeData class.
/// it can be applied to the same node multiple times.
/// <example>
/// [GraphUsage(DialogueGraph)]
/// </example>
/// </summary>
[AttributeUsage(AttributeTargets.Class)]
[BaseTypeRequired(typeof(NodeData))]
public class GraphUsageAttribute:System.Attribute{
public Type GraphDataType;
public GraphUsageAttribute(Type t){
//check if the type t is graph
if(!typeof(GraphData).IsAssignableFrom(t)){
throw new Exception("The type must be a graph");
}
GraphDataType = t;
}
}
}

@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 25593dbfe27b42809a2a38eae3458521
timeCreated: 1656389642

@ -7,6 +7,7 @@ namespace TNode.BaseViews{
private readonly Dragger _dragger = new Dragger();
protected void ConstructWindowBasicSetting(){
style.position = new StyleEnum<Position>(Position.Absolute);
RegisterCallback<WheelEvent>(evt => { evt.StopPropagation(); });
focusable = false;
capabilities |= Capabilities.Movable | Capabilities.Resizable;

@ -1,38 +1,80 @@
using System;
using System.Collections.Generic;
using System.Linq;
using TNode.Attribute;
using TNode.BaseViews;
using TNode.Editor;
using TNode.Editor.BaseViews;
using TNode.Models;
using UnityEditor.Experimental.GraphView;
using UnityEngine;
namespace TNode.Cache{
/// <summary>
/// Internal singleton class for caching TNode reflection Data.
/// </summary>
internal class NodeEditorSingleton{
private static NodeEditorSingleton _instance;
public readonly Dictionary<Type,Type> FromGenericToSpecific = new Dictionary<Type, Type>();
public readonly Dictionary<Type, List<Type>> GraphDataUsage = new Dictionary<Type, List<Type>>();
public static NodeEditorSingleton Instance{
get{ return _instance ??= new NodeEditorSingleton(); }
}
private static readonly string[] ExcludedAssemblies = new string[]{"Microsoft", "UnityEngine","UnityEditor","mscorlib","System"};
private NodeEditorSingleton(){
foreach(var assembly in AppDomain.CurrentDomain.GetAssemblies()){
//exclude unity ,system ,and microsoft types
var assemblies = AppDomain.
CurrentDomain.GetAssemblies()
.Where(x=>ExcludedAssemblies.All(y=>!x.GetName().Name.Split(".")[0].Equals(y)));
foreach(var assembly in assemblies){
foreach(var type in assembly.GetTypes()){
if(type.IsClass && !type.IsAbstract){
foreach(var attribute in type.GetCustomAttributes(typeof(NodeComponentAttribute), false)){
//fetch this type 's parent class
var parent = type.BaseType;
//Check if this type is a generic type and is a generic type of NodeView or DataGraphView
if(parent is{IsGenericType: true} && (parent.GetGenericTypeDefinition() == typeof(NodeView<>) || parent.GetGenericTypeDefinition() == typeof(DataGraphView<>))){
//Get the generic type of this type
//Add this type to the dictionary
Debug.Log($"Find a component named {type} and its parent is {parent}" );
FromGenericToSpecific.Add(parent, type);
}
//Register Node View And Graph View via its parent class
SetNodeComponentAttribute(type);
//Register Node Data by GraphUsageAttribute.
SetGraphUsageAttribute(type);
}
}
}
}
private void SetGraphUsageAttribute(Type type){
foreach (var attribute in type.GetCustomAttributes(typeof(GraphUsageAttribute), true)){
var parent = type.BaseType;
if (typeof(NodeData).IsAssignableFrom(type.BaseType)){
//Check if GraphDataUsage dictionary has GraphDataType of attribute
if (attribute is GraphUsageAttribute attributeCasted){
if (GraphDataUsage.ContainsKey(attributeCasted.GraphDataType)){
GraphDataUsage[attributeCasted.GraphDataType].Add(type);
}
else{
GraphDataUsage.Add(attributeCasted.GraphDataType, new List<Type>{type});
}
}
}
}
}
private void SetNodeComponentAttribute(Type type){
foreach (var attribute in type.GetCustomAttributes(typeof(NodeComponentAttribute), false)){
//fetch this type 's parent class
var parent = type.BaseType;
//Check if this type is a generic type and is a generic type of NodeView or DataGraphView
if (parent is{IsGenericType: true} && (parent.GetGenericTypeDefinition() == typeof(NodeView<>) ||
parent.GetGenericTypeDefinition() == typeof(DataGraphView<>))){
//Get the generic type of this type
//Add this type to the dictionary
Debug.Log($"Find a component named {type} and its parent is {parent}");
FromGenericToSpecific.Add(parent, type);
}
//TODO Note that a node component only applied to a specific type of editor,so ,same GraphView could behave differently in different editor.it's a todo feature.
}
}
}
//Outer wrapper for the singleton class
public static class NodeEditorExtensions{
public static T CreateInstance<T>(){
Debug.Log($"Create A instance of {typeof(T)}");
@ -50,5 +92,37 @@ namespace TNode.Cache{
var implementedType = NodeEditorSingleton.Instance.FromGenericToSpecific[typeof(T)] as T;
return (T)implementedType!=null;
}
public static List<Type> GetGraphDataUsage(Type t){
if (NodeEditorSingleton.Instance.GraphDataUsage.ContainsKey(t)){
return NodeEditorSingleton.Instance.GraphDataUsage[t];
}
return new List<Type>();
}
public static object CreateNodeViewFromNodeType<T>() where T:NodeData,new(){
//Check specific derived type exists or not.
var type = typeof(NodeView<T>);
if (NodeEditorSingleton.Instance.FromGenericToSpecific.ContainsKey(type)){
var implementedType = NodeEditorSingleton.Instance.FromGenericToSpecific[type];
var instance = (NodeView<T>)Activator.CreateInstance(implementedType);
return instance;
}
else{
return new DefaultNodeView();
}
}
public static object CreateNodeViewFromNodeType(Type t){
//Check the generic type of NodeView by t
var type = typeof(NodeView<>).MakeGenericType(t);
if (NodeEditorSingleton.Instance.FromGenericToSpecific.ContainsKey(type)){
var implementedType = NodeEditorSingleton.Instance.FromGenericToSpecific[type];
var instance = Activator.CreateInstance(implementedType);
return instance;
}
else{
return new DefaultNodeView();
}
}
}
}

@ -0,0 +1,8 @@
using TNode.BaseViews;
using TNode.Models;
namespace TNode.Editor{
public class DefaultNodeView:NodeView<NodeData>{
}
}

@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 30bf0ad9c92f4bebae1a838bafd71c06
timeCreated: 1656401737

@ -52,7 +52,10 @@ namespace TNode.Editor{
evt.menu.AppendAction("Create Node", dma => {
var dmaPos = dma.eventInfo.mousePosition+editorPosition;
SearchWindowContext searchWindowContext = new SearchWindowContext(dmaPos,200,200);
SearchWindow.Open(searchWindowContext, ScriptableObject.CreateInstance<SearchWindowProvider>());
var searchWindow = CreateInstance<SearchWindowProvider>();
searchWindow.Setup(typeof(T),_graphView);
Debug.Log(searchWindow);
SearchWindow.Open(searchWindowContext, searchWindow);
});
});
}
@ -78,7 +81,7 @@ namespace TNode.Editor{
{
string path = EditorUtility.SaveFilePanel("Save Graph", "", "", "asset");
if (path.Length != 0){
//Create a new asset file with type of T
//Create a new asset file with type of GraphDataType
T asset = ScriptableObject.CreateInstance<T>();
AssetDatabase.CreateAsset(asset, path);
}

@ -8,7 +8,7 @@ namespace TNode.Editor.Inspector{
public class DefaultInspectorItemFactory{
public InspectorItem<T> Create<T>(){
//Check type of T
//Check type of GraphDataType
var hasSpecificType = NodeEditorExtensions.HasSpecificType<InspectorItem<T>>();
if (hasSpecificType){
return NodeEditorExtensions.CreateInstance<InspectorItem<T>>();

@ -23,6 +23,8 @@ namespace TNode.Editor.Inspector{
}
public NodeInspector(){
var visualTreeAsset = Resources.Load<VisualTreeAsset>("NodeInspector");
Debug.Log(visualTreeAsset);
ConstructWindowBasicSetting();
BuildWindow(visualTreeAsset);
}

@ -1,18 +1,50 @@
using System.Collections.Generic;
using System;
using System.Collections.Generic;
using TNode.BaseViews;
using TNode.Cache;
using TNode.Models;
using UnityEditor.Experimental.GraphView;
using UnityEngine;
using UnityEngine.UIElements;
namespace TNode.Editor{
public class SearchWindowProvider:ScriptableObject,ISearchWindowProvider{
private Type _graphType;
private GraphView _graphView;
public void Setup(Type graph,GraphView graphView){
_graphType = graph;
_graphView = graphView;
}
public List<SearchTreeEntry> CreateSearchTree(SearchWindowContext context){
var list = new List<SearchTreeEntry>();
list.Add(new SearchTreeGroupEntry(new GUIContent("Add New Node"), 0));
list.Add(new SearchTreeGroupEntry(new GUIContent("Add Placemat"), 0));
var nodeDataTypes = NodeEditorExtensions.GetGraphDataUsage(_graphType);
var list = new List<SearchTreeEntry>{
new SearchTreeGroupEntry(new GUIContent("Add New Node"), 0),
};
//TODO a node icon shall be given by some way
Texture2D icon = new Texture2D(2,2);
foreach (var nodeDataType in nodeDataTypes){
Debug.Log(nodeDataType.Name);
list.Add(new SearchTreeEntry(new GUIContent($" {nodeDataType.Name} ",icon)){
level = 1,
userData = nodeDataType,
});
}
return list;
}
public bool OnSelectEntry(SearchTreeEntry SearchTreeEntry, SearchWindowContext context){
var userData = SearchTreeEntry.userData;
if (userData is Type type){
var nodeView = NodeEditorExtensions.CreateNodeViewFromNodeType(type) as GraphElement;
_graphView.AddElement(nodeView);
return true;
}
return false;
}
public SearchWindowProvider(){
}
}
}

@ -1,3 +0,0 @@
fileFormatVersion: 2
guid: ab3bb3578bf34dafad6ff9fb71f040e1
timeCreated: 1655794910

@ -1,8 +0,0 @@
using Dialogue;
using TNode.Attribute;
namespace TNode.TNodeSample{
}

@ -1,3 +0,0 @@
fileFormatVersion: 2
guid: a7d4101454c84539b936140f3b54a3a6
timeCreated: 1655794926

@ -1,15 +0,0 @@
using Dialogue;
using TNode.Attribute;
using TNode.Models;
using UnityEditor.Experimental.GraphView;
namespace TNode.TNodeSample{
public class NodeDataTest:NodeData{
[InputPort(typeof(NodeLink),Port.Capacity.Multi)]
private float _floatInput;
public NodeDataTest(string name):base(){
}
}
}

@ -1,3 +0,0 @@
fileFormatVersion: 2
guid: 2d66df6e04694c51818042134869583f
timeCreated: 1655794954
Loading…
Cancel
Save