xNode入门

Graph,Node,Port

xNode下载:下载地址
xNode是一个可视化脚本编辑工具,核心概念有Graph(图),Node(节点)和Port(接口,端点),Graph包含所有Node的列表,每个节点可以访问它的输入输出Port和它所属的Graph。
在这里插入图片描述
如上图,每个方框是一个Node,它包含自己定义的属性,黄点是Port,整个背景可以看作是Graph,它是所有Node的容器。

Node类是所有节点类型的基类。
NodeEditor是所有自定义节点编辑器的基类,用于定制节点外观。
NodeGraph是所有图类型的基类。
NodeGraphEditor是所有自定义图编辑器的基类。

创建一个Graph

//[CreateAssetMenu]用于右键创建一个新的Graph的asset文件,Create > SimpleGraph.
[CreateAssetMenu]
public class SimpleGraph : NodeGraph {
    
    
	//nodes是所有节点的列表,便利nodes找到开始节点
    public StartNode GetStartNode() {
    
    
        for (int i = 0; i < nodes.Count; i++) {
    
    
            if (nodes[i] is StartNode) return nodes[i] as StartNode;
        }
        return null;
    }
}

创建一个Node

//修改节点颜色,宽度
[NodeTint("#000000")]
[NodeWidth(200)]
public class StartNode : Node
{
    
    
    //标记输入,输出
    [Input] public float value;
    [Output] public float result;
    
    /// <summary>
    /// 其他节点获取该节点的输出值
    /// </summary>
    public override object GetValue(NodePort port) {
    
    
        if (port.fieldName == "result") {
    
    
            //如果输入Port没有连接,返回字段默认值, 否则返回连接Port的值
            return GetInputValue<float>("value", this.value);
        }
        else 
            return null;
    }
    
    /// <summary>
    /// 在节点的右键菜单中添加方法
    /// </summary>
    [ContextMenu("Do Something")]
    void DoSomething()
    {
    
    
        Debug.Log("Perform operation");

        //获取输出Port连接的Port,进而获取相邻的Node,Connection是从所有连接Port中获取第一个非空Port
        NodePort otherPort = GetOutputPort("myOutput").Connection;
        if (otherPort != null) {
    
    
            MyNode nextNode = otherPort.node as MyNode;
        }
    }
}

实现一个简单的计算

参考官方的实例,定义一个Graph和两种Node

namespace xNodeTest
{
    
    
    [CreateAssetMenu]
    public class CalcGraph : NodeGraph {
    
     }
}
namespace XNodeTest
{
    
    
	public class FloatNode : Node 
	{
    
    
		//howBackingValue.Unconnected表示Port连接时显示Port值,没连接显示字段值。
		//ConnectionType.Override表示只允许一条线连接该Port
		[Input(ShowBackingValue.Unconnected, ConnectionType.Override)] public float input;
		[Output] public float output;
		
		public override object GetValue(NodePort port) 
		{
    
    
			return GetInputValue<float>("input", this.input); 
		}
	}
}
namespace xNodeTest
{
    
    
	public class CalcNode : Node 
	{
    
    
		[Input] public float input1;
		[Input] public float input2;
		[Output] public float output;
		
		public MathType mathType = MathType.Add;
		public enum MathType {
    
     Add, Subtract, Multiply, Divide }
		
		public override object GetValue(XNode.NodePort port) 
		{
    
    
			float a = GetInputValue<float>("input1", this.input1);
			float b = GetInputValue<float>("input2", this.input2);
			
			output = 0f;
			if (port.fieldName == "output")
				switch (mathType) {
    
    
					case MathType.Add: default: output = a+b; break;
					case MathType.Subtract: output = a - b; break;
					case MathType.Multiply: output = a * b; break;
					case MathType.Divide: output = a / b; break;
				}
			return output;
		}
	}
}

右键–Crate–CalcGraph,在图上创建节点如下,就可以实现一个简单的加减乘除计算。
在这里插入图片描述

修改节点外观

修改后效果
在这里插入图片描述

namespace xNodeTest
{
    
    
    [CustomNodeGraphEditor(typeof(CalcGraph))]
    public class CalcGraphEditor : NodeGraphEditor
    {
    
    
        /// <summary>
        /// 修改所有Port的颜色
        /// </summary>
        public override Color GetPortColor(XNode.NodePort port) {
    
    
            return Color.cyan;
        }
    }
}
namespace xNodeTest
{
    
    
    [CustomNodeEditor(typeof(CalcNode))]
    public class CalcNodeEditor : NodeEditor
    {
    
    
        /// <summary>
        /// 绘制标题
        /// </summary>
        public override void OnHeaderGUI()
        {
    
    
            GUILayout.Label("计算", NodeEditorResources.styles.nodeHeader, GUILayout.Height(30));
            
            //绘制圆点
            Rect dotPos = GUILayoutUtility.GetLastRect();
            dotPos.size = new Vector2(16, 16);
            dotPos.y += 6;
            
            GUI.color = Color.green;
            //NodeEditorResources.dot是Texture2D
            GUI.DrawTexture(dotPos, NodeEditorResources.dot);
            GUI.color = Color.white;
        }
        
        /// <summary>
        /// 绘制主体
        /// </summary>
        public override void OnBodyGUI() {
    
    
            if (target == null) {
    
    
                Debug.LogWarning("Null target node for node editor!");
                return;
            }
            base.OnBodyGUI();
            
            CalcNode node = target as CalcNode;
            if (GUILayout.Button("Do Something"))
            {
    
    
                //Do Something
            }
        }
    }
}

在这里插入图片描述
Edit - Preference中可以对节点的颜色,连线的类型等进行设置

猜你喜欢

转载自blog.csdn.net/sinat_34014668/article/details/126652362
今日推荐