Unity 6.3
0 онлайн 77 гостей 3 в системе
Вход

Используйте Painter2D API для создания радиального индикатора прогресса

Версия: 2023.2+

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

Примерный обзор

В этом примере создается пользовательский контроллер, отображающий прогресс, в качестве альтернативы строке загрузки. Индикатор прогресса отображает значение прогресса в частично заполненном кольце вокруг метки, отображающей процент. Он поддерживает значение от 0 до 100, которое определяет, насколько кольцо заполнено.

Радиальное управление с прогрессом выделен зеленым цветом, и число 87% отображается в центре радиального управления.
Радиальное управление с прогрессом выделен зеленым цветом, и число 87% отображается в центре радиального управления.

Вы можете найти завершенные файлы, созданные этим примером, в хранилище GitHub.

Предварительные условия

Это руководство предназначено для разработчиков, знакомых со скриптами Unity Editor, UI Toolkit и C#. Перед началом работы ознакомьтесь со следующим:

Создание радиального контроля прогресса и его пользовательской сетки

Создайте скрипт C# для определения визуального элемента RadialProgress и скрипт C# для определения пользовательской сетки. Стиль визуального элемента в файле USS.

  1. Создайте проект Unity с любым шаблоном.
  2. Создайте папку radial-progress для хранения ваших файлов.
  3. В папке radial-progress создайте скрипт C# с именем RadialProgress.cs со следующим содержанием:
using Unity.Collections;
using UnityEngine;
using UnityEngine.UIElements;

namespace MyGameUILibrary
{

    // An element that displays progress inside a partially filled circle
    [UxmlElement]
    public partial class RadialProgress : VisualElement
    {

        // These are USS class names for the control overall and the label.
        public static readonly string ussClassName = "radial-progress";
        public static readonly string ussLabelClassName = "radial-progress__label";

        // These objects allow C# code to access custom USS properties.
        static CustomStyleProperty<Color> s_TrackColor = new CustomStyleProperty<Color>("--track-color");
        static CustomStyleProperty<Color> s_ProgressColor = new CustomStyleProperty<Color>("--progress-color");

        Color m_TrackColor = Color.gray;
        Color m_ProgressColor = Color.red;

        // This is the label that displays the percentage.
        Label m_Label;

        // This is the number that the Label displays as a percentage.
        float m_Progress;

        // A value between 0 and 100
        [UxmlAttribute]
        public float progress
        {
            // The progress property is exposed in C#.
            get => m_Progress;
            set
            {
                // Whenever the progress property changes, MarkDirtyRepaint() is named. This causes a call to the
                // generateVisualContents callback.
                m_Progress = value;
                m_Label.text = Mathf.Clamp(Mathf.Round(value), 0, 100) + "%";
                MarkDirtyRepaint();
            }
        }

        // This default constructor is RadialProgress's only constructor.
        public RadialProgress()
        {
            // Create a Label, add a USS class name, and add it to this visual tree.
            m_Label = new Label();
            m_Label.AddToClassList(ussLabelClassName);
            Add(m_Label);

            // Add the USS class name for the overall control.
            AddToClassList(ussClassName);

            // Register a callback after custom style resolution.
            RegisterCallback<CustomStyleResolvedEvent>(evt => CustomStylesResolved(evt));

            // Register a callback to generate the visual content of the control.
            generateVisualContent += GenerateVisualContent;

            progress = 0.0f;
        }

        static void CustomStylesResolved(CustomStyleResolvedEvent evt)
        {
            RadialProgress element = (RadialProgress)evt.currentTarget;
            element.UpdateCustomStyles();
        }

        // After the custom colors are resolved, this method uses them to color the meshes and (if necessary) repaint
        // the control.
        void UpdateCustomStyles()
        {
            bool repaint = false;
            if (customStyle.TryGetValue(s_ProgressColor, out m_ProgressColor))
                repaint = true;

            if (customStyle.TryGetValue(s_TrackColor, out m_TrackColor))
                repaint = true;

            if (repaint)
                MarkDirtyRepaint();
        }

        void GenerateVisualContent(MeshGenerationContext context)
        {
            float width = contentRect.width;
            float height = contentRect.height;

            var painter = context.painter2D;
            painter.lineWidth = 10.0f;
            painter.lineCap = LineCap.Butt;

            // Draw the track
            painter.strokeColor = m_TrackColor;
            painter.BeginPath();
            painter.Arc(new Vector2(width * 0.5f, height * 0.5f), width * 0.5f, 0.0f, 360.0f);
            painter.Stroke();

            // Draw the progress
            painter.strokeColor = m_ProgressColor;
            painter.BeginPath();
            painter.Arc(new Vector2(width * 0.5f, height * 0.5f), width * 0.5f, -90.0f, 360.0f * (progress / 100.0f) - 90.0f);
            painter.Stroke();
        }
    }
}

Стиль настраиваемого контроля

Создайте файл USS с именем RadialProgress.uss со следующим содержимым:

.radial-progress {
        min-width: 26px;
        min-height: 20px;
        --track-color: rgb(130, 130, 130);
        --progress-color: rgb(46, 132, 24);
        --percentage-color: white;
        margin-left: 5px;
        margin-right: 5px;
        margin-top: 5px;
        margin-bottom: 5px;
        flex-direction: row;
        justify-content: center;
        width: 100px; 
        height: 100px;
    }

    .radial-progress__label {
        -unity-text-align: middle-left;
        color: var(--percentage-color);
    }

Используйте пользовательский элемент управления в UI Документ и тест

Используйте UI Builder для добавления элемента управления и применения таблицы стилей USS. Проверьте элемент управления с различными значениями Progress.

  1. Создать UI Документ с именем RadialProgressExample.uxml.
  2. Дважды щелкните RadialProgressExample.uxml, чтобы открыть его в UI Builder.
  3. В окне Библиотека выберите Project > Пользовательские элементы управления > UxmlSerializedData > MyUILibrary.
  4. Перетащите RadialProgress в окно Hierarchy.
  5. В разделе StyleSheets UI Builder добавить RadialProgress.uss в качестве существующего USS..
  6. В окне Hierarchy выберите RadialProgress.
  7. В окне Inspector введите radial-progress в поле Имя.
  8. В окне Inspector введите различные значения в поле Прогресс. Процент в окне Видовой проем изменяется, и зеленое кольцо прогресса изменяет размер.

Создание логики для обновления прогресса с динамическими значениями

Создайте скрипт C# MonoBehaviour для обновления свойства Progress управления динамическими значениями для демонстрационных целей. В папке radial-progress создайте скрипт C# MonoBehaviour с именем RadialProgressComponent.cs со следующим содержанием:

using MyUILibrary;
using UnityEngine;
using UnityEngine.UIElements;

[RequireComponent(typeof(UIDocument))]
public class RadialProgressComponent : MonoBehaviour
{
    RadialProgress m_RadialProgress;

    void OnEnable()
    {
        var root = GetComponent<UIDocument>().rootVisualElement;

        m_RadialProgress = new RadialProgress() {
            style = {
                position = Position.Absolute,
                left = 20, top = 20, width = 200, height = 200
            }
        };

        root.Add(m_RadialProgress);
    }

    void Update()
    {
        m_RadialProgress.progress = ((Mathf.Sin(Time.time) + 1.0f) / 2.0f) * 60.0f + 10.0f;
    }
}

Проверка индикатора прогресса во время выполнения

  1. В Unity выберите GameObject > UI Toolkit > UI Документ.
  2. Выберите UIDocument в окне Hierarchy.
  3. Добавить RadialProgressComponent.cs в качестве компонента UIDocument GameObject.
  4. Введите режим воспроизведения. Индикатор прогресса появляется в сцене, и кольцо прогресса и значение изменяются динамически.

Дополнительные ресурсы