加载中...
UitoolKit+ GraphView 开发 可视化节点编译器
发表于:2024-04-01 | 分类: Learn

视频地址

UI Toolkit介绍

UI Toolkit是用于开发用户界面(UI)的功能、资源和工具的集合。你可以使用UI Toolkit为Unity编辑器、运行时调试工具以及游戏和应用程序的运行时UI开发自定义UI和扩展。

UIToolKit受网页开发技术的启发,通过类似于HTML+CSS的方法来构建UI,在Unity中对应的就是UXML和USS,简单来说,UXML规定UI布局,USS规定UI样式。在UI的实际开发过程当中,我们也主要是和这两个部分打交道。

UIToolKit提供了一个UIBuilder工具来帮助我们完成UI的布局,具体的UIBuilder应该怎么使用这里就不做过多的解释。

Unity GraphView 介绍

首先Unity已经为我们提供了一个功能完善的Graphview模块,我们只需要继承这个模块,就能够定义自己的Graphview

可视化窗口搭建

下面就说一下使用过程中主要的函数调用

创建可视化窗口

继承EditorWindow 类去进行窗口编译器扩展
通过Creat/Uitoolkit/EditorWIndow 创建EditorWindow

public class CharEditor : EditorWindow
{
[MenuItem(“Tool/CharEditor”)]
public static void OpenWindow()
{
CharEditor wnd = GetWindow();
wnd.titleContent = new GUIContent(“CharEditor”);
}
}

通过UitoolKit 创建并绘制你想要的可视化窗口UI内容

使用 编写的uitolkit的 uus 和html 文件去进行绘制

public class CharEditor : EditorWindow
{
public void CreateGUI()
{
VisualElement root = rootVisualElement;

        var nodeTree = AssetDatabase.LoadAssetAtPath<VisualTreeAsset>( CharEditorConfig.ConfiguredPath+"NodeEditor.uxml");
        // 此处不使用visualTree.Instantiate() 为了保证行为树的单例防止重复实例化,以及需要将此root作为传参实时更新编辑器状态
        nodeTree.CloneTree(root);

        var styleSheet = AssetDatabase.LoadAssetAtPath<StyleSheet>(CharEditorConfig.ConfiguredPath+"NodeEditor.uss");
        root.styleSheets.Add(styleSheet);
    }

}
public static class CharEditorConfig
{
public const string ConfiguredPath=”Assets/CharTool/Config/“;
}

编译器窗口右键功能

创建可视化窗口的背景样式 这里使用.uss的样式

这里都是一样的UItoolkit种类

在可视化窗口UI中 增加对编译器的控制 添加该脚本

GraphView 这个就是编译器绘制的关键
public class NodeTreeViewer : GraphView
{
public new class UxmlFactory : UxmlFactory<NodeTreeViewer,GraphView.UxmlTraits>{}
NodeTree tree;
public NodeTreeViewer(){
Insert(0, new GridBackground());
var styleSheet = AssetDatabase.LoadAssetAtPath(CharEditorConfig.ConfiguredPath+”NodeTreeViewer.uss”);
styleSheets.Add(styleSheet);
}
}

编译器右键功能

给窗口增加创建栏
public class NodeTreeViewer : GraphView
{

/// <summary>
/// NodeTreeViewer视图中添加右键节点创建栏
/// </summary>
/// <param name="evt"></param>
public override void BuildContextualMenu(ContextualMenuPopulateEvent evt)
{
    {
        var types = TypeCache.GetTypesDerivedFrom<CompositeNode>();
        foreach(var type in types){
            if (!type.IsAbstract){
                evt.menu.AppendAction(type.Name, (a) => CreateNode(type));
            }
        }
    }
}
 void CreateNode(System.Type type){}

}

窗口中 控制监听等
   // 添加视图缩放
    this.AddManipulator(new ContentZoomer());
    // 添加视图拖拽
    this.AddManipulator(new ContentDragger());
    // 添加选中对象拖拽
    this.AddManipulator(new SelectionDragger());
节点之间互相连接

GetCompatiblePorts 通过这个方法

public override List<Port> GetCompatiblePorts(Port startPort, NodeAdapter nodeAdapter)
{
    /* 
        返回兼容接口列表
        需要判断接入的兼容接口仅为入口 endport.direction != startPort.direction
        且同个节点的出口不能接入自己的入口 endport.node != startPort.node
    */
    return ports.ToList().Where(
        endport => endport.direction != startPort.direction 
                   && endport.node != startPort.node).ToList();
}

uitoolkit节点制作和其他面板

这里这些面板的 拼接就不讲了 主要来说一些 : VisualElement
对Uitoolkit中的扩展
这样你就可以在uitollkit中使用
这里的

public class InspectorViewer : VisualElement
{
public new class UxmlFactory : UxmlFactory<InspectorViewer,VisualElement.UxmlTraits>{}
Editor editor;
public InspectorViewer(){

}

}

节点的 制作 UnityEditor.Experimental.GraphView.Node
unity中已经准备好的相关的node 节点
public class NodeView : UnityEditor.Experimental.GraphView.Node
{
public NodeView(Node node) : base(CharEditorConfig.ConfiguredPath+”NodeView.uxml”){}
}

对于节点中特殊属性

这两个 就是 Node中 输入,输出节点

///


/// 创建输入节点
///

///
private void CreateInputPorts()
{
input = InstantiatePort(Orientation.Vertical, Direction.Input, Port.Capacity.Multi, typeof(bool));
if(input != null){
// 将端口名设置为空
input.portName = “”;
// 因为input端口的label默认是在端口右边因此需要将排列方式调整为竖向自上往下
input.style.flexDirection = FlexDirection.Column;
inputContainer.Add(input);
}
}

/// <summary>
/// 创建输出节点
/// </summary>
/// <exception cref="NotImplementedException"></exception>
private void CreateOutputPorts()
{
    output = InstantiatePort(Orientation.Vertical, Direction.Output, Port.Capacity.Single, typeof(bool));
    
    if(output != null){
        output.portName = "";
        // 因为output端口的label默认是在端口左边边因此需要将排列方式调整为竖向自下往上
        output.style.flexDirection = FlexDirection.ColumnReverse;
        outputContainer.Add(output);
    }
}
节点的位置
/// <summary>
/// 设置节点在节点树视图中的位置
/// </summary>
/// <param name="newPos"></param>
public override void SetPosition(Rect newPos)
{
    // 将视图中节点位置设置为最新位置newPos
    base.SetPosition(newPos);
    // 撤回记录
    Undo.RecordObject(node,"Node Tree(Set Position)");
    // 将最新位置记录到运行时节点树中持久化存储
    node.position.x = newPos.xMin;
    node.position.y = newPos.yMin;
    EditorUtility.SetDirty(node);
}

总结

其中关于 使用uiyoolkit+graphView 进行可视化编译器开发就结束了
其中 uitoolkit的作用主要是编写 node格式 ,窗口样式,
不过 这种方式开发还是比较简单粗暴的

引用文献:
Unity 可视化节点编辑器(GraphView、编辑器扩展)地址
unity 可视化编译器行为树地址

上一篇:
unity性能优化心得
下一篇:
DrawCall
本文目录
本文目录