Unity 6.3
0 онлайн 97 гостей 3 в системе
Вход
Unity Editor interface Шаг 87 из 131

Создание настраиваемого наложения

Вы можете создавать настраиваемые накладки панели и накладки панели инструментов для окна представления Scene.

Тип: Информация о создании UIElements, см. UI Руководство для разработчиков Elements.

Понимание EditorToolbarElement

Элемент панели инструментов может содержать текст, значок или комбинацию обоих элементов.

Используйте EditorToolbarElement(Identifier, EditorWindowType) для регистрации элементов панели инструментов для использования в реализациях ToolbarOverlay.

Вы можете наследовать от любого типа VisualElement и создавать стиль самостоятельно, но элементы панели инструментов требуют особого стиля. Предпочтительнее наследовать от одного из этих предопределенных типов EditorToolbar:

  • EditorToolbarButton: на основе UnityEditor.UIElements.ToolbarButton
  • EditorToolbarToggle: на основе UnityEditor.UIElements.ToolbarToggle
  • EditorToolbarDropdown: на основе EditorToolbarButton
  • EditorToolbarDropdownToggle: на основе UnityEngine.UIElements.BaseField

Совет: Если панель инструментов прикреплена горизонтально или вертикально, ее текст может быть невидимым или отрезанным. Вы можете указать значок для каждой панели инструментов, чтобы избежать отрезания текста.

Создание наложения панели

Все накладки должны наследовать от Overlay базовый класс и реализуйте CreatePanelContent метод. Это создает базовую панель, которую можно использовать и в которую можно добавлять элементы панели инструментов.

Чтобы создать наложение панели:

  1. Создать новый C# скрипт в 2000 году Папка редактора и назвать его.

  2. Откройте созданный скрипт.

  3. Удаление содержимого по умолчанию из скрипта.

  4. Осуществление Overlay класс из UnityEditor.Overlays пространство имен.

  5. Переопределите функцию CreatePanelContent и добавьте свой контент в визуальный элемент.

  6. Добавить OverlayAttribute атрибут к классу.

  7. В OverlayAttributeукажите, в каком типе окна вы хотите разместить это наложение:

    • Если вы хотите, чтобы накладка была доступна во всех окнах Редактора, укажите EditorWindow в качестве типа. Только окна, наследующие от ISupportOverlays могут использовать накладки.
    • Чтобы сделать накладку доступной в типе окна, наследующем от ISupportOverlays, укажите окно в качестве типа. Например, чтобы сделать накладку доступной только в представлении Scene, укажите SceneView в качестве типа.
  8. В течение OverlayAttribute, добавьте отображаемое имя. См. OverlayAttribute для информации о других свойствах, которые можно добавить в OverlayAttribute.

  9. Чтобы добавить значок, который отображается при сжатии наложения, добавьте Icon атрибут к Overlay класс и укажите значок. Если у оверлея значка нет, система по умолчанию берёт первые две буквы его имени или первые буквы двух первых слов.

Пример

using UnityEditor;
using UnityEditor.Overlays;
using UnityEngine.UIElements;
[Overlay(typeof(SceneView), "Panel Overlay Example", true)]
public class MyToolButtonOverlay : Overlay
{
    public override VisualElement CreatePanelContent()
    {
        var root = new VisualElement() { name = "My Toolbar Root" };
        root.Add(new Label() { text = "Hello" });
        return root;

    }
}

Создание наложения панели инструментов

Накладки панели инструментов — это контейнеры, которые содержат элементы панели инструментов и состоят из коллекций EditorToolbarElement.

Накладки панели инструментов имеют встроенные горизонтальные, вертикальные и панельные макеты. ToolbarOverlay реализует безпараметровый конструктор, который передает EditorToolbarElementAttribute ID. В отличие от накладок панели, содержимое определяется как отдельные части, которые собираются для создания полосы элементов.

При создании наложений панели инструментов:

  • Используйте EditorToolbarElement(Identifier, EditorWindowType) для регистрации элементов панели инструментов для использования в реализации ToolbarOverlay.
  • Пометьте все накладки OverlayAttribute.
  • Убедитесь, что накладки панели инструментов наследуют ToolbarOverlay и реализуют конструктор без параметров.
  • Убедитесь, что содержимое панели инструментов заполнено строкой IDs, которая передается в базовый конструктор.
  • Убедитесь, что IDs определены EditorToolbarElementAttribute.
  • Используйте атрибут Icon, чтобы добавить icon значок к вашему накладному изображению. Значок видим при сжатии накладного изображения. Если накладное изображение не имеет значка, первые две буквы названия накладного изображения (или первые две буквы первых двух слов) отображаются при сжатии накладного изображения.

При реализации элементов, специфических для ToolbarOverlay в накладке:

  • Используйте IAccessContainerWindow интерфейс только для панелей инструментов. Элемент не знает о своём контексте. В DropdownToggleExample, если вы переключите элемент, он ничего не сделает.
  • Используйте стиль UIElement для визуальных эффектов. Элемент панели инструментов не будет иметь свой стиль в накладке.

Чтобы создать наложение панели инструментов:

  1. Создать новый C# скрипт в 2000 году Папка редактора и назвать его.
  2. Откройте созданный скрипт.
  3. Удаление содержимого по умолчанию из скрипта.
  4. Добавить элементы панели инструментов в скрипт.
  5. Добавить элементы панели инструментов в конструктор наложений.
  6. Добавить накладку панели и реализовать элементы панели инструментов.

Пример

Этот пример представляет собой накладку с названием Элемент Панели инструментов Пример, который демонстрирует следующие элементы панели инструментов:

  • EditorToolbarButton
  • EditorToolbarToggle
  • EditorToolbarDropdown
  • EditorToolbarDropdownToggle

Каждый элемент панели инструментов создаётся как отдельный класс и затем добавляется на панель оверлея.

Это наложение:

  • Может быть расположен в виде панели, горизонтально и вертикально.
  • Имеет кнопки, которые включают текст и подсказки.
  • Имеет значки панели инструментов, определенные атрибутом Icon. Этот значок отображается, когда накладка свернута.
    using System.Collections;
    using System.Collections.Generic;
    using System.Text;
    using UnityEngine;
    using UnityEditor.EditorTools;
    using UnityEditor.Toolbars;
    using UnityEditor.Overlays;
    using UnityEngine.UIElements;
    using UnityEditor;

    // Use [EditorToolbarElement(Identifier, EditorWindowType)] to register toolbar elements for use in ToolbarOverlay implementation.

    [EditorToolbarElement(id, typeof(SceneView))]
    class DropdownExample : EditorToolbarDropdown
    {
        public const string id = "ExampleToolbar/Dropdown";

        static string dropChoice = null;

        public DropdownExample()
        {
            text = "Axis";
            clicked += ShowDropdown;
        }

        void ShowDropdown()
        {
            var menu = new GenericMenu();
            menu.AddItem(new GUIContent("X"), dropChoice == "X", () => { text = "X"; dropChoice = "X"; });
            menu.AddItem(new GUIContent("Y"), dropChoice == "Y", () => { text = "Y"; dropChoice = "Y"; });
            menu.AddItem(new GUIContent("Z"), dropChoice == "Z", () => { text = "Z"; dropChoice = "Z"; });
            menu.ShowAsContext();
        }
    }
    [EditorToolbarElement(id, typeof(SceneView))]
    class ToggleExample : EditorToolbarToggle
    {
        public const string id = "ExampleToolbar/Toggle";
        public ToggleExample()
        {
            text = "Toggle OFF";
            this.RegisterValueChangedCallback(Test);
        }

        void Test(ChangeEvent<bool> evt)
        {
            if (evt.newValue)
            {
                Debug.Log("ON");
                text = "Toggle ON";
            }
            else
            {
                Debug.Log("OFF");
                text = "Toggle OFF";
            }
        }
    }

    [EditorToolbarElement(id, typeof(SceneView))]
    class DropdownToggleExample : EditorToolbarDropdownToggle, IAccessContainerWindow
    {
        public const string id = "ExampleToolbar/DropdownToggle";

        // This property is specified by IAccessContainerWindow and is used to access the Overlay's EditorWindow.

        public EditorWindow containerWindow { get; set; }
        static int colorIndex = 0;
        static readonly Color[] colors = new Color[] { Color.red, Color.green, Color.cyan };
        public DropdownToggleExample()
        {
            text = "Color Bar";
            tooltip = "Display a color rectangle in the top left of the Scene view. Toggle on or off, and open the dropdown" +
                      "to change the color.";

        // When the dropdown is opened, ShowColorMenu is invoked and we can create a popup menu.

            dropdownClicked += ShowColorMenu;

        // Subscribe to the Scene view OnGUI callback so that we can draw our color swatch.

            SceneView.duringSceneGui += DrawColorSwatch;
        }

        void DrawColorSwatch(SceneView view)
        {

         // Test that this callback is for the Scene View that we're interested in, and also check if the toggle is on
        // or off (value).

            if (view != containerWindow || !value)
            {
                return;
            }

            Handles.BeginGUI();
            GUI.color = colors[colorIndex];
            GUI.DrawTexture(new Rect(8, 8, 120, 24), Texture2D.whiteTexture);
            GUI.color = Color.white;
            Handles.EndGUI();
        }

        // When the dropdown button is clicked, this method will create a popup menu at the mouse cursor position.

        void ShowColorMenu()
        {
            var menu = new GenericMenu();
            menu.AddItem(new GUIContent("Red"), colorIndex == 0, () => colorIndex = 0);
            menu.AddItem(new GUIContent("Green"), colorIndex == 1, () => colorIndex = 1);
            menu.AddItem(new GUIContent("Blue"), colorIndex == 2, () => colorIndex = 2);
            menu.ShowAsContext();
        }
    }

    [EditorToolbarElement(id, typeof(SceneView))]
    class CreateCube : EditorToolbarButton//, IAccessContainerWindow
    {
        // This ID is used to populate toolbar elements.

        public const string id = "ExampleToolbar/Button";

        // IAccessContainerWindow provides a way for toolbar elements to access the `EditorWindow` in which they exist.
        // Here we use `containerWindow` to focus the camera on our newly instantiated objects after creation.
        //public EditorWindow containerWindow { get; set; }

        // Because this is a VisualElement, it is appropriate to place initialization logic in the constructor.
        // In this method you can also register to any additional events as required. In this example there is a tooltip, an icon, and an action.

        public CreateCube()
        {

    // A toolbar element can be either text, icon, or a combination of the two. Keep in mind that if a toolbar is
        // docked horizontally the text will be clipped, so usually it's a good idea to specify an icon.

            text = "Create Cube";
            icon = AssetDatabase.LoadAssetAtPath<Texture2D>("Assets/CreateCubeIcon.png");
            tooltip = "Instantiate a cube in the scene.";
            clicked += OnClick;
        }

        // This method will be invoked when the `Create Cube` button is clicked.

        void OnClick()
        {
            var newObj = GameObject.CreatePrimitive(PrimitiveType.Cube).transform;

        // When writing editor tools don't forget to be a good citizen and implement Undo!

            Undo.RegisterCreatedObjectUndo(newObj.gameObject, "Create Cube");

        //if (containerWindow is SceneView view)
        //    view.FrameSelected();

        }

    }

    // All Overlays must be tagged with the OverlayAttribute

    [Overlay(typeof(SceneView), "ElementToolbars Example")]

        // IconAttribute provides a way to define an icon for when an Overlay is in collapsed form. If not provided, the name initials are used.

    [Icon("Assets/unity.png")]

    // Toolbar Overlays must inherit `ToolbarOverlay` and implement a parameter-less constructor. The contents of a toolbar are populated with string IDs, which are passed to the base constructor. IDs are defined by EditorToolbarElementAttribute.

    public class EditorToolbarExample : ToolbarOverlay
    {

     // ToolbarOverlay implements a parameterless constructor, passing the EditorToolbarElementAttribute ID.
    // This is the only code required to implement a toolbar Overlay. Unlike panel Overlays, the contents are defined
    // as standalone pieces that will be collected to form a strip of elements.

        EditorToolbarExample() : base(
            CreateCube.id,
            ToggleExample.id,
            DropdownExample.id,
            DropdownToggleExample.id
            )
        { }
    }


Реализация элементов панели инструментов

Управление элементами панели инструментов аналогично их эквиваленту в UIToolkit, но они наследуют некоторые функции панели инструментов и специфический стиль.

В этом разделе приведены примеры следующих элементов панели инструментов:

EditorToolbarButton

EditorToolbarButton — это отдельный класс, содержащий логику элемента. В этом примере создаётся кнопка, которая по щелчку порождает куб:

[EditorToolbarElement(id, typeof(SceneView))]
class CreateCube : EditorToolbarButton
{
// This ID is used to populate toolbar elements.

public const string id = "ExampleToolbar/Button";

// Because this is a VisualElement, it is appropriate to place initialization logic in the constructor.

// In this method you can also register to any additional events as required. In this example there is a tooltip, an icon, and an action.

    public CreateCube()
       {

// A toolbar element can be either text, icon, or a combination of the two. Keep in mind that if a toolbar is docked horizontally the text will be clipped, so it's a good idea to specify an icon.

            text = "Create Cube";
            icon = AssetDatabase.LoadAssetAtPath<Texture2D>("Assets/CreateCubeIcon.png");
            tooltip = "Instantiate a cube in the scene.";
            clicked += OnClick;
}

void OnClick()
{
    var newObj = GameObject.CreatePrimitive(PrimitiveType.Cube).transform;

    // When writing editor tools, don't forget to be a good citizen and implement Undo.

    Undo.RegisterCreatedObjectUndo(newObj.gameObject, "Create Cube");

// Note: Using ObjectFactory class instead of GameObject(like in this example) will register the undo entry automatically removing the need to register manually.

}
}

Добавьте ID элемента в конструктор Overlay:

[Overlay(typeof(SceneView), "ElementToolbar Example")]
[Icon("Assets/unity.png")]
public class EditorToolbarExample : ToolbarOverlay
{
    EditorToolbarExample() : base(CreateCube.id) { }

}

EditorToolbarToggle

Создайте отдельный класс со всей логикой элемента. В этом примере создаётся переключатель, который выводит своё состояние в консоль и обновляет текст в элементе:

[EditorToolbarElement(id, typeof(SceneView))]
class ToggleExample : EditorToolbarToggle
{
    public const string id = "ExampleToolbar/Toggle";
    public ToggleExample()
    {
        text = "Toggle OFF";

    // Register the class to a callback for when the toggle’s state changes

        this.RegisterValueChangedCallback(OnStateChange);
    }

    void OnStateChange(ChangeEvent<bool> evt)
    {
        if (evt.newValue)
        {

    // Put logic for when the state is ON here

                Debug.Log("Toggle State -> ON");
        text = "Toggle ON";
        }
        else
        {

    // Put logic for when the state is OFF here

                Debug.Log("Toggle State -> OFF");
        text = "Toggle OFF";
        }
    }
}

Добавьте ID элемента в конструктор Overlay:

[Overlay(typeof(SceneView), "ElementToolbar Example")]
[Icon("Assets/unity.png")]
public class EditorToolbarExample : ToolbarOverlay
{
    EditorToolbarExample() : base(
ToggleExample.id
) { }

}

EditorToolbarDropdown

Создайте отдельный класс со всей логикой элемента. Вот простой пример выпадающего списка, который меняет свой текст в соответствии с выбранным пунктом.

[EditorToolbarElement(id, typeof(SceneView))]
class DropdownExample : EditorToolbarDropdown
{
    public const string id = "ExampleToolbar/Dropdown";

    static string dropChoice = null;

    public DropdownExample()
    {
        text = "Axis";
        clicked += ShowDropdown;
    }

    void ShowDropdown()
    {

// A simple GenericMenu to populate the dropdown content

        var menu = new GenericMenu();
        menu.AddItem(new GUIContent("X"), dropChoice == "X", () => { text = "X"; dropChoice = "X"; });
        menu.AddItem(new GUIContent("Y"), dropChoice == "Y", () => { text = "Y"; dropChoice = "Y"; });
        menu.AddItem(new GUIContent("Z"), dropChoice == "Z", () => { text = "Z"; dropChoice = "Z"; });
        menu.ShowAsContext();
    }
}

Добавьте ID элемента в конструктор Overlay:

[Overlay(typeof(SceneView), "ElementToolbar Example")]
[Icon("Assets/unity.png")]
public class EditorToolbarExample : ToolbarOverlay
{
    EditorToolbarExample() : base(
DropdownExample.id
) { }

}

EditorToolbarDropdownToggle

Создайте отдельный класс со всей логикой элемента. Выпадающий переключатель — это выпадающий список, который можно переключать, как меню Gizmo в окне Scene. В этом примере в углу окна Scene создаётся прямоугольник, цвет которого выбирается из выпадающего списка в оверлее.

[EditorToolbarElement(id, typeof(SceneView))]
class DropdownToggleExample : EditorToolbarDropdownToggle, IAccessContainerWindow
{
    public const string id = "ExampleToolbar/DropdownToggle";


    // This property is specified by IAccessContainerWindow and is used to access the Overlay's EditorWindow.

    public EditorWindow containerWindow { get; set; }
    static int colorIndex = 0;
    static readonly Color[] colors = new Color[] { Color.red, Color.green, Color.cyan };
    public DropdownToggleExample()
    {
        text = "Color Bar";
        tooltip = "Display a color rectangle in the top left of the Scene view. Toggle on or off, and open the dropdown" +
                "to change the color.";


   // When the dropdown is opened, ShowColorMenu is invoked and you can create a pop-up menu.

        dropdownClicked += ShowColorMenu;


    // Subscribe to the Scene view OnGUI callback to draw a color swatch.

        SceneView.duringSceneGui += DrawColorSwatch;
    }


    void DrawColorSwatch(SceneView view)
    {

        // Test that this callback is for the correct Scene view, and check if the toggle is on
     // or off (value).

        if (view != containerWindow || !value)
        {
            return;
        }


        Handles.BeginGUI();
            GUI.color = colors[colorIndex];
        GUI.DrawTexture(new Rect(8, 8, 120, 24), Texture2D.whiteTexture);
        GUI.color = Color.white;
        Handles.EndGUI();
    }


    // When the drop-down button is clicked, this method creates a pop-up menu at the mouse cursor position.

    void ShowColorMenu()
    {
        var menu = new GenericMenu();
        menu.AddItem(new GUIContent("Red"), colorIndex == 0, () => colorIndex = 0);
        menu.AddItem(new GUIContent("Green"), colorIndex == 1, () => colorIndex = 1);
        menu.AddItem(new GUIContent("Blue"), colorIndex == 2, () => colorIndex = 2);
        menu.ShowAsContext();
    }
}

Добавьте ID элемента в конструктор Overlay:

[Overlay(typeof(SceneView), "ElementToolbar Example")]
[Icon("Assets/unity.png")]
public class EditorToolbarExample : ToolbarOverlay
{
    EditorToolbarExample() : base(
DropdownToggleExample.id
) { }


}