Version: Unity 6.0 (6000.0)
언어 : 한국어
바인딩된 프로퍼티가 변경될 때 콜백 수신
ListView로 리스트에 바인딩

바인딩된 프로퍼티가 변경되면 콜백 수신

버전: 2021.3+

이 예제는 직렬화된 바운드 오브젝트의 프로퍼티가 변경될 때 콜백을 수신하는 방법을 보여 줍니다.

개요 예시

이 예시에서는 두 개의 필드가 있는 커스텀 인스펙터를 생성합니다. 필드 값이 특정 범위를 벗어나면 사용자에게 경고가 표시됩니다.

예시의 완성된 파일은 GitHub 저장소에서 찾을 수 있습니다.

선행 조건

이 가이드는 Unity 에디터, UI 툴킷, C# 스크립팅에 익숙한 개발자를 위한 가이드입니다. 시작하기 전에 먼저 다음을 숙지하십시오.

무기 오브젝트 생성

C# 스크립트를 생성하여 m_BaseDamagem_HardModeModifier 프로퍼티가 있는 MonoBehaviourWeapon 클래스를 정의합니다.

  1. 임의의 템플릿을 사용하여 Unity에서 프로젝트를 생성합니다.

  2. 프로젝트 창에서 파일을 저장할 callback-any-SerializedProperty-changes라는 폴더를 만듭니다.

  3. Weapon.cs라는 이름의 C# 스크립트를 생성하고 해당 콘텐츠를 다음과 같이 바꿉니다.

    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;
            }
        }
    }
    

콜백을 수신하기 위한 바인딩 만들기

Weapon에 대한 커스텀 인스펙터를 정의하고 TrackSerializedObjectValue() 메서드를 사용하여 m_BaseDamagem_HardModeModifier 프로퍼티의 변경 사항을 확인하는 C# 스크립트를 생성합니다.

  1. callback-any-SerializedProperty-changes 폴더에 Editor라는 폴더를 만듭니다.

  2. Editor 폴더에서 WeaponCustomEditor.cs라는 C# 스크립트를 생성하고 해당 콘텐츠를 다음과 같이 바꿉니다.

    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. 씬에서 빈 게임 오브젝트를 만듭니다.

  2. 해당 게임 오브젝트를 선택합니다.

  3. 인스펙터에서 Weapon 컴포넌트를 추가합니다.

  4. Weapon 컴포넌트에서 필드의 값을 다음과 같이 변경합니다.

    • Base Damage 또는 Base DamageHard Mode Modifier를 곱한 값이 음수면 경고 메시지가 표시됩니다.
    • Base Damage 또는 Base DamageHard Mode Modifier를 곱한 값이 9999보다 크면 다른 경고 메시지가 표시됩니다.

추가 리소스

바인딩된 프로퍼티가 변경될 때 콜백 수신
ListView로 리스트에 바인딩