Overlay 是在编辑器窗口中可用的持久且可自定义的面板和工具栏。使用 Overlay 以方便且用户可控的方式公开操作和工具选项。
这是所有 Overlay 继承的基类。要创建 Overlay,请返回 UnityEngine.UIElements.VisualElement。
显示 Overlay 的最简单方法是使用 OverlayAttribute 并注册目标 EditorWindow。
using UnityEditor; using UnityEditor.Overlays; using UnityEngine.UIElements;
// Specifying `OverlayAttribute.editorWindowType` tells the OverlayCanvas to always show this Overlay in the menu. [Overlay(typeof(SceneView), "Selection Count")] class SelectionCount : Overlay { Label m_Label;
public override VisualElement CreatePanelContent() { Selection.selectionChanged += () => { if (m_Label != null) m_Label.text = $"Selection Count {Selection.count}"; };
return m_Label = new Label($"Selection Count {Selection.count}"); } }
Overlay 可用于实现 ISupportsOverlays 的任何 EditorWindow。可以使用 OverlayCanvas.Add 和 OverlayCanvas.Remove 从 Overlay 菜单中添加和删除 Overlay。
using System; using UnityEditor; using UnityEditor.Overlays; using UnityEngine; using UnityEngine.UIElements;
public class OverlayWindowExample : EditorWindow, ISupportsOverlays { bool m_ShowOverlay; InstanceOverlay m_Overlay;
// InstanceOverlay is not registered as a persistent overlay, and it must be instantiated through code. In contrast, // PersistentOverlay is registered with a target window type and will be available at any time. // All OverlayAttribute properties are optional. Here, we specify that when this overlay is added to a window for the // first time, so it is visible by default. IfdefaultDisplay
is set to it's default value of false, the // Overlay will be available in the Overlay Menu when added to a window, but not visible. [Overlay(defaultDisplay = true)] class InstanceOverlay : Overlay { OverlayWindowExample m_Window; public InstanceOverlay(OverlayWindowExample win) => m_Window = win; public override VisualElement CreatePanelContent() => new Label() { text = $"Hello from {m_Window.name}!" }; }
// Persistent overlays are always available in the Overlay Menu. An Overlay is made persistent by assigning the // `editorWindowType` property in `OverlayAttribute`. [Overlay(typeof(OverlayWindowExample), "Persistent Overlay", defaultDisplay = true)] class PersistentOverlay : Overlay { public override VisualElement CreatePanelContent() => new Label() { text = "Hello, I'm always available!" }; }
[MenuItem("Window/Overlay Window")] static void Init() => GetWindow<OverlayWindowExample>();
void OnEnable() => m_Overlay = new InstanceOverlay(this);
void OnGUI() { EditorGUI.BeginChangeCheck(); m_ShowOverlay = EditorGUILayout.Toggle("Show Overlay", m_ShowOverlay); if (EditorGUI.EndChangeCheck()) { if (m_ShowOverlay) overlayCanvas.Add(m_Overlay); else overlayCanvas.Remove(m_Overlay); } } }
Overlay 可以通过 SceneView.AddOverlayToActiveView 和 SceneView.RemoveOverlayFromActiveView 在活动 SceneView 中显示。这对于需要显示 UI 的 EditorTool 很有用。
using System.Linq; using UnityEngine; using UnityEditor; using UnityEditor.EditorTools; using UnityEditor.Overlays; using UnityEngine.UIElements;
// A simple tool that moves the selected transforms using an Overlay interface. [EditorTool("Offset", typeof(Transform))] public class OffsetTool : EditorTool { // By default, overlays added to the canvas are not displayed. Setting the `defaultDisplay` property ensures that the // first time this Overlay is added to a canvas it will be visible. [Overlay(defaultDisplay = true)] class OffsetToolOverlay : Overlay { Transform[] selection;
public OffsetToolOverlay(Transform[] targets) => selection = targets;
public override VisualElement CreatePanelContent() { var root = new VisualElement(); root.Add(new Button(() => Move(Vector3.right)) { text = "Move Right" }); root.Add(new Button(() => Move(Vector3.up)) { text = "Move Up" }); root.Add(new Button(() => Move(Vector3.forward)) { text = "Move Forward" }); return root; }
void Move(Vector3 direction) { Undo.RecordObjects(selection, "Move Selection"); foreach (var transform in selection) transform.position += direction; } }
OffsetToolOverlay m_Overlay;
public override void OnActivated() { SceneView.AddOverlayToActiveView(m_Overlay = new OffsetToolOverlay(targets.Select(x => x as Transform).ToArray())); }
public override void OnWillBeDeactivated() { SceneView.RemoveOverlayFromActiveView(m_Overlay); } }
要创建可停靠在工具栏中的 Overlay,请参阅 ToolbarOverlay。
ussClassName | 此类型元素的 USS 类名。 |
collapsed | 定义 Overlay 是否处于折叠形式。 |
collapsedIcon | 定义 Overlay 处于折叠形式时要使用的自定义图标。 |
containerWindow | 包含 Overlay 的 EditorWindow。 |
defaultSize | 设置 defaultSize 以定义 Overlay 在未被用户调整大小时的尺寸。 |
displayed | 显示或隐藏 Overlay。 |
displayName | 用作标题的 Overlay 名称。 |
floating | 如果 Overlay 处于浮动状态,则返回 true;如果 Overlay 停靠在角落或工具栏中,则返回 false。 |
floatingPosition | Overlay 最接近角落到最接近停靠位置的局部位置,处于浮动状态时。 |
id | Overlay 唯一 ID。 |
isInToolbar | 如果 Overlay 停靠在工具栏中,则返回 true。 |
layout | Overlay 的首选布局。 |
maxSize | Overlay 的最大尺寸。 |
minSize | Overlay 的最小尺寸。 |
rootVisualElement | 根 VisualElement。 |
size | Overlay 的尺寸。 |
关闭 | 从其 OverlayCanvas 中删除 Overlay。 |
CreateContent | 创建一个新的 VisualElement,其中包含此 Overlay 的内容。 |
CreatePanelContent | 实现此方法以返回您的视觉元素内容。 |
OnCreated | 当 Overlay 在 Overlay Canvas 中实例化时,将调用 OnCreated。 |
OnWillBeDestroyed | 当 Overlay 即将被销毁时调用。 |
RefreshPopup | 调整 OverlayPopup 的大小以适合内容。 |
Undock | 如果此 Overlay 当前位于工具栏中,它将被删除并返回到浮动状态。 |
collapsedChanged | 当 Overlay.collapsed 值更改时调用。 |
displayedChanged | 当 Overlay.displayed 值更改时,将调用此回调。 |
floatingChanged | 当 floating 的值更改时调用。 |
floatingPositionChanged | 当 Overlay.floatingPosition 更改时,将调用此事件。 |
layoutChanged | 订阅此事件以在 Overlay.Layout 属性修改时收到通知。 |