fix:Node create at correct position

main
taoria 3 years ago
parent c88caec24d
commit 8d6792ae58
  1. 15
      README.md
  2. 2
      TNode/TNodeCore/Runtime/Attributes/GraphUsageAttribute.cs
  3. 10
      TNode/TNodeCore/Runtime/Models/BlackboardData.cs
  4. 7
      TNode/TNodeCore/Runtime/Models/IModel.cs
  5. 17
      TNode/TNodeCore/Runtime/Models/Model.cs
  6. 0
      TNode/TNodeCore/Runtime/Models/Model.cs.meta
  7. 7
      TNode/TNodeCore/Runtime/Models/NodeData.cs
  8. 14
      TNode/TNodeCore/Runtime/RuntimeCache/RuntimeCache.cs
  9. 2
      TNode/TNodeGraphViewImpl/Editor/Cache/NodeEditorExtensions.cs
  10. 64
      TNode/TNodeGraphViewImpl/Editor/NodeGraphView/DataGraphView.cs
  11. 14
      TNode/TNodeGraphViewImpl/Editor/NodeViews/NodeView.cs
  12. 3
      TNode/TNodeGtfImpl/Editor.meta

@ -1,10 +1,10 @@
# T-Node
Node graph creation tool based on unity experimental graphview and if possible latter,GTF.
the main goal of the repo is to make graph creation easier and more intuitive.
Note **it's not usable and productive on current stage** and need a better
development .
and it's mainly for my own use now.
The tool separate its graph editor implementation and the graph creation logic.
@ -12,25 +12,24 @@ The tool separate its graph editor implementation and the graph creation logic.
currently under development
# Main Features
# Some Features
* Create graph script by the creator tool
* Create graph script a the creator tool
* Node creation based on specified type of graph
* Easy port creation via attribute
* Runtime graph
* Blackboard for runtime graph as exposed parameters
* Runtime graph execution
* An easy test mode (Runtime graph only)
* Scene object nodes hold scene objects
# Some To-dos
* Caching runtime state for faster execution
* Undo redo support
* Function as port
* Better blackboard support
* Circular dependency support for some situations such as FSM
* Edge colors customization
# Usage
No ,It's better not to use TNode at current stage until it's stable.
Not yet documented
### Convention

@ -4,7 +4,7 @@ using TNodeCore.Runtime.Models;
namespace TNodeCore.Runtime.Attributes{
/// <summary>
/// Use this attribute to claim the usage of a type derived IModel IModel
/// Use this attribute to claim the usage of a type derived Model Model
/// it can be applied to the same node multiple times.
/// <example>
/// [GraphUsage(DialogueGraph)]

@ -1,4 +1,5 @@
using System;
using UnityEngine;
namespace TNodeCore.Runtime.Models{
/// <summary>
@ -6,11 +7,10 @@ namespace TNodeCore.Runtime.Models{
/// </summary>
[Serializable]
public class BlackboardData:IModel,ICloneable{
public object Clone(){
return this.MemberwiseClone();
}
public class BlackboardData:Model,ICloneable{
}
}

@ -1,7 +0,0 @@
using System;
namespace TNodeCore.Runtime.Models{
public interface IModel:ICloneable{
}
}

@ -0,0 +1,17 @@
using System;
using UnityEngine;
using UnityEngine.Serialization;
namespace TNodeCore.Runtime.Models{
[Serializable]
public abstract class Model:ICloneable{
#if UNITY_EDITOR
public Rect positionInView;
#endif
public object Clone(){
var memberwiseClone = this.MemberwiseClone();
return memberwiseClone;
}
}
}

@ -12,7 +12,7 @@ namespace TNodeCore.Runtime.Models{
///
/// </summary>
[Serializable]
public class NodeData:IModel{
public class NodeData:Model{
public NodeData() : base(){
//Object Registration
@ -37,8 +37,7 @@ namespace TNodeCore.Runtime.Models{
}
#endif
public object Clone(){
return this.MemberwiseClone();
}
}
}

@ -64,8 +64,8 @@ namespace TNodeCore.Runtime.RuntimeCache{
get{ return _instance ??= new RuntimeCache(); }
}
//delegate return a value from a nodedata
public delegate object GetValueDelegate(IModel nodeData);
public delegate void SetValueDelegate(IModel nodeData,object value);
public delegate object GetValueDelegate(Model nodeData);
public delegate void SetValueDelegate(Model nodeData,object value);
@ -258,11 +258,11 @@ namespace TNodeCore.Runtime.RuntimeCache{
public static class RuntimeExtension{
//todo latter on i will try some way caching reflection more efficiently
public static T GetValue<T>(this IModel data,string path,Type type=null){
public static T GetValue<T>(this Model data,string path,Type type=null){
var method = RuntimeCache.Instance.CachedDelegatesForGettingValue[type??data.GetType()][path];
return (T) method.Invoke(data);
}
public static object GetValue(this IModel data, string path,Type type=null){
public static object GetValue(this Model data, string path,Type type=null){
if(!RuntimeCache.Instance.CachedDelegatesForGettingValue.ContainsKey(type??data.GetType())){
return null;
}
@ -270,7 +270,7 @@ 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){
public static object GetListValue(this Model data,string path,int index,Type type=null){
if(!RuntimeCache.Instance.CachedDelegatesForGettingValue.ContainsKey(type??data.GetType())){
return null;
}
@ -286,11 +286,11 @@ namespace TNodeCore.Runtime.RuntimeCache{
return list[index];
}
public static void SetValue<T>(this IModel data,string path,T value,Type type=null){
public static void SetValue<T>(this Model data,string path,T value,Type type=null){
var method = RuntimeCache.Instance.CachedDelegatesForSettingValue[type??data.GetType()][path];
method.Invoke(data,value);
}
public static void SetValue(this IModel data,string path,object value,Type type=null){
public static void SetValue(this Model data,string path,object value,Type type=null){
var method = RuntimeCache.Instance.CachedDelegatesForSettingValue[type??data.GetType()][path];
method.Invoke(data,value);
}

@ -89,7 +89,7 @@ namespace TNode.TNodeGraphViewImpl.Editor.Cache{
private void SetGraphUsageAttribute(Type type){
foreach (var attribute in type.GetCustomAttributes(typeof(GraphUsageAttribute), true)){
var parent = type.BaseType;
if (typeof(IModel).IsAssignableFrom(type.BaseType)){
if (typeof(Model).IsAssignableFrom(type.BaseType)){
//Check if GraphDataUsage dictionary has GraphDataType of attribute
if (typeof(NodeData).IsAssignableFrom(type)){

@ -98,15 +98,14 @@ namespace TNode.TNodeGraphViewImpl.Editor.NodeGraphView{
var res = DragAndDrop.objectReferences;
foreach (var obj in res){
if (obj is T graphData){
Data = graphData;
IsRuntimeGraph = false;
Data = graphData;
}
else{
if (obj is GameObject gameObject){
if (gameObject.GetComponent<RuntimeGraph>() != null){
if (gameObject.GetComponent<RuntimeGraph>().graphData != null){
_runtimeGraph = gameObject.GetComponent<RuntimeGraph>();
IsRuntimeGraph = true;
BuildRuntimeGraphBehaviour();
@ -114,7 +113,6 @@ namespace TNode.TNodeGraphViewImpl.Editor.NodeGraphView{
if(Data==null){
Debug.LogError($"Dragged a wrong graph data to editor,expected {typeof(T)} but got {gameObject.GetComponent<RuntimeGraph>().graphData.GetType()}");
}
}
}
}
@ -341,8 +339,7 @@ namespace TNode.TNodeGraphViewImpl.Editor.NodeGraphView{
}
private void AddPersistentNode(NodeData dataNode){
var nodePos = Owner.graphEditorData.graphElementsData.FirstOrDefault(x => x.guid == dataNode.id)?.pos ??
new Rect(0, 0, 200, 200);
var nodePos = dataNode.positionInView;
AddTNode(dataNode, nodePos);
}
//OnDataChanged event
@ -391,21 +388,21 @@ namespace TNode.TNodeGraphViewImpl.Editor.NodeGraphView{
}
public void SaveEditorData(GraphEditorData graphEditorData){
graphEditorData.graphElementsData?.Clear();
//iterator nodes
if (graphEditorData.graphElementsData == null){
graphEditorData.graphElementsData = new List<GraphElementEditorData>();
}
foreach (var node in this.nodes){
var nodeEditorData = new GraphElementEditorData{
pos = node.GetPosition(),
};
if (node is IBaseNodeView nodeView){
nodeEditorData.guid = nodeView.GetNodeData().id;
}
graphEditorData.graphElementsData.Add(nodeEditorData);
EditorUtility.SetDirty(graphEditorData);
}
// graphEditorData.graphElementsData?.Clear();
// //iterator nodes
// if (graphEditorData.graphElementsData == null){
// graphEditorData.graphElementsData = new List<GraphElementEditorData>();
// }
// foreach (var node in this.nodes){
// var nodeEditorData = new GraphElementEditorData{
// pos = node.GetPosition(),
// };
// if (node is IBaseNodeView nodeView){
// nodeEditorData.guid = nodeView.GetNodeData().id;
// }
// graphEditorData.graphElementsData.Add(nodeEditorData);
// EditorUtility.SetDirty(graphEditorData);
// }
}
public void SaveWithEditorData(GraphEditorData graphEditorData){
@ -499,8 +496,15 @@ namespace TNode.TNodeGraphViewImpl.Editor.NodeGraphView{
#region implement interfaces
public void AddTNode(NodeData nodeData, Rect rect){
if (NodeEditorExtensions.CreateNodeViewFromNodeType(nodeData.GetType()) is Node nodeView){
nodeView.SetPosition(rect);
//convert rect at graph space
var resPos = this.viewTransform.matrix.inverse.MultiplyPoint3x4(rect.position);
rect.position = resPos;
if(nodeView is IBaseNodeView nodeViewInterface){
nodeViewInterface.SetNodeData(nodeData);
}
AddElement(nodeView);
((IBaseNodeView)nodeView).InitializePosition(rect);
//Add a select callback to the nodeView
nodeView.RegisterCallback<MouseDownEvent>(evt => {
if (evt.clickCount == 1){
@ -510,14 +514,17 @@ namespace TNode.TNodeGraphViewImpl.Editor.NodeGraphView{
}
}
});
if(nodeView is IBaseNodeView nodeViewInterface){
nodeViewInterface.SetNodeData(nodeData);
}
_nodeDict.Add(nodeData.id, nodeView);
if(_nodeDict.ContainsKey(nodeData.id)==false)
_nodeDict.Add(nodeData.id, nodeView);
if (_data.NodeDictionary.ContainsKey(nodeData.id) == false){
Undo.RegisterCompleteObjectUndo(_data,"Node Creation");
_data.NodeDictionary.Add(nodeData.id,nodeData);
}
//register an callback ,when right click context menu
nodeView.RegisterCallback<ContextClickEvent>(evt => {
var menu = new GenericMenu();
@ -558,6 +565,13 @@ namespace TNode.TNodeGraphViewImpl.Editor.NodeGraphView{
}
public bool TestMode{ get; set; }
public override EventPropagation DeleteSelection(){
Undo.RegisterCompleteObjectUndo(_data,"Delete Selection");
var res = base.DeleteSelection();
ResetGraphView();
return res;
}
public void CreateBlackboard(){
_blackboard = NodeEditorExtensions.CreateBlackboardWithGraphData(typeof(T));

@ -184,6 +184,18 @@ namespace TNode.TNodeGraphViewImpl.Editor.NodeViews{
Refresh();
}
public override void SetPosition(Rect newPos){
var graphView = (GraphView)BaseDataGraphView;
//Cast newPos s position to global space
var globalPos = graphView.contentViewContainer.LocalToWorld(newPos.position);
_data.positionInView.position = globalPos;
base.SetPosition(newPos);
}
public void InitializePosition(Rect pos){
base.SetPosition(pos);
}
public void Refresh(){
title = _data.nodeName;
}
@ -195,6 +207,8 @@ namespace TNode.TNodeGraphViewImpl.Editor.NodeViews{
public void OnDataModified();
IBaseDataGraphView BaseDataGraphView{ get; }
public void InitializePosition(Rect pos);
}
public interface INodeView<T>:IBaseNodeView where T:NodeData,new(){

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