본문 바로가기
개발/Unity

Unity)Attribute) Serialized field Update/Change Callback(Editor 값 변경시 호출)

by 테샤르 2022. 8. 17.

Serialized field Update/Change Callback(Editor 값 변경시 호출)

Serialized Field를 변경하면 자동으로 해당 값이 변경되는것을 제약하고 싶었다.

이번에 작업하는 코드에서 Size라는 항목을 변경하면 m_data라는 Bool 배열을 자동으로 처리하는 코드이다.

 

반응형

<사용방법>

OnChangedCall( 호출할 메소드 ) 형태로 가능하다.

 [OnChangedCall("Resize")]
    [SerializeField, Range(3, 20)]
    private int Size;
    
    
    
    public void Resize()
    {
        m_data = new bool[size * size];
    }

<OnChangedCallAttribute>

using System.Linq;
using UnityEngine;
using UnityEditor;

public class OnChangedCallAttribute : PropertyAttribute
{
    public string methodName;
    public OnChangedCallAttribute(string methodNameNoArguments)
    {
        methodName = methodNameNoArguments;
    }
}

#if UNITY_EDITOR

[CustomPropertyDrawer(typeof(OnChangedCallAttribute))]
public class OnChangedCallAttributePropertyDrawer : PropertyDrawer
{
    public override void OnGUI(Rect position, SerializedProperty property, GUIContent label)
    {
        EditorGUI.BeginChangeCheck();
        EditorGUI.PropertyField(position, property, label);
        if (!EditorGUI.EndChangeCheck()) return;

        var targetObject = property.serializedObject.targetObject;

        var callAttribute = attribute as OnChangedCallAttribute;
        var methodName = callAttribute?.methodName;

        var classType = targetObject.GetType();
        var methodInfo = classType.GetMethods().FirstOrDefault(info => info.Name == methodName);

        // Update the serialized field
        property.serializedObject.ApplyModifiedProperties();

        // If we found a public function with the given name that takes no parameters, invoke it
        if (methodInfo != null && !methodInfo.GetParameters().Any())
        {
            methodInfo.Invoke(targetObject, null);
        }
        else
        {
            // TODO: Create proper exception
            Debug.LogError($"OnChangedCall error : No public function taking no " +
                           $"argument named {methodName} in class {classType.Name}");
        }
    }
}

 

테스트한 영상은 다음과 같다.

 

 

Extending the Unity Editor for the Observable Pattern : [링크]

 

Extending the Unity Editor for the Observable Pattern - Alexander van der Zalm

A solution that allows methods to be called when a value is changed in the Unity3D Editor Inspector. Making a reactive/observable pattern possible.

alexandervanderzalm.com

stackoverflow : [링크]

 

unity - how to update an object when a serialized field is changed?

I'm sure the question is already out there but I cannot find it, sorry. I'm trying to sync a Serialized field of an object with other of its components. let's say I have a field "size" wh...

stackoverflow.com

 

 

★☆☆☆☆

 

반응형

댓글