Unity 编辑拓展使用Attribute 实现面板按钮

unity面板按钮工具

测试以及效果
多了个按钮
img

对比
img

(1) 测试代码

代码部分

namespace ColorzoreTools
{
    using System;
    using UnityEngine;
    public class TestAttribute : MonoBehaviour
    {
        [Button("测试")] //实现自定义按钮
        public void TestBtn()
        {
            //这个方法会被注册到ui上
            Debug.Log("执行方法");
        }
    }
}

使用的知识点

特性Attribute 和反射Reflection

特性Attribute : 标记按钮对应的方法

反射Reflection :找到指定类上被标记方法,进行调用

源码


using System;
using System.Linq;
#if UNITY_EDITOR
using UnityEditor;
#endif
using UnityEngine;

namespace ColorzoreTools
{
    /// <summary>
    /// 自定义按钮属性
    /// 只能在方法上运行
    /// [Buttom("方法名称")]
    /// </summary>
    [AttributeUsage(AttributeTargets.Method ,AllowMultiple = false)]
    public class ButtonAttribute:Attribute
    {
        public string buttonName;

        public ButtonAttribute(string buttonName)
        {
            this.buttonName = buttonName;
        }
    }


#if UNITY_EDITOR

    [CustomEditor(typeof(MonoBehaviour),true)]
    public class CustomAttributeDrawer : Editor 
    {
        public override void OnInspectorGUI() 
        {
            base.OnInspectorGUI();

            //获取目标对象
            var mono = target as MonoBehaviour;
            
            if(mono == null)
            {
                return;
            }

            //获取所有的方法
            var methods = mono.GetType()
                .GetMethods(System.Reflection.BindingFlags.Instance | 
                System.Reflection.BindingFlags.Public |
                System.Reflection.BindingFlags.NonPublic);
            
            //遍历方法
            foreach(var method in methods)
            {
                //查找带有ButtonAttribute的方法
                var buttonAttribute = 
                    method.GetCustomAttributes(typeof(ButtonAttribute),true)
                    .FirstOrDefault() as ButtonAttribute;
                
                if(buttonAttribute != null)
                {
                    //绘制按钮
                    if(GUILayout.Button(buttonAttribute.buttonName))
                    {
                        //执行方法
                        method.Invoke(mono,null);
                    }
                }
            }
            
        }
    }
#endif
}


结束

posted @ 2024-06-22 23:39  冷榷  阅读(42)  评论(0编辑  收藏  举报