feature:blackboard support array or list as exposed attribute

main
taoria 3 years ago
parent 5659d24d33
commit a2efbc4bad
  1. 1
      TNode/TNodeCore/Editor/Blackboard/IBlackboardView.cs
  2. 3
      TNode/TNodeCore/Editor/DeveloperHelper.meta
  3. 66
      TNode/TNodeCore/Editor/DeveloperHelper/CleanMissingTypeHelper.cs
  4. 3
      TNode/TNodeCore/Editor/DeveloperHelper/CleanMissingTypeHelper.cs.meta
  5. 6
      TNode/TNodeCore/Editor/EditorPersistence/GraphEditorData.cs
  6. 4
      TNode/TNodeCore/Editor/GraphEditor.cs
  7. 1
      TNode/TNodeCore/Editor/NodeGraphView/IBaseDataGraphView.cs
  8. 1
      TNode/TNodeCore/Editor/Serialization/BlackboardDataWrapper.cs
  9. 32
      TNode/TNodeCore/Runtime/Components/RuntimeGraph.cs
  10. 11
      TNode/TNodeCore/Runtime/DataWrapper.cs
  11. 2
      TNode/TNodeCore/Runtime/Models/BlackboardData.cs
  12. 30
      TNode/TNodeCore/Runtime/Models/BlackboardDragNodeData.cs
  13. 4
      TNode/TNodeCore/Runtime/Models/GraphData.cs
  14. 16
      TNode/TNodeCore/Runtime/RuntimeCache/RuntimeCache.cs
  15. 44
      TNode/TNodeGraphViewImpl/Editor/GraphBlackboard/BlackboardDataEntry.cs
  16. 3
      TNode/TNodeGraphViewImpl/Editor/GraphBlackboard/BlackboardDataEntry.cs.meta
  17. 117
      TNode/TNodeGraphViewImpl/Editor/GraphBlackboard/DefaultGraphBlackboardView.cs
  18. 11
      TNode/TNodeGraphViewImpl/Editor/GraphBlackboard/GraphBlackboardView.cs
  19. 29
      TNode/TNodeGraphViewImpl/Editor/NodeGraphView/DataGraphView.cs
  20. 24
      TNode/TNodeGraphViewImpl/Editor/NodeViews/DragNodeView.cs
  21. 12
      TNode/TNodeGraphViewImpl/Editor/Resources/BlackboardDataEntry.uss
  22. 3
      TNode/TNodeGraphViewImpl/Editor/Resources/BlackboardDataEntry.uss.meta
  23. 32
      TNode/TNodeGraphViewImpl/Editor/Search/BlackboardSearchWindowProvider.cs

@ -10,6 +10,7 @@ namespace TNodeCore.Editor.Blackboard{
public void AddItem();
void Setup(IBaseDataGraphView graphView,EditorWindow ownerWindow);
void NotifyUpdate();
}
public interface IBlackboardView<T> : IBlackboardView where T : BlackboardData{

@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 7d20d1aa36604785a19ec27375f3becb
timeCreated: 1659420802

@ -0,0 +1,66 @@
using System.Text;
using UnityEditor;
using UnityEngine;
using UnityEngine.SceneManagement;
namespace TNodeCore.Editor.DeveloperHelper{
public class CleanMissingTypeHelper
{
[MenuItem("TNode/CleanMissingType/CleanScriptObjects")]
public static void CleanMissingTypesOnScriptableObjects()
{
var report = new StringBuilder();
var guids = AssetDatabase.FindAssets("t:ScriptableObject", new[] {"Assets"});
foreach (string guid in guids)
{
var path = AssetDatabase.GUIDToAssetPath(guid);
Object obj = AssetDatabase.LoadMainAssetAtPath(path);
if (obj != null)
{
if (SerializationUtility.ClearAllManagedReferencesWithMissingTypes(obj))
{
report.Append("Cleared missing types from ").Append(path).AppendLine();
}
else
{
report.Append("No missing types to clear on ").Append(path).AppendLine();
}
}
}
Debug.Log(report.ToString());
}
[MenuItem("TNode/CleanMissingType/CleanSceneGameObjects")]
public static void CleanMissingTypesOnGameObjects(){
var report = new StringBuilder();
SceneManager.GetActiveScene().GetRootGameObjects();
foreach (GameObject root in SceneManager.GetActiveScene().GetRootGameObjects()){
foreach (var o in root.transform){
if (SerializationUtility.ClearAllManagedReferencesWithMissingTypes(o as Object))
{
report.Append("Cleared missing types from ").Append(root.name).AppendLine();
}
else
{
report.Append("No missing types to clear on ").Append(root.name).AppendLine();
}
}
if (SerializationUtility.ClearAllManagedReferencesWithMissingTypes(root))
{
report.Append("Cleared missing types from ").Append(root.name).AppendLine();
}
else
{
report.Append("No missing types to clear on ").Append(root.name).AppendLine();
}
}
Debug.Log(report.ToString());
}
}
}

@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: d24a02b78de74a29a32e095205fe977c
timeCreated: 1659420813

@ -17,8 +17,12 @@ namespace TNodeCore.Editor.EditorPersistence{
public IDataGraphView<T> GetGraphView<T> () where T:GraphData{
switch (graphImplType){
case GraphImplType.GraphViewImpl:
case GraphImplType.GraphViewImpl:{
return (IDataGraphView<T>)GraphViewImplCreator.Invoke(typeof(T));
}
case GraphImplType.GraphToolsFoundationImpl:
throw new NotImplementedException();
default:

@ -81,7 +81,11 @@ namespace TNodeCore.Editor{
}
private void BuildGraphView(){
GraphView = graphEditorData.GetGraphView<T>();
GraphView.Owner = this;
rootVisualElement.Add((VisualElement)GraphView);
GraphView.AfterEditorLoadGraphView();
((VisualElement)GraphView).StretchToParentSize();
}

@ -29,5 +29,6 @@ namespace TNodeCore.Editor.NodeGraphView{
void NotifyRuntimeUpdate();
public Action AfterRuntimeGraphUpdate{ get; set; }
void AfterEditorLoadGraphView();
}
}

@ -3,6 +3,5 @@ using TNodeCore.Runtime.Models;
namespace TNodeCore.Editor.Serialization{
public class BlackboardDataWrapper:DataWrapper<BlackboardDataWrapper,BlackboardData>{
}
}

@ -2,6 +2,7 @@
using System.Collections.Generic;
using System.Linq;
using TNodeCore.Runtime.Models;
using UnityEditor;
using UnityEngine;
namespace TNodeCore.Runtime.Components{
@ -13,7 +14,6 @@ namespace TNodeCore.Runtime.Components{
/// <summary>
/// Runtime copy of scene node data to hold references to scene objects
/// </summary>
public List<SceneNodeData> sceneNodes;
/// <summary>
/// Map of node id to runtime node
@ -264,21 +264,25 @@ namespace TNodeCore.Runtime.Components{
#region build scene node data
#if UNITY_EDITOR
public void BuildSceneNodePersistentData(SceneNodeData sceneNodeData){
var tr = transform.Find("PersistentData");
GameObject go;
if (tr == null){
go = new GameObject("PersistentData");
go.transform.SetParent(transform);
go.AddComponent<SceneDataPersistent>();
}
go = tr.gameObject;
var persistentData = go.GetComponent<SceneDataPersistent>();
var persistentData = transform.Find("PersistentData").GetComponent<SceneDataPersistent>();
persistentData.SceneNodeDataDictionary.Add(sceneNodeData.id,sceneNodeData);
}
public SceneDataPersistent CreateSceneNodePersistentGameObject(){
var go = new GameObject("PersistentData");
go.transform.SetParent(transform);
return go.AddComponent<SceneDataPersistent>();
}
public void BuildSceneNode(){
var fetchedSceneNode = graphData.NodeDictionary.Values.Where(x => x is SceneNodeData and not BlackboardDragNodeData);
var scenePersistent = transform.Find("PersistentData").GetComponent<SceneDataPersistent>();
var fetchedSceneNode = graphData.NodeDictionary.Values.Where(x => x is SceneNodeData and not BlackboardDragNodeData).ToArray();
if (!fetchedSceneNode.Any()) return;
var scenePersistent = transform.Find("PersistentData")?.GetComponent<SceneDataPersistent>();
if(scenePersistent == null){
scenePersistent = CreateSceneNodePersistentGameObject();
}
foreach (var nodeData in fetchedSceneNode){
if (scenePersistent.SceneNodeDataDictionary.ContainsKey(nodeData.id)){
var sceneNodeData = scenePersistent.SceneNodeDataDictionary[nodeData.id];
@ -396,6 +400,7 @@ namespace TNodeCore.Runtime.Components{
}
public class SceneDataPersistent:MonoBehaviour,ISerializationCallbackReceiver{
[NonSerialized]
public readonly Dictionary<string,SceneNodeData> SceneNodeDataDictionary = new();
@ -404,6 +409,7 @@ namespace TNodeCore.Runtime.Components{
public void OnBeforeSerialize(){
sceneNodeData.Clear();
foreach(var node in SceneNodeDataDictionary.Values){
sceneNodeData.Add(node);
@ -416,7 +422,7 @@ namespace TNodeCore.Runtime.Components{
}
}
}
public enum ProcessingStrategy{
BreadthFirst,
DepthFirst

@ -36,10 +36,19 @@ namespace TNodeCore.Runtime{
var fieldInfo = data.GetType().GetField(path);
return fieldInfo.GetValue(data);
}
public KeyValuePair<string,object>[] GetAllFieldValue(){
var fieldInfos = data.GetType().GetFields();
var list = new List<KeyValuePair<string,object>>();
foreach (var fieldInfo in fieldInfos){
list.Add(new KeyValuePair<string, object>(fieldInfo.Name,fieldInfo.GetValue(data)));
}
return list.ToArray();
}
public virtual TData GetData(){
return data;
}
public static implicit operator TData(DataWrapper<TWrapper,TData> wrapper){
if (wrapper == null)
return default(TData);

@ -10,5 +10,7 @@ namespace TNodeCore.Runtime.Models{
public object Clone(){
return this.MemberwiseClone();
}
}
}

@ -2,19 +2,45 @@
using TNodeCore.Runtime.Attributes;
using TNodeCore.Runtime.Attributes.Ports;
using TNodeCore.Runtime.RuntimeCache;
using UnityEngine;
namespace TNodeCore.Runtime.Models{
[Serializable]
[InternalUsage]
public class BlackboardDragNodeData:SceneNodeData{
public string BlackDragData{
get => blackDragData;
set{
blackDragData = value;
if (blackDragData.Contains('.')){
isListElement = true;
}
}
}
public string blackDragData;
/// <summary>
/// it's very hacky way to get blackboard data ,even when the value is null,type info is not null!
/// </summary>
/// TODO : The type handling in a safer way in the future
[Output("",PortNameHandling.MemberType,TypeHandling.Implemented)]
public object Value => BlackboardData.GetValue(blackDragData);
public object Value{
get{
if (!isListElement){
return BlackboardData.GetValue(BlackDragData);
}
else{
var split = BlackDragData.Split('.');
Debug.Log(blackDragData);
var index = int.Parse(split[1]);
return BlackboardData.GetListValue(split[0],index);
}
}
}
public bool isListElement=false;
public BlackboardDragNodeData(){
}

@ -1,10 +1,12 @@
using System;
using System.Collections.Generic;
using UnityEditor;
using UnityEngine;
namespace TNodeCore.Runtime.Models{
[Serializable]
public class GraphData:ScriptableObject,ISerializationCallbackReceiver{
[NonSerialized]
public Dictionary<string,NodeData> NodeDictionary = new Dictionary<string,NodeData>();
[SerializeReference]
@ -28,8 +30,6 @@ namespace TNodeCore.Runtime.Models{
public void OnBeforeSerialize(){
nodeList.Clear();
foreach(var node in NodeDictionary.Values){
nodeList.Add(node);

@ -1,4 +1,5 @@
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
@ -269,6 +270,21 @@ namespace TNodeCore.Runtime.RuntimeCache{
var method = dic.ContainsKey(path) ? dic[path] : null;
return method?.Invoke(data);
}
public static object GetListValue(this IModel data,string path,int index,Type type=null){
if(!RuntimeCache.Instance.CachedDelegatesForGettingValue.ContainsKey(type??data.GetType())){
return null;
}
var dic = RuntimeCache.Instance.CachedDelegatesForGettingValue[type ?? data.GetType()];
var method = dic.ContainsKey(path) ? dic[path] : null;
if(method == null){
return null;
}
var list = method.Invoke(data) as IList;
if(list == null){
return null;
}
return list[index];
}
public static void SetValue<T>(this IModel data,string path,T value,Type type=null){
var method = RuntimeCache.Instance.CachedDelegatesForSettingValue[type??data.GetType()][path];

@ -0,0 +1,44 @@
using System;
using System.Collections;
using UnityEditor.Experimental.GraphView;
using UnityEngine;
using UnityEngine.UIElements;
namespace TNode.TNodeGraphViewImpl.Editor.GraphBlackboard{
public class BlackboardDataEntry:GraphElement{
public Type propertyType;
public string propertyPath;
public BlackboardDataEntry(Type type){
propertyType = type;
if (typeof(Component).IsAssignableFrom(propertyType)){
this.AddToClassList("typeComponent");
}
if (typeof(GameObject).IsAssignableFrom(propertyType)){
this.AddToClassList("gameObject");
}
if (typeof(Vector2).IsAssignableFrom(propertyType)){
this.AddToClassList("vector");
}
if (typeof(Vector2Int).IsAssignableFrom(propertyType)){
this.AddToClassList("vector");
}
if (typeof(IList).IsAssignableFrom(propertyType)){
this.AddToClassList("list");
}
this.capabilities |= Capabilities.Selectable | Capabilities.Deletable | Capabilities.Droppable | Capabilities.Renamable;
this.AddManipulator(new SelectionDropper());
var styleSheet = Resources.Load<StyleSheet>("BlackboardDataEntry");
this.styleSheets.Add(styleSheet);
this.RegisterCallback<MouseEnterEvent>((evt) => {
style.borderBottomColor=style.borderRightColor=style.borderLeftColor=style.borderTopColor=new Color(1,1,1,1);
});
this.RegisterCallback<MouseLeaveEvent>((evt) => {
style.borderBottomColor = style.borderRightColor =
style.borderLeftColor = style.borderTopColor = StyleKeyword.Null;
});
}
}
}

@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 1c0d8e24a45b4ed78454d17047f6cf7e
timeCreated: 1659416220

@ -1,4 +1,5 @@
using System.Collections;
using System;
using System.Collections;
using System.Reflection;
using TNode.TNodeGraphViewImpl.Editor.Search;
using TNodeCore.Editor.NodeGraphView;
@ -14,6 +15,7 @@ using UnityEngine.UIElements;
namespace TNode.TNodeGraphViewImpl.Editor.GraphBlackboard{
[ViewComponent]
public class DefaultGraphBlackboardView:GraphBlackboardView<BlackboardData>{
public DefaultGraphBlackboardView():base(){
//the label and the field gap smaller
styleSheets.Add( Resources.Load<StyleSheet>("GraphViewPropertyField"));
@ -21,44 +23,113 @@ namespace TNode.TNodeGraphViewImpl.Editor.GraphBlackboard{
}
protected override void UpdateBlackboard(BlackboardData data){
if (data == null) return;
this.Clear();
var serializedObject = new SerializedObject((BlackboardDataWrapper)data);
var currentGraphView = graphView as IBaseDataGraphView;
var isRuntimeGraph = currentGraphView?.IsRuntimeGraph ?? false;
var blackboardGlobalSection = new BlackboardSection{
title = "Global Data"
};
Add(blackboardGlobalSection);
foreach (var field in data.GetType()
.GetFields(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance)){
//if the field is MonoBehaviour,add a property field for blackboard
//skip if the field is a list or Ilist
if (!typeof(IList).IsAssignableFrom(field.FieldType)){
VisualElement visualElement = new VisualElement();
var propertyField = new BlackboardField(new BlackboardProperty.BlackboardProperty(field.Name,field.FieldType));
var foldoutData = new Foldout{
text = ObjectNames.NicifyVariableName(field.Name)
};
var drawer = new GraphBlackboardPropertyField(serializedObject.FindProperty("data").FindPropertyRelative(field.Name),isRuntimeGraph);
drawer.Bind(serializedObject);
foldoutData.Add(drawer);
visualElement.Add(propertyField);
visualElement.Add(foldoutData);
Add(visualElement);
if (!typeof(IList).IsAssignableFrom(field.FieldType)&&!field.FieldType.IsArray){
CreateBlackboardDataEntry(field, serializedObject, isRuntimeGraph, blackboardGlobalSection);
}
else{
var blackboardList = new BlackboardSection{
title = field.Name
};
this.Add(blackboardList);
var foldout = new Foldout{
text = field.Name,
};
blackboardList.Add(foldout);
Add(blackboardList);
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);
for (var i = 0; i < array.Length; i++){
CreateBlackboardDataEntryForListItem(field, serializedObject, isRuntimeGraph, blackboardList, i);
}
}
}
}
addItemRequested = (sender) => {
var res = ScriptableObject.CreateInstance<BlackboardSearchWindowProvider>();
addItemRequested += (sender) => {
var res = ScriptableObject.CreateInstance<BlackboardSearchWindowProvider>();
//Get right top corner of the blackboard
var blackboardPos = GetPosition().position+OwnerWindow.position.position;
var searchWindowContext = new SearchWindowContext(blackboardPos,200,200);
//Call search window
res.Setup(Owner.GetGraphData().GetType(),Owner,OwnerWindow);
SearchWindow.Open(searchWindowContext, res);
//Get right top corner of the blackboard
var blackboardPos = GetPosition().position+OwnerWindow.position.position;
var searchWindowContext = new SearchWindowContext(blackboardPos,200,200);
//Call search window
res.Setup(Owner.GetGraphData().GetType(),Owner,OwnerWindow,this);
SearchWindow.Open(searchWindowContext, res);
};
}
private static void CreateBlackboardDataEntryForListItem(FieldInfo field, SerializedObject serializedObject,
bool isRuntimeGraph,
BlackboardSection blackboardSection, int index){
var property =serializedObject.FindProperty("data").FindPropertyRelative(field.Name).GetArrayElementAtIndex(index);
BlackboardDataEntry entry = new BlackboardDataEntry(field.FieldType){
propertyPath = field.Name+"."+index,
};
var drawer =
new GraphBlackboardPropertyField(property,
isRuntimeGraph);
drawer.Bind(serializedObject);
entry.Add(drawer);
var container = blackboardSection.Q<Foldout>();
container.Add(entry);
}
private static void CreateBlackboardDataEntry(FieldInfo field, SerializedObject serializedObject, bool isRuntimeGraph,
BlackboardSection blackboardSection){
BlackboardDataEntry entry = new BlackboardDataEntry(field.FieldType){
propertyPath = field.Name
};
//var propertyField = new BlackboardField(new BlackboardProperty.BlackboardProperty(field.Name,field.FieldType));
var foldoutData = new Foldout{
};
var drawer =
new GraphBlackboardPropertyField(serializedObject.FindProperty("data").FindPropertyRelative(field.Name),
isRuntimeGraph);
drawer.Bind(serializedObject);
foldoutData.Add(drawer);
entry.Add(foldoutData);
blackboardSection.Add(entry);
Label visualElementOverlapFoldoutLabel = new Label(ObjectNames.NicifyVariableName(field.Name)){
style ={
//put the label in the position that overlaps the foldout's right side to prevent click
position = Position.Absolute,
left = 20,
alignContent = new StyleEnum<Align>(Align.Center),
justifyContent = new StyleEnum<Justify>(Justify.Center),
unityTextAlign = new StyleEnum<TextAnchor>(TextAnchor.UpperCenter),
marginTop = 0,
paddingTop = 0
}
};
entry.Add(visualElementOverlapFoldoutLabel);
visualElementOverlapFoldoutLabel.BringToFront();
}
}
}

@ -14,11 +14,18 @@ namespace TNode.TNodeGraphViewImpl.Editor.GraphBlackboard{
protected EditorWindow OwnerWindow;
private T _data;
public void AddItem(){
}
public void Setup(IBaseDataGraphView graphView,EditorWindow ownerWindow){
Owner = graphView;
OwnerWindow = ownerWindow;
}
public void NotifyUpdate(){
UpdateBlackboard(GetBlackboardData());
}
public new void SetPosition(Rect rect){
@ -44,8 +51,6 @@ namespace TNode.TNodeGraphViewImpl.Editor.GraphBlackboard{
Data = (T) data;
}
public void AddItem(){
}
}
}

@ -3,6 +3,7 @@ using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using TNode.TNodeGraphViewImpl.Editor.Cache;
using TNode.TNodeGraphViewImpl.Editor.GraphBlackboard;
using TNode.TNodeGraphViewImpl.Editor.Inspector;
using TNode.TNodeGraphViewImpl.Editor.NodeViews;
using TNode.TNodeGraphViewImpl.Editor.Search;
@ -34,6 +35,8 @@ namespace TNode.TNodeGraphViewImpl.Editor.NodeGraphView{
private IBlackboardView _blackboard;
private bool _runtimeGraphUpdate;
public T Data{
get{ return _data; }
set{
@ -195,8 +198,14 @@ namespace TNode.TNodeGraphViewImpl.Editor.NodeGraphView{
private void OnInit(){
ConstructDefaultBehaviour();
OnGraphViewCreate();
CheckDataAfterInit();
OnGraphViewCreate();
}
public virtual void AfterEditorLoadGraphView(){
}
protected void CreateMenu(){
@ -247,11 +256,22 @@ namespace TNode.TNodeGraphViewImpl.Editor.NodeGraphView{
//Make a constructor of BlackboardDragNodeData<field.PropertyType > by reflection
var dragNodeData = NodeCreator.InstantiateNodeData<BlackboardDragNodeData>();
dragNodeData.BlackboardData = GetBlackboardData();
dragNodeData.blackDragData = field.BlackboardProperty.PropertyName;
dragNodeData.BlackDragData = field.BlackboardProperty.PropertyName;
AddTNode(dragNodeData,new Rect(evt.mousePosition,new Vector2(200,200)));
}
}
var blackboardEntries = data.OfType<BlackboardDataEntry>();
foreach (var selectable in blackboardEntries){
if(selectable is { } entry) {
//Make a constructor of BlackboardDragNodeData<field.PropertyType > by reflection
var dragNodeData = NodeCreator.InstantiateNodeData<BlackboardDragNodeData>();
dragNodeData.BlackboardData = GetBlackboardData();
dragNodeData.BlackDragData = entry.propertyPath;
AddTNode(dragNodeData,new Rect(evt.mousePosition,new Vector2(200,200)));
}
}
}
}
@ -261,6 +281,7 @@ namespace TNode.TNodeGraphViewImpl.Editor.NodeGraphView{
DragAndDrop.visualMode = DragAndDropVisualMode.Move;
//high light the
}
}
#endregion
@ -523,7 +544,7 @@ namespace TNode.TNodeGraphViewImpl.Editor.NodeGraphView{
public void CreateBlackboard(){
_blackboard = NodeEditorExtensions.CreateBlackboardWithGraphData(typeof(T));
_blackboard.Setup(this,Owner);
Debug.Log(Owner);
var castedBlackboard = _blackboard as Blackboard;
Add(castedBlackboard);
Rect blackboardPos = new Rect(0,0,300,700);

@ -21,13 +21,25 @@ namespace TNode.TNodeGraphViewImpl.Editor.NodeViews{
var blackboard = obj.BlackboardData;
BlackboardDataWrapper blackboardWrapper = (BlackboardDataWrapper)blackboard;
var serializedData = new SerializedObject(blackboardWrapper);
var serializedProperty = serializedData.FindProperty("data").FindPropertyRelative(obj.blackDragData);
label.text = ObjectNames.NicifyVariableName(obj.blackDragData);
var arrayElement = obj.isListElement;
SerializedProperty serializedProperty = null;
if (arrayElement){
var part = obj.BlackDragData.Split('.');
serializedProperty = serializedData.FindProperty("data").FindPropertyRelative(part[0]).GetArrayElementAtIndex(int.Parse(part[1]));
}
else{
serializedProperty = serializedData.FindProperty("data").FindPropertyRelative(obj.BlackDragData);
}
label.text = ObjectNames.NicifyVariableName(obj.BlackDragData);
//Get serialized property's icon
var icon = AssetPreview.GetMiniThumbnail(serializedProperty.boxedValue as UnityEngine.Object);
Texture2D icon = null;
if (serializedProperty.boxedValue is Object value){
icon = AssetPreview.GetMiniThumbnail(value);
}
else{
icon = AssetPreview.GetMiniTypeThumbnail(serializedProperty.boxedValue.GetType());
}
label.parent.Add(new Image(){
image = icon
});

@ -0,0 +1,12 @@
BlackboardDataEntry{
border-width: 1px;
border-color: aqua;
}
.typeComponent{
border-width: 1px;
border-color: rgba(201, 249, 116, 255);
}
.vector{
border-width: 1px;
border-color: rgba(0.788, 0.969, 0.455, 1.000);
}

@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 9e945d200b8b4056bcf0adeb55f52cc8
timeCreated: 1659416935

@ -1,16 +1,20 @@
using System;
using System.Collections;
using System.Collections.Generic;
using TNode.TNodeGraphViewImpl.Editor.GraphBlackboard;
using TNodeCore.Editor.Blackboard;
using TNodeCore.Editor.NodeGraphView;
using UnityEditor;
using UnityEditor.Experimental.GraphView;
using UnityEngine;
using Object = UnityEngine.Object;
namespace TNode.TNodeGraphViewImpl.Editor.Search{
public class BlackboardSearchWindowProvider:ScriptableObject,ISearchWindowProvider{
private Type _graphType;
private IBaseDataGraphView _graphView;
private EditorWindow _editor;
private IBlackboardView _blackboard;
private struct InternalSearchTreeUserData{
public IList List;
@ -38,31 +42,49 @@ namespace TNode.TNodeGraphViewImpl.Editor.Search{
List = field.GetValue(blackboardData) as IList,
Type = field.FieldType.GetGenericArguments()[0]
}
});
}
}
if (field.FieldType.IsArray){
list.Add(new SearchTreeEntry(new GUIContent(field.Name,icon)){
level = 1,
userData = new InternalSearchTreeUserData(){
List = field.GetValue(blackboardData) as Array,
Type = field.FieldType.GetElementType()
}
});
}
}
Debug.Log($"{list.Count}");
return list;
}
public bool OnSelectEntry(SearchTreeEntry SearchTreeEntry, SearchWindowContext context){
var userData = SearchTreeEntry.userData;
if (userData is InternalSearchTreeUserData){
var list = ((InternalSearchTreeUserData) userData).List;
Debug.Log(list);
var type = ((InternalSearchTreeUserData) userData).Type;
var newItem = Activator.CreateInstance(type);
list?.Add(newItem);
if (!typeof(Object).IsAssignableFrom(type)){
var newItem = Activator.CreateInstance(type);
list?.Add(newItem);
}
else{
var newItem = EditorUtility.InstanceIDToObject(EditorGUIUtility.GetObjectPickerControlID());
list?.Add(newItem);
}
_blackboard.NotifyUpdate();
return true;
}
return false;
}
public void Setup(Type graph,IBaseDataGraphView graphView,EditorWindow editor){
public void Setup(Type graph,IBaseDataGraphView graphView,EditorWindow editor,IBlackboardView blackboard){
_graphType = graph;
_graphView = graphView;
_editor = editor;
_blackboard = blackboard;
}
}

Loading…
Cancel
Save