Unity剧情编译器的实现 —— 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;
		}
	}
}

在这里插入图片描述

以实现剧情编译器的模板链接:https://pan.baidu.com/s/1zugnp3G3tX8sLsoHfmGQlA 
提取码:pusg

参考:使用Xnode制作可视化剧本编辑插件(1) - 知乎

Unity编辑器扩展:使用xNode制作自己的可视化工具(2) - 知乎

使用Xnode编写的简易对话系统_legroft的博客-CSDN博客_xnode dialoge

猜你喜欢

转载自blog.csdn.net/qq_38721111/article/details/128954150