Unity開發筆記-Editor擴展用GraphView實現邏輯表達式(2)表達式邏輯Node擴展


本篇我們將實現表達式編輯器的UI功能部分

0 操作數節點FloatNode

既然我們的目標是實現一個邏輯表達式,我們需要一個FloatNode作為基本的操作數。你也可以實現自己的Int版本
我們在Node的ContentContainer中加入FloatField輸入框讓用戶輸入內容

  `
   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,代表操作后的結果輸出

  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);
        
    }
}

`

我們需要定義一個操作方法枚舉,代表我們可以進行的操作行為類型

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

然后我們添加一個EnumField,讓用戶可以在Node中選擇自己想要的BinaryNodeOpType

YaoJZBinaryOpNodeView.cs類

  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的右鍵菜單中

  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部分已經實現的差不多了,下一篇我們實現表達式的運行時邏輯


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM