Unity Graph View打造图形化对话编辑系统(三)
系统 Unity 打造 View 编辑 对话 Graph 图形化
2023-09-11 14:20:53 时间
Unity Graph View打造图形化对话编辑系统(三)——UIBuilder构造Editor Window
目录
视频效果演示
Graph View打造图形化对话编辑系统效果展示
最终源码先附在此
先得写几个类
编辑窗口分成左右两部分,左边是属性窗口(Inspector),当用户选择了一个节点时,可以在这里编辑它。右边是对话树的编辑窗口,编辑工作主要在这里进行。那么我们需要以下几个类:
- HorizontalSplitView —— 水平方向分割窗口视图类,继承自TwoPaneSplitView
- DialogueTreeView —— 对话树视图类,它是节点和连线的容器,继承自GraphView
- DialogueNodeView —— 节点视图类,它负责渲染节点,是接口的容器,继承自Node
- InspectorView —— 节点属性编辑面板,继承自VisualElement
这几个类,因为只需要运行在编辑模式中,所以,最好把他们放到Editor文件夹下面,这样可以确保在发布时不会将他们打包进工程。
以DialogueTreeView为例:
public class DialogGraphView : GraphView
{
public new class UxmlFactory : UxmlFactory<DialogGraphView, UxmlTraits> { }
// 对话树的Scriptable数据
public DialogTree treeData = null;
public DialogGraphView()
{
// 增加格子背景、内容缩放、拖动、框选组件。
Insert(0, new GridBackground());
this.AddManipulator(new ContentZoomer());
this.AddManipulator(new ContentDragger());
this.AddManipulator(new SelectionDragger());
this.AddManipulator(new RectangleSelector());
// 加载uss风格文件,类似HTML里的css
var styleSheet = AssetDatabase.LoadAssetAtPath<StyleSheet>("Assets/Dialog Graph/Editor/EditorWindow/DialogGraphWindow.uss");
styleSheets.Add(styleSheet);
}
}
用UIBuilder搭建如下的UI(注意左侧层级关系):
需要注意的一个小坑:
InspectorView和DialogueTreeView,不要直接隶属面板容器,或者说他们不要有兄弟面板,否则就会导致鼠标位置响应不准确。要先给他套上一个VisualElement。这UIBuilder目前还是preview状态,尚未正式发布,所有还有一些各种各样的小问题。
默认情况下,打开我们自己定义的编辑窗口,是通过自定义的菜单来实现的,但是,我们想让我们的编辑窗口关联到Scriptable数据上,我们想让用户双击DialogTree时,能够自动打开编辑窗口,然后对该DialogTree进行编辑,所以,我们需要修改一下窗口的代码:
public class DialogGraphWindow : EditorWindow
{
/*
这是之前的打开方式,我们不再需要它了
[MenuItem("Dialog Graph/Editor Window")]
public static void OpenEditorWindow()
{
DialogGraphWindow wnd = GetWindow<DialogGraphWindow>();
wnd.titleContent = new GUIContent("DialogGraphWindow");
}
*/
// 当双击Assets时,如果双击的是一颗对话树,那我们就编辑它
[OnOpenAsset(1)]
public static bool OnOpenAssets(int id, int line)
{
if( EditorUtility.InstanceIDToObject(id) is DialogTree tree )
{
DialogGraphWindow wnd = GetWindow<DialogGraphWindow>();
wnd.titleContent = new GUIContent($"图形化对话系统");
Label titleLab = wnd.rootVisualElement.Q<Label>("TreeViewTitle");
if( titleLab != null )
titleLab.text = $"对话图 - {tree.name}";
wnd.graphView.Populate(tree);
return true;
}
return false;
}
public static void CloseEditorWindow()
{
DialogGraphWindow wnd = GetWindow<DialogGraphWindow>();
wnd.Close();
}
private DialogGraphView graphView = null;
private InspectorView inspectorView = null;
public void CreateGUI()
{
var visualTree = AssetDatabase.LoadAssetAtPath<VisualTreeAsset>("Assets/Dialog Graph/Editor/EditorWindow/DialogGraphWindow.uxml");
visualTree.CloneTree(rootVisualElement);
graphView = rootVisualElement.Q<DialogGraphView>("GraphView");
graphView.OnNodeSelected += WhenNodeSelected;
inspectorView = rootVisualElement.Q<InspectorView>("Inspector");
Button bt = rootVisualElement.Q<Button>("SaveButton");
bt.clicked += OnSaveButtonClicked;
}
private void OnSaveButtonClicked()
{
AssetDatabase.SaveAssets();
}
private void OnDestroy()
{
AssetDatabase.SaveAssets();
}
}
还有一个问题,如果用户双击了一个DialogTree,进入了编辑状态,然后它又将这个DialogTree删除了,怎么办?此时我们的编辑窗口所编辑的目标已经消失了,窗口应该要自动关闭才合理。所以,我们需要监听这种事情的发生。查阅资料后,果然有一个方法:
public class CloseEditorBeforeAssetRemoved : UnityEditor.AssetModificationProcessor
{
public static AssetDeleteResult OnWillDeleteAsset(string assetPath, RemoveAssetOptions option)
{
if( AssetDatabase.LoadAssetAtPath<DialogTree>(assetPath) is DialogTree tree )
{
DialogGraphWindow.CloseEditorWindow();
}
return AssetDeleteResult.DidNotDelete;
}
}
相关文章
- Linux下查看系统版本号信息的方法
- Windows Server系统加固
- win10系统和linux配置环境变量wechaty token ID这是最基本的操作
- UWA学堂上新:如何绕过Unity打造自己的HUD UI系统
- windows系统下Python环境的搭建
- 03分布式电商项目 - 系统架构
- 推荐系统那点事
- linux系统(CentOS7)虚拟机上安装oracle 11g,解决oracle图形界面卡住无法点击next问题
- B站日志系统的前世今生
- 基于python的环境噪声监测报警系统实例解析
- ghost 安装系统出现EFI PART红色错误的问题
- 【Unity3D插件】Dialogue System for Unity插件分享《对话系统插件》
- Unity框架学习_DataManager,基于事件的信息管理驱动系统,简单快捷的实现信息改动后全局的刷新
- Unity Android 之 获取系统Calendar 日历日程 (涉及指定日期时间判断是星期几的方法使用)的方法整理
- Unity 工具之 获取当前系统时间,并格式化显示的封装(并有简单的月星期am/pm转换)
- Unity编辑器开发(二):四大GUI系统
- Unity实用框架(三)事件系统
- Unity 之 Addressable可寻址系统 -- 资源远程加载 | 资源预下载 -- 进阶(三)
- Unity 之 Addressable可寻址系统 -- 代码加载介绍 -- 进阶(一)
- Unity 动画系统-AnimationEvent
- Unity 物理系统 -- 碰撞体简介(碰撞、触发条件)
- Unity UI系统 UGUI-RectTransform
- Unity UI系统-NGUI-基本组件(二)
- 什么是RUTP协议?RUDP协议在视频会议系统中的应用
- RookeyFrame Bug 编号显示 系统自动生成 的问题,有时候依旧会显示text文本框
- Unity笔记-29-ARPG游戏项目-03-攀爬系统
- MATLAB通信系统建模
- 张晓丹:新一代两地三中心多活系统实践