unity/유니티 Tools

Unity Tool - 버튼 attribute 만들기

rimugiri 2024. 10. 25. 17:43
728x90

코드를 실행할때 플레이 버튼을 눌러 실행하는 것이 불편하여 Edior 기능을 알게되어 InspectorUI를 그동안 활용하고 있었다.

 

하지만 이것의 문제점은 그때마다 Edior 스크립트를 만들어 줘야되고 이를 또 Edior 파일에 넣어줘야 빌드가 완료되는것이 너무 귀찮았다. 그래서 떠올른 것이 [Serializable] 같은 어트리 뷰트로 Button을 만들면 되지 않을까 라는 생각이였고 확인해 보니 다른 분들도 많이 이를 활용하는 것으로 보여졌다

 

1. 기초 구조 제작하기

- 어떤 매개변수들을 적용할지 어떤 매소드를 대상으로 동작할 지 선언해 준다

- 현재 이름을 통해 에디터 상에 나올 이름을 표시할 수 있게 해주고 모드를 선택하여 test용도로만 사용가능할수 있도록 만들어 주었다

using System;
using UnityEngine;

namespace PKW_Attributes
{
    public enum ButtonEnableMode
    {
        // 항상
        Always,
        // 에디터 상에서만
        Editor,
        // Playmode 상에서만
        Playmode
    }

    // 하나의 매소드를 대상으로 동작
    [AttributeUsage(AttributeTargets.Method, AllowMultiple = false, Inherited = true)]
    public class ButtonAttribute : PropertyAttribute
    {
        public string ButtonName { get; }
        public System.Object[] Parameter { get; private set; }
        public ButtonEnableMode ButtonEnableMode { get; private set; }

        public ButtonAttribute(string buttonName = "", ButtonEnableMode ButtonEnableMode = ButtonEnableMode.Always)
        {
            this.ButtonName = buttonName;
            this.ButtonEnableMode = ButtonEnableMode;
        }

        public ButtonAttribute(string _buttonName = "", params System.Object[] _parameter)
        {
            this.ButtonName = _buttonName;
            this.Parameter = _parameter;
        }
    }
}

 

2. Button Attribute 제작

- 현재 Mode는 적용이 되어있지 않은데 GUI.enabled를 통해 이를 구현하는 것보다 좀더 효율적인 방법이 있으면 적용하고 없으면 추후 삭제할 수 도 있을거 같다

using System;
using System.Reflection;
using UnityEditor;
using UnityEngine;
namespace PKW_Attributes
{
    [CustomEditor(typeof(MonoBehaviour), true)]
    public class ButtonAttributeEditor : Editor
    {
        private MonoBehaviour monoBehaviour;
        private void OnEnable()
        {
            monoBehaviour = target as MonoBehaviour;
        }
        public override void OnInspectorGUI()
        {
            // 원래 존재하는 Inspector를 그린다
            base.OnInspectorGUI();
            // 모든 매소드를 확인해 본다
            MethodInfo[] methods = monoBehaviour.GetType().GetMethods(BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public);

            foreach (MethodInfo method in methods)
            {
                ButtonAttribute buttonAttribute = Attribute.GetCustomAttribute(method, typeof(ButtonAttribute)) as ButtonAttribute;

                if (buttonAttribute != null)
                {
                    // 버튼 이름 설정
                    string buttonLabel = string.IsNullOrEmpty(buttonAttribute.ButtonName) ? method.Name : buttonAttribute.ButtonName;

                    if (GUILayout.Button(buttonLabel))
                    {
                        method.Invoke(monoBehaviour, buttonAttribute.Parameter);
                    }
                }
            }
        }
    }
}

 

3. Test 코드

using UnityEngine;

namespace PKW_Attributes
{
    public class ButtonAttributeTest : MonoBehaviour
    {
        public int testInt = 0;
        [SerializeField]

        [Button("TestMethod")]
        public void TestMethod()
        {
            Debug.Log("TestMethod");
        }

        [Button("TestMethod2", "Hello")]
        public void TestMethod2(string _test)
        {
            Debug.Log(_test);
        }

        [Button("TestMethod3")]
        public void TestMethod3()
        {
            testInt++;
            Debug.Log("TestMethod3");
        }
    }
}

 

 

후기 

추후 다양한 어트리뷰트를 작성하려면 상위 클래스를 만들어서 통합해 봐야겠다

 

 

PKW_Tools/PKW_Attributes at main · gunwonpark/PKW_Tools

MYOwnTools. Contribute to gunwonpark/PKW_Tools development by creating an account on GitHub.

github.com

 

728x90