Unity 编辑器扩展总结 三:编辑器的相关特性

编辑器扩展总结

工欲善其事必先利其器

引言: 在项目开发中,编辑器扩展为开发者提供了开发自定义工具的功能,让开发者更加便利地使用编辑器开发项目。近期小生一直在学习编辑器扩展的知识,发现网络上关于编辑器知识点的博客较为零散且混乱。当然,有一些大佬已经总结的很好了,小生这就算是狗尾续貂,主要目的为自我学习,近期会整理一系列编辑器相关的博客,分享给每一位在学习道路上奋斗的童鞋。如若博客中存在错误,还请大佬们不吝赐教。所有参考的博客或者视频来源将在文末展示。
开发版本: Unity 2018.1.3f1

相关博客传送门
一、编辑器开发入门

二、Gizmos辅助调试工具

三、编辑器的相关特性

四、自定义Inspector面板

五、数组或list集合的显示方式

编辑器的相关特性

Unity编辑器提供了大量的特性,帮助开发者更加便利地开发项目,这里主要介绍三种类别常用的特性,需要注意一些特性属于System、UnityEngine空间,一些又属于UnityEditor空间,并提供一个自定义属性绘制器的案例。此案例来自泰课的Unity编辑器扩展开发精讲

常用的属性特性

  • [Range(0,100)] //限制数值范围
  • [Multiline(3)] //字符串多行显示
  • [TextArea(2,4)] //文本输入框
  • [SerializeField] //序列化字段,主要用于序列化私有字段
  • [NonSerialized] //反序列化一个变量,并且在Inspector上隐藏
  • [HideInInspector] //public变量在Inspector面板隐藏
  • [FormerlySerializedAs(“Value1”)] //当变量名发生改变时,可以保存原来Value1的值
  • [ContextMenu(“TestBtn”)] //组件右键菜单按钮
  • [ContextMenuItem(“Reset Value”,“Reset”)] //定义属性的右键菜单
  • [Header(“Header Name”)] //加粗效果的标题
  • [Space(10)] //表示间隔空间,数字越大,间隔越大
  • [Tooltip(“Tips”)] //显示字段的提示信息
  • [ColorUsage(true)] //显示颜色面板
[COntextMenuItem("Reset Value","Reset")]
public int intValue = 100;

private void Reset()
{
    intValue = 0;
}

常用的方法特性

  • [DrawGizmo] //用于Gizmos渲染,将逻辑与调试代码分离
  • [MenuItem] //添加菜单项

常用的类的特性

  • [Serializable] //序列化一个类,作为一个子属性显示在监视面板
  • [RequireComponent(typeof(Animator))] //挂载该类的对象,必须要有Animator组件
  • [DisallowMultipleComponent] //不允许挂载多个该类或其子类
  • [ExecuteInEditMode] //允许脚本在编辑器未运行的情况下运行
  • [CanEditMultipleObjects] //允许当选择多个挂有该脚本的对象时,统一修改值
  • [AddComponentMenu] //可以在菜单栏Component内添加组件按钮
  • [CustomEditor] //要自定义编辑器就要加这个特性
  • [CustomPropertyDrawer] //用于绘制自定义PropertyDrawer的特性
  • [SelectionBase] //选择在场景视图中使用此属性的组件对象,即不会误选中子物体

P.S. 多个特性可以用逗号隔开,例如:[SerializeField, Range(0,5)]

自定义属性特性

using UnityEngine;

//定义特性
public class ShowTimeAttribute : PropertyAttribute
{ 
   public readonly bool ShowHour;

   //定义构造函数
   public ShowTimeAttribute(bool isShowHour = false)
   {
       ShowHour = isShowHour;
   }
}
using UnityEngine;
using UnityEditor;

//用于绘制特性,该类需要放到Editor中
[CustomPropertyDrawer(typeof(ShowTimeAttribute))]
public class TimeDrawer : PropertyDrawer
{
    //设置绘制的区域高度
    public override float GetPropertyHeight(SerializedProperty property, GUIContent label)
    {
        return EditorGUI.GetPropertyHeight(property) * 2;
    }
    
    public override void OnGUI(Rect position, SerializedProperty property, GUIContent label)
    {
        if (property.propertyType == SerializedPropertyType.Integer)
        {
            property.intValue = EditorGUI.IntField(new Rect(position.x, position.y, position.width, position.height / 2), label, Mathf.Max(0, property.intValue));

            EditorGUI.LabelField(new Rect(position.x, position.y + position.height / 2, position.width, position.height / 2), "", TimeConvert(property.intValue));
        }
        else
        {
            EditorGUI.HelpBox(position, "To use the Time Atribute," + label.ToString() + "must be int", MessageType.Error);
        }
    }

    private string TimeConvert(int value)
    {
        ShowTimeAttribute time = attribute as ShowTimeAttribute;
        if (time != null)
        {
            if (time.ShowHour)
            {
                int hours = value / (60 * 60);
                int minutes = (value % (60 * 60)) / 60;
                int seconds = value % 60;

                return string.Format("{0}:{1}:{2}(H:M:S)", hours, minutes.ToString().PadLeft(2, '0'), seconds.ToString().PadLeft(2, '0'));
            }
        }
        else
        {
            int minutes = (value % (60 * 60)) / 60;
            int seconds = value % 60;

            return string.Format("{0}:{1}(M:S)", minutes.ToString().PadLeft(2, '0'), seconds.ToString().PadLeft(2, '0'));
        }
        return string.Empty;
    }
}
//测试
public class Test : MonoBehaviour
{
    [ShowTime(true)]
    public int time = 3605;
}

参考资料

Unity 特性(Attribute)总览

猜你喜欢

转载自blog.csdn.net/qq_35361471/article/details/84715294