创建添加节点对话框类
- 打开UI文件夹,创建C#文件,命名为
NodeCreationBox
- 打开NodeCreationBox.cs,将内容修改如下:
C#
using System.Collections.Generic;
using UnityEditor.Experimental.GraphView;
using UnityEngine;
namespace E.Story
{
// 添加节点对话框
public class NodeCreationBox : ScriptableObject, ISearchWindowProvider
{
private StoryGraphView graphViewer;
private Texture2D indentationIcon;
// 初始化
public void Init(StoryGraphView viewer)
{
graphViewer = viewer;
// 设置缩进图标
indentationIcon = new Texture2D(1, 1);
indentationIcon.SetPixel(0, 0, Color.clear);
indentationIcon.Apply();
}
// 创建搜索树
public List CreateSearchTree(SearchWindowContext context)
{
List searchTreeEntries = new()
{
// 标题
new SearchTreeGroupEntry(new GUIContent("添加节点")),
new SearchTreeEntry(new GUIContent("对话", indentationIcon))
{
level = 1,
userData = NodeType.Dialogue
},
new SearchTreeEntry(new GUIContent("分支", indentationIcon))
{
level = 1,
userData = NodeType.Branch
},
new SearchTreeEntry(new GUIContent("开始", indentationIcon))
{
level = 1,
userData = NodeType.Start
},
new SearchTreeEntry(new GUIContent("结束", indentationIcon))
{
level = 1,
userData = NodeType.End
},
};
return searchTreeEntries;
}
// 当点击对话框某个按钮时
public bool OnSelectEntry(SearchTreeEntry SearchTreeEntry, SearchWindowContext context)
{
// 检测节点类型执行对应操作
NodeType type = (NodeType)SearchTreeEntry.userData;
switch (type)
{
case NodeType.Dialogue:
case NodeType.Branch:
case NodeType.Start:
case NodeType.End:
graphViewer.CreateNode(SearchTreeEntry.content.text, type, Vector2.zero);
return true;
default:
return false;
}
}
}
}
实例化添加节点对话框类
- 打开StoryGraphView.cs,添加字段
nodeCreationBox
C#
private NodeCreationBox nodeCreationBox;
- 新增以下方法
C#
// 添加添加节点对话框
private void AddNodeCreationBox()
{
nodeCreationBox = ScriptableObject.CreateInstance();
nodeCreationBox.Init(this);
}
// 当打开添加节点对话框时
private void OnOpenNodeCreationBox()
{
// 定义请求事件
nodeCreationRequest = context =>
{
// 打开搜索框
SearchWindow.Open(new SearchWindowContext(context.screenMousePosition), nodeCreationBox);
};
}
- 调用方法
C#
// 构造器
public StoryGraphView(StoryEditorWindow window)
{
/* ... 此处代码已省略 ... */
// 调用方法
AddNodeCreationBox();
OnOpenNodeCreationBox();
}
简化上下文菜单
- 打开StoryGraphView.cs,修改
BuildContextualMenu
方法
C#
public override void BuildContextualMenu(ContextualMenuPopulateEvent evt)
{
base.BuildContextualMenu(evt);
evt.menu.AppendAction("添加节点", action =>
{
// 获取光标当前屏幕位置
Vector2 screenMousePosition = action.eventInfo.mousePosition + storyEditorWindow.position.position + new Vector2(50, 35);
// 触发请求事件
nodeCreationRequest(new NodeCreationContext
{
screenMousePosition = screenMousePosition,
index = -1
});
});
}
使节点创建在光标点击位置
- 打开StoryGraphView.cs,新增
GetLocalMousePosition
方法
C#
// 获取本地鼠标坐标
public Vector2 GetLocalMousePosition(Vector2 screenMousePosition)
{
// 将光标的屏幕坐标转换为光标在当前窗口内的坐标
Vector2 windowMousePosition = screenMousePosition - storyEditorWindow.position.position;
// 将光标在当前窗口内的坐标转换为光标在节点视图内的坐标
Vector2 localMousePosition = contentViewContainer.WorldToLocal(windowMousePosition);
return localMousePosition;
}
- 打开NodeCreationBox.cs,修改
OnSelectEntry
方法
C#
// 当点击对话框某个按钮时
public bool OnSelectEntry(SearchTreeEntry SearchTreeEntry, SearchWindowContext context)
{
// 获取本地点击坐标
Vector2 localMousePostion = graphViewer.GetLocalMousePosition(context.screenMousePosition);
// 检测节点类型执行对应操作
NodeType type = (NodeType)SearchTreeEntry.userData;
switch (type)
{
case NodeType.Dialogue:
case NodeType.Branch:
case NodeType.Start:
case NodeType.End:
graphViewer.CreateNode(SearchTreeEntry.content.text, type, localMousePostion);
return true;
default:
return false;
}
}
修改默认添加的节点
- 打开StoryGraphView.cs,修改
AddDefaultNodes
方法
C#
// 添加默认节点
private void AddDefaultNodes()
{
CreateNode("开始", NodeType.Start, new Vector2(200, 200));
CreateNode("结束", NodeType.End, new Vector2(800, 200));
}
测试效果
最终窗口效果如下:
