节点编辑插件GraphProcessor(1) – 半只龙虾人

浏览量:
626

声明,此节点编辑器是我基于alelievr大佬的NodeGraphProcessor项目魔改而来,有兴趣的可以去给大佬点个star。原项目在节点之间的逻辑控制使用了很多反射,关于这点我个人不是很喜欢这种方式,所以使用了与xNode一样的逻辑控制方式,xNode使用传统的imgui绘制方式,除了绘制方式的落后性能稍差之外,其它地方写的都非常棒,代码结构清晰,语法简洁,非常值得学习。魔改后的github地址GraphProcessor

GraphProcessor的数据保存不使用外部工具,对于抽象的节点数据保存,仅使用unity内置的JsonUtility,因此Unity不支持的数据类型,节点编辑器也不支持,若有需要,只需修改JsonDeserializer脚本内的序列化方式即可

GraphProcessor底层是UIElements,相较于传统的IMGUI绘制方式,性能要高上不少,这里不多做赘述,网上有很多相关资料,下面上效果图。

核心类有两个,BaseGraph和BaseNode

BaseGraph是所有Graph的基类,继承自UnityEngine.ScriptableObject,存储所有的节点,黑板数据,连线等数据,是所有数据的集合,同时辅助Node之间的逻辑控制

/// 黑板的默认大小 public static readonly Vector2 DefaultBlackboardSize = new Vector2(150, 200); public Vector3 position = Vector3.zero; public Vector3 scale = Vector3.one; public Rect blackboardPosition = new Rect(Vector2.zero, DefaultBlackboardSize); public bool blackboardoVisible = true; //SerializeField] NodesDictionary nodes = new NodesDictionary(); [SerializeField] Dictionary nodes = new Dictionary(); [SerializeField] EdgesDictionary edges = new EdgesDictionary(); [SerializeField] List groups = new List(); [SerializeField] StackNodesDictionary stackNodes = new StackNodesDictionary(); // GUID和变量的映射表 [SerializeField] ExposedParametersDictionary parametersGUID = new ExposedParametersDictionary(); // 字段名和GUID的映射表 [SerializeField, HideInInspector] ParamNameGUIDDictionary parametersName = new ParamNameGUIDDictionary();

BaseNode是所有节点的基类,其中包含了节点的类型,在Graph中的坐标,接口信息,数据传递等相关信息和功能

[SerializeField] BaseGraph owner; /// 唯一标识 [SerializeField, HideInInspector] string guid; /// 位置坐标 public Rect position; /// 展开状态 [SerializeField] bool expanded = true; /// 锁定状态 [SerializeField] bool locked = false; [SerializeField] Dictionary ports = new Dictionary();

代码较多,可以直接克隆github上的项目,版本要求2019.4及以上

如何创建一个Graph

使用非常简单,创建一个脚本,继承BaseGraph

[CreateAssetMenu(menuName = “GraphProcessor/New Math”, fileName = “New Math Graph”)] public class MathGraph : BaseGraph { }

节点类的创建同样如此

// 特性NodeMenuItem是节点在节点列表中的路径及创建出来节点的默认名称 [NodeMenuItem(“Math”, “Float”)] public class FloatNode : BaseNode { [Port(PortDirection.Output)] public float value; }

[NodeMenuItem(“Math”, “Float”)]是该节点在Graph视图,节点菜单中的路径

节点间的数据传递

通过TryGetConnectValue获取端口连接的对面端口数据

// 参数_fieldName是端口名称,即要通过哪个端口去对面端口取值 // _value 则是对面端口返回的值,如果返回值为false,则说明端口没有连接 // 或者对面没有要返回的值 public bool TryGetConnectValue(string _fieldName, out T _value, T _fallback = default(T)) { _value = _fallback; if (TryGetPort(_fieldName, out NodePort port)) return port.TryGetConnectValue(ref _value); return false; }

通过GetValue向外部返回数据,这个方法需要通过override实现功能,否则外部无法获取数据

// 参数_port是外部获取数据的那个接口 // 如果没要要返回的数据,直接返回false即可 public override bool GetValue(NodePort _port, ref T _value) { if (value is T tValue) { _value = tValue; return true; } return false; }


比丘资源网 » 节点编辑插件GraphProcessor(1) – 半只龙虾人

发表回复

提供最优质的资源集合

立即查看 了解详情