Unity 编辑器扩展之Attribute特性实现脚本面板控制

很多时候我们写一些公共工具或者通用脚本时,需要跟Unity组件一样实现某些功能,例如Button组件上的Transition选择之后会变化出相对应的模块。那么这个功能怎么实现呢?其实Unity提供了这种功能实现的方法,那就是Attribute标签,标记特性类。想具体知道是怎么实现的可以看下官方文档或者一些关于Attribute的博客。

实现

实现一个通用的鼠标对button移入移出切换图片或者显示/隐藏物体脚本。

首先,把自己要实现的功能脚本写完,我这里写的是对button移入移出的简单脚本

using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.EventSystems;
using UnityEngine.UI;

namespace Util
{
    public enum Mode 
    {
        /// <summary>
        /// UI事件
        /// </summary>
        UISprite,
        
        /// <summary>
        /// 物体隐藏显示
        /// </summary>
        UIObject,
    }
    
    public class UIEnterEvent : MonoBehaviour, IPointerEnterHandler, IPointerExitHandler, IPointerClickHandler
    {
        [Header("选择模式")] [SerializeField] private Mode uiMode; 
        
        //----------Object操作----------------
        [Header("移入时")] [SerializeField] private GameObject enterObj;
        [Header("移出时")] [SerializeField] private GameObject exitObject;
        
        //----------UI操作-----------------------
        [Header("移入时")] [SerializeField] private Sprite enterSpr;
        [Header("移出时")] [SerializeField] private Sprite exitSpr;
        [Header("点击时")] [SerializeField] private Sprite clickSpr;
        
    
        private void OnDisable()
        {
            if (uiMode == Mode.UISprite && exitSpr != null)
            {
                GetComponent<Image>().sprite = exitSpr;
            }
        }
    
        public void OnPointerEnter(PointerEventData eventData)
        {
            if (uiMode == Mode.UISprite && enterSpr != null)
            {
                GetComponent<Image>().sprite = enterSpr;
            }

            if (uiMode == Mode.UIObject && enterObj != null)
            {
                enterObj.SetActive(true);
            }
        }
    
        public void OnPointerExit(PointerEventData eventData)
        {
            if (uiMode == Mode.UISprite && exitSpr != null)
            {
                GetComponent<Image>().sprite = exitSpr;
            }

            if (uiMode == Mode.UIObject && exitObject != null)
            {
                exitObject.SetActive(false);
            }
        }
    
        public void OnPointerClick(PointerEventData eventData)
        {
            if (uiMode == Mode.UISprite && clickSpr != null)
            {
                GetComponent<Image>().sprite = clickSpr;
            }
        }
    }
}

Enum Mode就是等会需要用到切换方式的枚举,通过这个枚举来确定我们这个脚本具体实现的功能。

下面就来定义一个Attribute特性类,因为需要在编辑器下运行所以要写在editor下。

[CustomEditor(typeof(UIEnterEvent))] 定义好这个标签就可以实现想要的功能。

using System;
using UnityEngine;
using UnityEditor;
using Util;

[CustomEditor(typeof(UIEnterEvent))]
public class ComponentInspectorEditor : Editor
{
    private SerializedObject object;
    
    private SerializedProperty _PropertyEnum;

    //OBJ属性
    private SerializedProperty _EnterObj;
    private SerializedProperty _ExitObj;
    
    //UI属性
    private SerializedProperty _EnterSp;
    private SerializedProperty _ExitSp;
    private SerializedProperty _ClickSp;

    private void OnEnable()
    {
        object = new SerializedObject(target);

        _PropertyEnum = object.FindProperty("uiMode");
        
        //obj
        _EnterObj = object.FindProperty("enterObj");
        _ExitObj = object.FindProperty("exitObject");
        
        //ui
        _EnterSp = object.FindProperty("enterSpr");
        _ExitSp = object.FindProperty("exitSpr");
        _ClickSp = object.FindProperty("clickSpr");
    }

    public override void OnInspectorGUI()
    {
        EditorGUILayout.PropertyField(_PropertyEnum);
        //枚举 = UIObject时  打开物体属性面板
        if (_PropertyEnum.enumValueIndex == 1)
        {
            EditorGUILayout.PropertyField(_EnterObj);
            EditorGUILayout.PropertyField(_ExitObj);
        }
        //枚举 = UISprite时  打开UI属性面板
        if (_PropertyEnum.enumValueIndex == 0)
        {
            EditorGUILayout.PropertyField(_EnterSp);
            EditorGUILayout.PropertyField(_ExitSp);
            EditorGUILayout.PropertyField(_ClickSp);
        }

        object.ApplyModifiedProperties();
    }
}

结果

 

猜你喜欢

转载自blog.csdn.net/ThreePointsHeat/article/details/129836452