Unity编辑器扩展插件 Odin Inspector 全特性介绍


简介

Odin已经可以说是非常出名了,深受广大开发者喜爱,AssetStore上买的也挺多的,非常好用的Unity编辑器拓展插件,它的很多特性可以使我们的Inspector面板变得更加直观易用。

本次介绍的时Odin的3.0.8.0版本,也就是最新版本的所有特性的功能。

请添加图片描述

第一部分

1.AssetsOnly / SceneObjectsOnly

标记在物体的属性上,用来限制物体的来源,用AssetsOnly标记的只能从资源目录中取,反之用SceneObjectsOnly标记的只能从场景中取,代码如下

    [AssetsOnly]
    public GameObject assetObject;
    [SceneObjectsOnly]
    public GameObject sceneObject;

2.CustomValueDrawer

使用一个自定义的静态方法来绘制属性,不是很常用

    [CustomValueDrawer("MyCustomDrawerStatic")]
    public float CustomTest;
    private static float MyCustomDrawerStatic(float value,GUIContent label)
    {
    
    
        return EditorGUILayout.Slider(label,value,0,10);
    }

3.DelayedProperty

延迟赋值,在失去焦点后会触发值改变的方法,拖拽调整时不会触发,这个用起来还是挺方便的,有点像InputField的Finish

    [Delayed]
    public int DelayValue;
    [ShowInInspector,DelayedProperty]
    public int DelayProperty {
    
     get; set; }

4.DetailedInfoBox

可以折叠的细节信息描述盒子,用来描述Inspector上暴露出的参数的作用。用到的时候也不多

    [DetailedInfoBox("敌人攻击力","敌人每次普通攻击造成的伤害")]
    public int enemyAttack;

动图封面

5.EnableGUI

激活属性,但还是会受到属性修改器的限制,我也不怎么用

    [ShowInInspector]
    public int DisableProp1 {
    
     get; }
    [ShowInInspector,EnableGUI]
    public int DisableProp2 {
    
     get;}
    [ShowInInspector, EnableGUI]
    public int DisableProp3 {
    
     get; set; }

动图封面

6.GUIColor

改变颜色,这个很常用,可以改变属性的颜色,用来分类,提示什么的再好不过了

    [GUIColor(.5f, 1, 0, 1)]
    public int health;
    [GUIColor(0, .5f, 1f, 1)]
    public int power;
    [GUIColor(1, .5f, 0, 1)]
    public int attack;

7.HideLable

隐藏标签,偶尔会用,我一般会和"LabelText"合在一起用

    [HideLabel][LabelText("玩家ID")]
    public string PlayerId;

8.PropertyOrder

强制调整属性的显示顺序,也还挺好用的

    [PropertyOrder(2)]
    public string player2Name;
    [PropertyOrder(1)]
    public string player1Name;

9.PropertySpace

属性间隔,相当与排版中的行间距,用来对不同类型的属性进行分割比较有效

    public string TypeA1, TypeA2, TypeA3;
    [PropertySpace]
    public string TypeB1;
    public string TypeB2;

10.ReadOnly

只读属性,用来显示一些不想被修改的属性,用来查看或测试,我经常使用

    [ReadOnly]
    public string player1Name="KDF";
    public string player2Name="KKK";

11.Required

需求,强提醒,没有会有报错提示,我一般不用,看着报错有点难受。。

    [Required]
    public string MessageId;

动图封面

12.Searchable

可搜索的,好用!!!,当列表中管理的数据较多时,可以快速进行查找,方便操作

    [Searchable]
    public List<SearchItem> itemList;
    [Serializable]
    public class SearchItem
    {
    
    
        public string Id;
        public string Name;
        public int Age;
    }

动图封面

13.ShowInInspector

强制显示,可以将属性显示到面板上,上面已经用过了

14.Title

标题,就是标题

    [Title("基础属性")]
    public string Health;
    public string Attack;
    public string Power;
    [Title("特有属性")]
    public float moveSpeed;

15.TypeFilter

按我的理解来讲就是通过基类显示子类,我从来没有用过,,

官方提供的实例代码

    [TypeFilter("GetFilteredTypeList")]
    public BaseClass A, B;

    [TypeFilter("GetFilteredTypeList")]
    public BaseClass[] Array = new BaseClass[3];

    public IEnumerable<Type> GetFilteredTypeList()
    {
    
    
        var q = typeof(BaseClass).Assembly.GetTypes()
            .Where(x => !x.IsAbstract)                                          // Excludes BaseClass
            .Where(x => !x.IsGenericTypeDefinition)                             // Excludes C1<>
            .Where(x => typeof(BaseClass).IsAssignableFrom(x));                 // Excludes classes not inheriting from BaseClass

        // Adds various C1<T> type variants.
        q = q.AppendWith(typeof(C1<>).MakeGenericType(typeof(GameObject)));
        q = q.AppendWith(typeof(C1<>).MakeGenericType(typeof(AnimationCurve)));
        q = q.AppendWith(typeof(C1<>).MakeGenericType(typeof(List<float>)));

        return q;
    }

    public abstract class BaseClass
    {
    
    
        public int BaseField;
    }

    public class A1 : BaseClass {
    
     public int _A1; }
    public class A2 : A1 {
    
     public int _A2; }
    public class A3 : A2 {
    
     public int _A3; }
    public class B1 : BaseClass {
    
     public int _B1; }
    public class B2 : B1 {
    
     public int _B2; }
    public class B3 : B2 {
    
     public int _B3; }
    public class C1<T> : BaseClass {
    
     public T C; }

动图封面

16.TypeInfoBox

又是一个提示信息盒子,不过他是可以标记在类上,而不是必须标记到变量上

    [HideLabel]
    public Student st;
    [Serializable,TypeInfoBox("学生基本信息")]
    public class Student
    {
    
    
        public string Name;
        public int Score;
    }

17.ValidateInput

输入验证,可以验证你输入的值,并且给出反馈

    [ValidateInput("CheckPlayerAge","",InfoMessageType.Error)]
    public int playerAge;

    public bool CheckPlayerAge(int age,ref string errorMessage,ref InfoMessageType? messageType)
    {
    
    
        errorMessage = "角色未成年";
        return age >= 18;
    }

动图封面

18.ValueDropDown

下拉列表,像是枚举类型的显示形式,这里可以将数组或者其他带有枚举器的值以这种方式显示出来。

    [ValueDropdown("PlayerLevel")]
    public int playerLevel;
    public static List<int> PlayerLevel = new List<int>() {
    
    1,2,3,4 };

以上是Odin的一部分基础节点,有插件的同学也可以把它导入到Unity中然后通过

Tools–>OdinInspector–>Attribute Overview 查看


第二部分

1.Button

可以说是最常用的特性了,没有之一!!,标注到方法上可以快速实现点击执行

    public int value;
    [Button("改变值",ButtonSizes.Large)]
    public void ShowName()
    {
    
    
        value++;
    }

动图封面

2.ButtonGroup

一组横向排布的按钮,也可以用HorizontalGroup实现(后面会介绍)

    [Button("Show1"), ButtonGroup]
    public void ShowValue1() {
    
     }
    [Button("Show2"), ButtonGroup]
    public void ShowValue2() {
    
     }
    [Button("Show3"), ButtonGroup]
    public void ShowValue3() {
    
     }

3.EnumPaging

分页显示枚举类型,没怎么用过

    [EnumPaging]
    public SubjectType st;
    public enum SubjectType {
    
    English,Math,Arts}

动图封面

4.EnumToggleButton

将枚举值以一排按钮的形式显示出来,

    [EnumToggleButtons]
    public SubjectType st;
    public enum SubjectType {
    
    English,Math,Arts}

动图封面

5.InlineButton

跟在变量后面显示按钮,这个我比较常用,我通常用来做重置按钮和加载按钮了

    [InlineButton("Reset")]
    public StudentScore ss;
    public void Reset()
    {
    
    
        ss = new StudentScore();
    }
    [Serializable]
    public class StudentScore
    {
    
    
        public float math = 100;
        public float english = 50;
        public float arts = 100;
    }

动图封面

6.ResponsiveButtonGroup

根据布局的空间自动适配按钮的位置和大小,不怎么常用,大概效果是这样的

动图封面

7.DictionaryDrawerSettings

在Inspector上显示字典,这个比较特殊,需要用到Odin的序列化功能才行,而且字典所在的脚本必须继承Odin序列化后的SerializedMonoBehaviour

public class OdinTest : SerializedMonoBehaviour
{
    
    
    [DictionaryDrawerSettings]
    public Dictionary<string, float> StudentDict = new Dictionary<string, float>();
}

然后Unity编译后会出现如下提示信息,点击隐藏即可

动图封面

为字典添加值时还有不能添加重复键的显示,非常人性化。

8.ListDrawerSettings

list的渲染,还行,

另外提一句,Odin导入到Unity后默认数组或者List都可以拖拽改变元素的顺序,这个功能很好用,也可以手动关掉拖拽功能

    [ListDrawerSettings(ShowIndexLabels =true)]
    public List<Student> studentList = new List<Student>();
    [ListDrawerSettings(ShowIndexLabels = true,DraggableItems =false)]
    public List<Student> studentList1 = new List<Student>();
    [Serializable]
    public class Student
    {
    
    
        public string name;
        public int Id;
        public float score;
    }

动图封面

9.TableList

将List以表的形式显示出来,表头为属性名字,还可以手动切换显示模式,好用!!

    [TableList]
    public List<Student> studentList = new List<Student>();
    [TableList,TableColumnWidth(20,Resizable =false)]
    [Serializable]
    public class Student
    {
    
    
        public string name;
        public int Id;
        public float score;
    }

动图封面

10.TableColumnWidth

设置表的列宽,并且限制拖拽宽度,跟上面的一起使用

    [TableList]
    public List<Student> studentList = new List<Student>();
    [Serializable]
    public class Student
    {
    
    
        [TableColumnWidth(50,Resizable =false)]
        public string name;
        public int Id;
        public float score;
    }

动图封面

11.TableMatrix

又是一个需要用到Odin自带的序列化工具的特性,脚本类也需要继承SerializedMonoBehaviour,可以将二维数组转化为表的显示形式

    [TableMatrix(SquareCells = false)]
    public int[,] MapData = {
    
    
        {
    
     1,1,1,0} ,
        {
    
     1,1,0,1},
        {
    
     1,0,1,1},
        {
    
     0,1,1,1}
    };

动图封面


第三部分

书接上回,继续Odin的特性介绍

一、基本的条件特性

1.DisableIf, EnableIf, HideIf, ShowIf

根据名字很容易看出了,分别是冻结,激活,隐藏,显示

使用的时候后面接上条件即可,条件可以是Bool类型的变量,枚举类型的变量,返回Bool值的表达式,或者返回Bool值的方法名

首先是Bool变量

    public bool AAA;
    [DisableIf("AAA")]
    public string DisableWhenA;
    [EnableIf("AAA")]
    public string EnableWhenA;
    [HideIf("AAA")]
    public string HideWhenA;
    [ShowIf("AAA")]
    public string ShowWhenA;

动图封面

简单描述一下

AAA为True时,

DisableWhenA检测条件通过被冻结

EnableWhenA检测条件通过被激活

HideWhenA检测条件通过被隐藏

ShowWhen检测条件通过显示了出来

AAA为False时,

DisableWhenA检测条件未通过被激活

EnableWhenA检测条件未通过被冻结

HideWhenA检测条件未通过显示出来

ShowWhen检测条件未通过没显示出来

接下来时枚举类型,这个比较简单,枚举值相同就是检测通过

    public enum SubjectType {
    
     Math,English,Arts}
    public SubjectType sType;

    [ShowIf("sType", SubjectType.Math)]
    public int mathScore;
    [ShowIf("sType", SubjectType.English)]
    public int EnglishScore;
    [ShowIf("sType", SubjectType.Arts)]
    public int ArtsScore;

动图封面

表达式和方法就一起介绍啦

    [EnableIf("@1==2")]
    public string Show1;

    [EnableIf("Show2Method")]
    public string Show2;

    private bool Show2Method()
    {
    
    
        return false;
    }

二、高级的条件特性

这些条件都是与物体在UnityEditor中的状态有关的

Odin将UnityEditor中的物体分为了几种状态,分别是

Editor Mode–Unity编辑器的非运行状态

Inline Editors–Object预览状态(这个可能不太好理解,往下看就可以)

NonPrefabs–不来自预制体

PlayMode–Unity的运行状态

PrefabAssets–预制体资源中,资源

Prefab Instances–预制体的实例,场景

Prefabs–预制体中,场景和资源

1.DisableInEditorMode,HideInEditorMode

在非运行状态下冻结或隐藏,编辑器运行起来后可以修改

默认状态下属性被冻结

运行起来后被激活

2.DisableInInlineEditors,ShowInInlineEditors

这个需要先解释下InlineEditor,它可以将继承了UnityEngine.Object的类的详细信息显示出来,比如比较常见的ScriptableObject

[CreateAssetMenu(menuName = "InLineTest")]
public class InLineTest : ScriptableObject
{
    
    
    public string myName;
    public int myAge;
}

//在我们之前的OdinTest脚本中引用
    [InlineEditor(InlineEditorModes.FullEditor)]
    public InLineTest mt;

会是下面的效果

可以看到在Inspector中展示了这个ScriptableObject,且属性都是激活的

[CreateAssetMenu(menuName = "InLineTest")]
public class InLineTest : ScriptableObject
{
    
    
    public string myName;
    [DisableInInlineEditors]
    public int myAge;
}

当我们给其中的一个属性标记后,在预览模式下它就会被冻结

3.DisableInNonPrefabs,HideInNonPrefabs

如果场景中的物体不来自预制体则冻结或隐藏,点击打开预制体会进入到一个新的场景,这里预制体相当于普通的物体,所以此时的变量是会冻结或隐藏的。

场景中的物体来自于预制体,所以不会被冻结

预制体编辑模式下相当于没有来源的普通物体,会被冻结

4.DisableInPlayMode,HideInPlayMode

与上面的第一条相反,在运行状态下冻结或隐藏,默认状态下被激活

5.DisableInPrefabAssets,HideInPrefabAssets

作为预制体资源打开时被冻结或隐藏,将预制体拖入场景后被激活

没有预制体来源的场景中的普通物体身上的属性也是激活状态。

6.DisableInPrefabInstances,HideInPrefabInstances

作为预制体的实例存在场景中时,被冻结或隐藏,,预制体中时激活状态,可以显示和修改

7.DisableInPrefabs,HideInPrefabs

场景中的预制体属性被冻结或隐藏

小结一下,上面的东西看着有点绕,各种模式下的显示隐藏,激活冻结,但实际开发中用的很少,反正我没用过,,我觉的掌握前面的基本的条件判断已经足够了,这些高级的了解功能即可。


三、分组

1.BoxGroup

将同一组内的字段放进一个盒子里,用来分隔类别挺好用的

    [BoxGroup("BaseInfo",CenterLabel=true)]
    public string studentName;
    [BoxGroup("BaseInfo", CenterLabel = true)]
    public string studentAge;
    [BoxGroup("BaseInfo", CenterLabel = true)]
    public string studentSex;

    [BoxGroup("Score", CenterLabel = true)]
    public string EnglishScore;
    [BoxGroup("Score", CenterLabel = true)]
    public string MathScore;
    [BoxGroup("Score", CenterLabel = true)]
    public string ArtScore;

2.FoldoutGroup

跟上面的唯一区别就是可以折叠起来,变量多的时候用起来很方便,我比较喜欢这个

    [FoldoutGroup("BaseInfo")]
    public string studentName;
    [FoldoutGroup("BaseInfo")]
    public string studentAge;
    [FoldoutGroup("BaseInfo")]
    public string studentSex;

    [FoldoutGroup("Score")]
    public string EnglishScore;
    [FoldoutGroup("Score")]
    public string MathScore;
    [FoldoutGroup("Score")]
    public string ArtScore;

动图封面

3.HorizontalGroup,VerticalGroup

横向和纵向布局,横向布局还有点用,unity 本来就是纵向的,所以这个纵向大可不必使用

    [HorizontalGroup("BaseInfo"),HideLabel]
    public string studentName;
    [HorizontalGroup("BaseInfo"), HideLabel]
    public string studentAge;
    [HorizontalGroup("BaseInfo"), HideLabel]
    public string studentSex;

    [VerticalGroup("Score")]
    public string EnglishScore;
    [VerticalGroup("Score")]
    public string MathScore;
    [VerticalGroup("Score")]
    public string ArtScore;

这里我隐藏了横向布局中变量的标签,看起来方便些

4.TabGroup

这个有点意思了,选项卡布局

    [TabGroup("BaseInfo")]
    public string studentName;
    [TabGroup("BaseInfo")]
    public string studentAge;
    [TabGroup("BaseInfo")]
    public string studentSex;

    [TabGroup("Score")]
    public string EnglishScore;
    [TabGroup("Score")]
    public string MathScore;
    [TabGroup("Score")]
    public string ArtScore;

动图封面

5.TitleGroup

带标题的分组,跟盒子分组差不多

    [TitleGroup("BaseInfo")]
    public string studentName;
    [TitleGroup("BaseInfo")]
    public string studentAge;
    [TitleGroup("BaseInfo")]
    public string studentSex;

    [TitleGroup("Score")]
    public string EnglishScore;
    [TitleGroup("Score")]
    public string MathScore;
    [TitleGroup("Score")]
    public string ArtScore;

6.ToggleGroup

emmm,带开关的分组,需要配合一个跟组名相同的bool值变量使用,没怎么正式用过

    [ToggleGroup("BaseInfo")]
    public bool BaseInfo;
    [ToggleGroup("BaseInfo")]
    public string studentName;
    [ToggleGroup("BaseInfo")]
    public string studentAge;
    [ToggleGroup("BaseInfo")]
    public string studentSex;

    [ToggleGroup("Score")]
    public bool Score;
    [ToggleGroup("Score")]
    public string EnglishScore;
    [ToggleGroup("Score")]
    public string MathScore;
    [ToggleGroup("Score")]
    public string ArtScore;


第四部分

书接上回,继续Odin特性的介绍

1.MaxValue

限制字段或属性的最大值

    [MaxValue(18)]
    public int grilAge;

动图封面

2.MinMaxSlider

最小最大的滑动条,用来描述V2类型的变量,xy分别为最小和最大值

    [MinMaxSlider(0, 18)]
    public Vector2Int grilAgeRange;

3.MinValue

限制字段或属性的最小值

    [MinValue(0)]
    public float studentScore;

动图封面

4.ProgressBar

将变量以进度条的形式显示,类似Range吧,也是一种最大最小值的限制,不过这个可能好看一点?

    [ProgressBar(0,1)]
    public float Progress;

动图封面

5.PropertyRange

属性范围显示,跟Unity的Range一样,只是这个是对属性的,需要配合ShowInInspector显示出来

    [ShowInInspector,PropertyRange(0,1)]
    public float Progress {
    
     get; set; }

6.Wrap

值在指定范围内循环

    [Wrap(0,10)]
    public int Score;

动图封面

数字在0-9之间循环

7.AssetList

资源列表,标记属性后点击右上角按钮可以快速选择和切换同类型资源

    [AssetList]
    public Material mat;

8.AssetSelector

资源选择器,跟上面的差不多,这个点击也会出现一个选择菜单,只不过这个是点击前面的三个点

    [AssetSelector]
    public Material mat;

9.ChildGameObjetsOnly

限制选择子物体

    [ChildGameObjectsOnly]
    public GameObject child;

10.ColorPalette

调色板,嗯,做配色应该挺方便的,可以从预设中直接选取颜色

    [ColorPalette]
    public Color color;

动图封面

11.DisplayAsString

将字段的值用只读字符串的形式显示

    [DisplayAsString]
    public Color col;

12.FilePath

文件路径,用来修饰字符串,我比较喜欢用来存地址,使用起来也很方便,直接拖拽就可以了

    [FilePath]
    public string gameObjectPath;

动图封面

13.FolderPath

文件夹路径,用法跟上面的文件一样,只不过这个是拖文件夹

    [FolderPath]
    public string gameObjectFolderPath;

动图封面

注意拖拽物体到上面时候会添加物体所在文件夹的路径

14.HideInTables

在表中隐藏,这个跟之前介绍过的TableList有联系,之前说TableList是将List以表的形式显示,HideInTables就是标记的属性不在表中显示

    [TableList]
    public List<Student1> st1;
    [TableList]
    public List<Student2> st2;
    [Serializable]
    public class Student1
    {
    
    
        public string Id;
        public string Name;
        public string Age;
    }
    [Serializable]
    public class Student2
    {
    
    
        [HideInTables]
        public string Id;
        public string Name;
        public string Age;
    }

15.HideMonoScript

隐藏Mono脚本

[HideMonoScript]
public class OdinTest : MonoBehaviour
{
    
    
    public string Show="SSSSS";
    public string Hide="HHHHH";
}

隐藏前

隐藏后

16.Hide Network Behaviour Fields

UNet已经被弃用了,这个也就没啥用了

官方描述是这样写的

HideNetworkBehaviour标记你的类,以防止特殊的"NetWork Channel"和"NetWorkSendInterval"属性在Inspector中作为一个NewWorkBehaviour被显示出来。此属性对没有继承NetworkBehaviour的类没有影响。

没有给示例,给了也用不到

17.Hide Reference Object Picker

这个不太好解释,没用过,看图吧

    public MyV3 Show;
    [HideReferenceObjectPicker]
    public MyV3 Hide;

    public class MyV3
    {
    
    
        public float x, y, z;
    }

下面添加了特性的把这个东西隐藏掉了

18.Inline Editor

这个之前介绍HideInInlineEditor的时候有介绍过,可以看一下上一篇文章

其中的高级条件特性的第二小点有介绍

19.MultiLineProperty

用来修饰字符串,显示多行文字,和Unity中的TextArea功能相同,我更习惯用后者

    [MultiLineProperty]
    public string MultTex;

20.Preview Field

预览选择的物体,我比较习惯用来预览图片,效果不错

    public Sprite lsp;
    [PreviewField]
    public Sprite sp;

上面的是普通的不能预览的,下面则可以看到缩略图

21.Toggle

开关,可以被用在任意字段或属性上,用来在Inspector上激活或冻结其的表现

注意,类中必须包含与特性中字符串参数名字相同的Bool值变量

    public MyToggle t1, t2;
    [Serializable,Toggle("Enable")]
    public class MyToggle
    {
    
    
        public bool Enable;
        public string Name;
        public string Age;
    }

22.ToggleLeft

将Bool值类型的勾选框放到Label的左边显示,看起里舒服很多

    [ToggleLeft]
    public bool Left;
    public bool Normal;


Odin的特性还真不少,怪不得插件有点贵


第五部分

1.CustomContextMenu

自定义的右键菜单

    [CustomContextMenu("SetAgeTen", "SetValueAsTen")]
    public int Age;
    public void SetValueAsTen()
    {
    
    
        Age = 10;
    }

动图封面

2.DisableContextMenu

禁用右键菜单

    [DisableContextMenu]
    public int DisableAge;

右键点击属性就不会有菜单了

3.DrawWithUnity

用Unity默认的显示方法显示Inspector上的属性,Odin导入Unity后Odin会改变属性的显示方式,这个属性相当于把属性重置回来了。

    public GameObject DrawInOdin;
    [DrawWithUnity]
    public GameObject DrawInUnity;

上面的是Odin的显示方式,下面的是Unity默认的显示方式

4.HideDuplicateReferenceBox

官方描述,表示 Odin 应隐藏引用,否则由于遇到重复的引用的值,该属性将被绘制为对另一属性的引用。请注意,如果值是递归引用本身,那么无论在所有递归渲染回调中是否具有此属性,都会绘制参考框。

然后他们给了个递归的例子,但是完全看不懂是怎么用的。。。我觉得他就是不想教会我

让后经过了我一个小时的尝试,终于找到了些许不同之处。

首先我新建了两个脚本

public class OdinTest : SerializedMonoBehaviour
{
    
    
    [HideDuplicateReferenceBox]
    public MyV3 mv3;
    [HideDuplicateReferenceBox]
    public MyV3 dmv3;
    public class MyV3
    {
    
    
        public string name;
    }
}

这个脚本声明两个同类型的变量

public class OdinTest1 : MonoBehaviour
{
    public OdinTest ot1;
    public OdinTest ot2;
    [Button]
    private void ReadValue()
    {
        ot2.mv3 = ot1.mv3;
        ot2.dmv3 = ot1.mv3;
    }
}

这个脚本是做赋值使用的,我打算在场景中做两个第一个脚本的实例,这个脚本从两个物体上获取引用,并将第一个里面的第一个值分别赋值给第二个里面的两个值

上面是测试场景的样子,挂好脚本后点击按钮赋值即可

这个是不加特性描述的两个变量值像是的样子,可以看到上面的两个变量有相同的来源,第二个变量有和第一个变量都是来自同另一个物体身上的值,所以它被框到了一个Box里面。

这个是加了变量后的样子,相当于将那个Box隐藏掉了,但值还是会同步的。

暂时不知道这个特性能拿来做什么,感觉没什么用

5.Indent

缩进,用来控制属性标签的缩进

    [Indent] public int A;
    [Indent(2)] public int B;
    [Indent(-2)] public int C;

6.InfoBox

信息盒子,用来详细描述属性

    [InfoBox("abcdefg\nhijklmn\nopqrst")]
    public int MyMathScore;

7.InlineProerty

将序列化后的属性与标签显示到同一行

    [InlineProperty]
    public MyV3 mvInLine;
    public MyV3 mv;
    [Serializable]
    public class MyV3
    {
    
    
        [HorizontalGroup(LabelWidth =10)]
        public int x, y, z;
    }

从上面的图中可以看到,上面的属性显示到了同一行,而下面的需要点击展开

8.LabelText

改变标签文字,简单描述变量,我特别喜欢用。

    [LabelText("我的成绩")]
    public float myScore;

9.LabelWidth

限制标签的长度

    [LabelText("我的成绩"),LabelWidth(20)]
    public float myScore;

10.OnCollectionChanged

集合变化时触发,用来监听集合的变化,我比较常用在List上

    public int count = 0;
    [OnCollectionChanged("ShowListCount")]
    public List<string> nameList;

    private void ShowListCount()
    {
    
    
        count = nameList.Count;
    }

动图封面

11.OnInspectorDispose

InspectorDispose重新排布时触发

    [OnInspectorDispose("ChangeCount")]
    public int count = 0;

    private void ChangeCount()
    {
    
    
        count++;
    }

动图封面

12.OnInspectorGUI

跟Unity的OnGUI或Update逻辑差不多,相当于Inspector的OnGUI,是在显示当前Inspector时一直执行

    [OnInspectorGUI("ChangeCount")]
    public int count = 0;

    private void ChangeCount()
    {
    
    
        count++;
    }

动图封面

13.OnInspectorInit

在Inspector初始化时触发,相当于Start或Awake

    [OnInspectorInit("ChangeCount")]
    public int count = 0;

    private void ChangeCount()
    {
        count++;
    }

动图封面

每次复制对象时对象身上的脚本都会执行一次Init,触发自加运算,所以会出现上图效果

14.OnStateUpdate

每帧执行一次,

    [OnStateUpdate("ChangeCount")]
    public bool OnStateChange;
    public int count = 0;
    private void ChangeCount()
    {
    
    
        if(OnStateChange)
        count++;
    }

动图封面

15.OnValueChanged

值变化时触发,比较常用

    [OnValueChanged("ChangeCount")]
    public bool OnStateChange;
    public int count = 0;
    private void ChangeCount()
    {
    
    
        count++;
    }

动图封面

16.PropertyToolTip

鼠标悬浮在属性上时的提示

    [PropertyTooltip("我的成绩")]
    public float myScore;

动图封面

17.SuffixLabel

后缀标签,标签显示到属性后面

    [SuffixLabel("我的成绩",Overlay =true)]
    public float myScore;

18.SuppressInvaildError

关闭不可用特性的报错

    [Range(0, 10), SuppressInvalidAttributeError]
    public string myScore1;

    [Range(0, 10)]
    public string myScore2;

19.ShowDrawerChain

显示绘制连,又是一个没用过的东西

官方描述,ShowDrawerList列出了Inspector中使用的所有前置、附加和值的Drawer。当你想调试,并想知道哪些Drawer可能参与绘制属性的时候非常有用。

说人话就是显示所有Drawer(我觉得可以理解为绘制器的意思)

    [Range(0, 10)]
    [ShowDrawerChain]
    public float SomeRange;

上面是当前属性的绘制器的使用结果

然后我给属性添加了一个InfoBox

    [Range(0, 10)]
    [ShowDrawerChain]
    [InfoBox("SSSSSSSome")]
    public float SomeRange;

可以看出多了一个InfoBox的绘制器

20.ShowPropertyResolver

显示属性解析器

    public MyV3 myV3;
    [ShowPropertyResolver]
    public MyV3 myV32;
    [Serializable]
    public class MyV3
    {
    
    
        public float x, y, z;
    }

添加了标签后会多一个这个东西,可以显示属性的类型,感觉没什么用


到这里所有Odin的特性就介绍完了,完结撒花。。

猜你喜欢

转载自blog.csdn.net/m0_58523831/article/details/132433504