유니티 인스펙터에서 함수를 실행시키는 간단한 어트리뷰트&에디터 스크립트

[Button]  
    public void PrintMessage()
    {
        Debug.Log(message);
    }

    [Button("Reset Position")]  
    public void ResetPosition()
    {
        transform.position = Vector3.zero;
        Debug.Log("Position Reset!");
    }

    [Button("Print Custom Message")]  
    public void PrintCustomMessage(string message)
    {
        Debug.Log($"Custom Message: {message}");
    }​
using System;
using UnityEngine;

[AttributeUsage(AttributeTargets.Method)]
public class ButtonAttribute : PropertyAttribute
{
    public string Label { get; }

    public ButtonAttribute(string label = null)
    {
        Label = label;
    }
}

어트리뷰트는 에디터 폴더 밖에 작성해도 됩니다.

using UnityEngine;
using UnityEditor;
using System;
using System.Reflection;
using System.Collections.Generic;

[CustomEditor(typeof(MonoBehaviour), true)]
public class ButtonDrawer : Editor
{
    private class MethodData
    {
        public MethodInfo Method;
        public ButtonAttribute Attribute;
        public object[] Parameters;
    }

    private List<MethodData> methods = new List<MethodData>();

    private void OnEnable()
    {
        methods.Clear();
        Type type = target.GetType();

        foreach (MethodInfo method in type.GetMethods(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic))
        {
            var attribute = method.GetCustomAttribute<ButtonAttribute>();
            if (attribute != null)
            {
                methods.Add(new MethodData
                {
                    Method = method,
                    Attribute = attribute,
                    Parameters = new object[method.GetParameters().Length]
                });
            }
        }
    }

    public override void OnInspectorGUI()
    {
        DrawDefaultInspector();
        foreach (var methodData in methods)
        {
            DrawButton(methodData);
        }
    }

    private void DrawButton(MethodData methodData)
    {
        string label = string.IsNullOrEmpty(methodData.Attribute.Label) ? methodData.Method.Name : methodData.Attribute.Label;

        GUILayout.BeginVertical("box");
        GUILayout.Label(label, EditorStyles.boldLabel);

        ParameterInfo[] parameters = methodData.Method.GetParameters();
        for (int i = 0; i < parameters.Length; i++)
        {
            methodData.Parameters[i] = DrawParameterField(parameters[i], methodData.Parameters[i]);
        }

        if (GUILayout.Button(label))
        {
            methodData.Method.Invoke(target, methodData.Parameters);
        }

        GUILayout.EndVertical();
    }

    private object DrawParameterField(ParameterInfo parameter, object value)
    {
        Type type = parameter.ParameterType;
        string paramName = parameter.Name;

        if (type == typeof(int))
            return EditorGUILayout.IntField(paramName, value != null ? (int)value : 0);
        if (type == typeof(float))
            return EditorGUILayout.FloatField(paramName, value != null ? (float)value : 0f);
        if (type == typeof(string))
            return EditorGUILayout.TextField(paramName, value as string ?? "");
        if (type == typeof(bool))
            return EditorGUILayout.Toggle(paramName, value != null && (bool)value);

        GUILayout.Label($"❌ 지원되지 않는 타입: {type.Name}");
        return value;
    }
}

ButtonDrawer스크립트는 반드시 에디터 폴더 안에 작성하셔야 합니다.

 

    [Button]  
    public void PrintMessage()
    {
        Debug.Log(message);
    }

    [Button("Reset Position")]  
    public void ResetPosition()
    {
        transform.position = Vector3.zero;
        Debug.Log("Position Reset!");
    }

    [Button("Print Custom Message")]  
    public void PrintCustomMessage(string message)
    {
        Debug.Log($"Custom Message: {message}");
    }

위 코드는 예시입니다.