Unity开发笔记-Editor扩展用GraphView实现逻辑表达式(2)表达式逻辑Node扩展

本篇我们将实现表达式编辑器的UI功能部分

0 操作数节点FloatNode#

既然我们的目标是实现一个逻辑表达式,我们需要一个FloatNode作为基本的操作数。你也可以实现自己的Int版本
我们在Node的ContentContainer中加入FloatField输入框让用户输入内容

Copy
` public class YaoJZFloatNodeView:Node { private FloatField _floatField; public Port OutputPort; public YaoJZFloatNodeView() { title = "Float"; OutputPort = Port.Create<Edge>(Orientation.Horizontal, Direction.Output, Port.Capacity.Single, typeof(Port)); outputContainer.Add(OutputPort); _floatField = new FloatField(); //添加一个floatfield输入框 _floatField.RegisterValueChangedCallback(OnFloatValueChanged); contentContainer.Add(_floatField); RefreshExpandedState(); } private void OnFloatValueChanged(ChangeEvent<float> evt) { //输入内容变化了 } public float Value { get{return _floatField.value;} set { _floatField.value = value; } } } `

1 BinaryOpNode二元操作节点#

现在我们实现一个二元操作功能的Node,这个Node实现二院表达式,我们先实现数学运算的加减乘除

BinaryOpNode有2个输入Port,分别来连接左操作数节点和右操作数节点
另外需要一个Output的Port,代表操作后的结果输出

Copy
public class YaoJZBinaryOpNodeView:Node { public Port LeftInput; //左操作数节点端口 public Port RightInput; //右操作数节点端口 public Port OutputPort; public YaoJZBinaryOpNodeView() { this.title = "BinaryOp"; OutputPort = Port.Create<Edge>(Orientation.Horizontal, Direction.Output, Port.Capacity.Single, typeof(Port)); outputContainer.Add(OutputPort); LeftInput = Port.Create<Edge>(Orientation.Horizontal, Direction.Input, Port.Capacity.Single, typeof(Port)); inputContainer.Add(LeftInput); RightInput = Port.Create<Edge>(Orientation.Horizontal, Direction.Input, Port.Capacity.Single, typeof(Port)); inputContainer.Add(RightInput); } }

`

我们需要定义一个操作方法枚举,代表我们可以进行的操作行为类型

Copy
public enum BinaryNodeOpType { Add, Sub, Divide, Mutiply, }

然后我们添加一个EnumField,让用户可以在Node中选择自己想要的BinaryNodeOpType

YaoJZBinaryOpNodeView.cs类

Copy
public class YaoJZBinaryOpNodeView:Node { private EnumField _opEnumField; public Enums.BinaryNodeOpType OpType { get { return (Enums.BinaryNodeOpType)_opEnumField.value; } set { _opEnumField.value = value; } } public YaoJZBinaryOpNodeView() { //...之前的代码 _opEnumField = new EnumField(); _opEnumField.Init(Enums.BinaryNodeOpType.Add); contentContainer.Add(_opEnumField); } }

别忘了将节点添加到ISearchWindowProvider的右键菜单中#

Copy
public class YaoJZSearchMenuWindowProvider:ScriptableObject, ISearchWindowProvider { public List<SearchTreeEntry> CreateSearchTree(SearchWindowContext context) { var entries = new List<SearchTreeEntry>(); entries.Add(new SearchTreeGroupEntry(new GUIContent("Create Node"))); entries.Add(new SearchTreeGroupEntry(new GUIContent("Example")) { level = 1 }); entries.Add(new SearchTreeEntry(new GUIContent("float")) { level = 2, userData = typeof(YaoJZFloatNodeView) }); entries.Add(new SearchTreeEntry(new GUIContent("binary")) { level = 2, userData = typeof(YaoJZBinaryOpNodeView) }); return entries; } }

改进:每次添加新节点未免有些麻烦,我们可以通过Attribute功能,利用反射将节点添加到右键菜单中。

现在我们连接一下看看最终的效果

我们的表达式编辑器的UI部分已经实现的差不多了,下一篇我们实现表达式的运行时逻辑

posted @   jeoyao  阅读(1646)  评论(1编辑  收藏  举报
编辑推荐:
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
· 浏览器原生「磁吸」效果!Anchor Positioning 锚点定位神器解析
· 没有源码,如何修改代码逻辑?
阅读排行:
· 分享4款.NET开源、免费、实用的商城系统
· 全程不用写代码,我用AI程序员写了一个飞机大战
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了
· 上周热点回顾(2.24-3.2)
点击右上角即可分享
微信分享提示
目录