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

Получение обратных вызовов при изменении связанных свойств

Версия: 2021.3+

Примеры демонстрируют, как получать обратные вызова, когда изменяются какие-либо свойства связанного серийного объекта.

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

Этот пример создает пользовательский Inspector с двумя полями. Он предупреждает пользователя, если значения полей выходят за определенные диапазоны.

Настраиваемый Inspector, который отображает текстовое предупреждение в Unity Editor.
Настраиваемый Inspector, который отображает текстовое предупреждение в Unity Editor.

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

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

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

Создание объекта «Оружие»

Создайте скрипт C#, описывающий класс Weapon как MonoBehaviour с двумя свойствами: m_BaseDamage и m_HardModeModifier.

  1. Создайте проект в Unity с любым шаблоном.

  2. В окне Project создайте папку callback-any-SerializedProperty-changes для хранения ваших файлов.

  3. Создайте скрипт C# с именем Weapon.cs и замените его содержимое следующим:

    using UnityEngine;
    
    namespace UIToolkitExamples
    {
        public class Weapon : MonoBehaviour
        {
            public const float maxDamage = 9999f;
    
            [SerializeField]
            float m_BaseDamage;
    
            [SerializeField]
            float m_HardModeModifier;
    
            public float GetDamage(bool hardMode)
            {
                return hardMode ? m_BaseDamage * m_HardModeModifier : m_BaseDamage;
            }
        }
    }
    

Создание привязки для получения обратных вызовов

Создайте скрипт C#, определяющий пользовательский Inspector для Weapon и использующий метод TrackSerializedObjectValue() для проверки изменений в свойствах m_BaseDamage и m_HardModeModifier.

  1. В течение callback-любой-SerializedProperty- изменения папка, создать папку с названием Editor.

  2. В течение Редактор папка, создать C# скрипт назван WeaponCustomEditor.cs и заменить его содержание следующим:

    using UnityEngine;
    using UnityEditor;
    using UnityEngine.UIElements;
    using UnityEditor.UIElements;
    
    namespace UIToolkitExamples
    {
        [CustomEditor(typeof(Weapon))]
        public class WeaponCustomEditor : Editor
        {
            // This is text used for the warning labels.
            const string k_NegativeWarningText =
                "This weapon has a negative final damage on at least 1 difficulty level.";
            static readonly string k_DamageCapWarningText =
                "This weapon has an excessive final damage that is capped to " + Weapon.maxDamage +
                " on at least 1 difficulty level.";
    
            // These are labels to warn users about negative damage and excessive damage.
            Label m_NegativeWarning, m_DamageCapWarning;
    
            public override VisualElement CreateInspectorGUI()
            {
                VisualElement root = new();
    
                // Create FloatFields for serialized properties.
                var baseDamageField = new FloatField("Base Damage") { bindingPath = "m_BaseDamage" };
                var modifierField = new FloatField("Hard Mode Modifier") { bindingPath = "m_HardModeModifier" };
                root.Add(baseDamageField);
                root.Add(modifierField);
    
                // Create warning labels and style them so they stand out.
                var warnings = new VisualElement();
                m_NegativeWarning = new(k_NegativeWarningText);
                m_DamageCapWarning = new(k_DamageCapWarningText);
                warnings.style.color = Color.red;
                warnings.style.unityFontStyleAndWeight = FontStyle.Bold;
                warnings.Add(m_NegativeWarning);
                warnings.Add(m_DamageCapWarning);
                root.Add(warnings);
    
                // Determine whether to show the warnings at the start.
                CheckForWarnings(serializedObject);
    
                // Whenever any serialized property on this serialized object changes its value, call CheckForWarnings.
                root.TrackSerializedObjectValue(serializedObject, CheckForWarnings);
    
                return root;
            }
    
            // Check the current values of the serialized properties to either display or hide the warnings.
            void CheckForWarnings(SerializedObject serializedObject)
            {
                // For each possible damage values of the weapon, determine whether it's negative and whether it's above the
                // maximum damage value.
                var weapon = serializedObject.targetObject as Weapon;
                var damages = new float[] { weapon.GetDamage(true), weapon.GetDamage(false) };
                var foundNegativeDamage = false;
                var foundCappedDamage = false;
                foreach (var damage in damages)
                {
                    foundNegativeDamage = foundNegativeDamage || damage < 0;
                    foundCappedDamage = foundCappedDamage || damage > Weapon.maxDamage;
                }
    
                // Display or hide warnings depending on the values of the damages.
                m_NegativeWarning.style.display = foundNegativeDamage ? DisplayStyle.Flex : DisplayStyle.None;
                m_DamageCapWarning.style.display = foundCappedDamage ? DisplayStyle.Flex : DisplayStyle.None;
            }
        }
    }
    

Проверка привязки

  1. Создайте пустой GameObject в сцене.

  2. Выберите GameObject.

  3. Добавить компонент Оружие в Inspector.

  4. В течение Оружие компонент, измените значения в полях:

    • Если Базовое Ущерб или Базовое Ущерб умноженное на Модификатора Трудного Режима является отрицательным, появляется предупреждение.
    • Если Базовый Урон или Базовый Урон умножен на Модификатора Трудного Режима больше 9999, появляется другое предупреждение.

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