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;
}
}
}
以实现剧情编译器的模板链接:https://pan.baidu.com/s/1zugnp3G3tX8sLsoHfmGQlA
提取码:pusg