[Unity编辑器扩展基础总结] 第2章 标准编辑器扩展

第2章 标准编辑器扩展

2.1 更改检查器的外观

范围 - [Range(x, y)]

该功能允许使用滑块更改数值,例如int,float,long和double,使得可以与滑块一起操作来提高可操作性。

using UnityEngine;
using System.Collections;

public class NewBehaviourScript : MonoBehaviour
{
    [Range(1, 10)]
    public int num1;

    [Range(1, 10)]
    public float num2;

    [Range(1, 10)]
    public long num3;

    [Range(1, 10)]
    public double num4;
}

多行文本 - [TextArea(x, y)]

   默认值为单行TextField,但可以将其更改为多行TextArea。Multiline和TextArea具有几乎相同的功能,但是Multiline具有一些限制,例如“不根据宽度自动换行”和“不显示滚动条”。建议使用TextArea,除非有特殊原因。

  

using UnityEngine;
using System.Collections;

public class NewBehaviourScript : MonoBehaviour
{
    [Multiline(5)]
    public string multiline;

    [TextArea(3, 5)]
    public string textArea;
}

2.2 扩展Inspector视图的功能

ContextMenuItem - [ContextMenuItem ("MenuName", "MethodName")

 将上下文菜单添加到检查器中显示的变量。当需要自动化一些步骤或同时更改其他变量的值时,可能需要使用它。另外,尽管有一个“重置”功能可以逐个组件地重置值,但是每个变量都没有重置功能,因此最好使用ContextMenuItem实现。

  

using UnityEngine;

public class NewBehaviourScript : MonoBehaviour
{
    [ContextMenuItem ("Random", "RandomNumber")]
    [ContextMenuItem ("Reset", "ResetNumber")]
    public int number;

    void RandomNumber ()
    {
        number = Random.Range (0, 100);
    }

    void ResetNumber ()
    {
        number = 0;
    }
}

颜色用法 - [ColorUsageAttribute(x, x, ...)]

使用颜色选择器更改颜色。ColorUsage可以在颜色选择器中启用/禁用使用alpha或将其更改为HDR的颜色选择器。

                 默认颜色选择器                                           无Alpha颜色选择器                                               HDR颜色选择器                                          

            

using UnityEngine;

public class EditorTest : MonoBehaviour
{
    public Color color1;

    [ColorUsageAttribute(false)]
    public Color color2;

    [ColorUsageAttribute(true, true, 0, 8, 0.125f, 3)]
    public Color color3;
}

2.3 调整监视器的外观

 它不会直接影响属性,但可以在外观上具有吸引力和装饰性。

标头 - [Header("xxx")]

 通过对属性进行分组并添加标题,使得更容易理解。

using System;
using UnityEngine;

public class EditorTest : MonoBehaviour
{
    [Header("玩家设置")]
    public Player player;

    [Serializable]
    public class Player
    {
        public string name;

        [Range(1, 100)]
        public int hp;
    }

    [Header("游戏设置")]
    public Color background;
}

空间间距 - [Space(xx)]

您可以提供垂直边距。当您希望通过在属性和属性之间提供边距来使其更易于查看时,此方法很方便。

using System;
using UnityEngine;

public class EditorTest : MonoBehaviour
{
    [Header("玩家设置")]
    public Player player;

    [Serializable]
    public class Player
    {
        [Space(20)]
        public string name;

        [Space(20)]
        public int hp;
    }

    [Header("游戏设置")]
    public Color background;
}

工具提示 - [Tooltip("xxxxxx")]

当我们想在检查器中查看属性的描述时,请使用此选项。

using System;
using UnityEngine;

public class EditorTest : MonoBehaviour
{
    [Header("玩家设置")]
    public Player player;

    [Serializable]
    public class Player
    {
        public string name;

        public int hp;
    }

    [Tooltip("这是一个游戏设置 这是一个游戏设置 这是一个游戏设置 这是一个游戏设置")]
    [Header("游戏设置")]
    public Color background;
}

隐藏属性 - [HideInInspector]

 当我们想在检查器中隐藏某个公开的属性时,可以在使用此选项。

 

using System;
using UnityEngine;

public class EditorTest : MonoBehaviour
{
    public string m_Str1;

    [HideInInspector]
    public string m_Str2;

    public string m_Str3;
}

必须附加指定组件 - [RequireComponent(typeof(xxxx)]

其他组件通常会创建所需的脚本。例如,当为Animator编写脚本时,都需要Animator组件。如果忘记添加该组件,当然就会报错,使用RequireComponent可以提前防止此类错误。

当使用RequireComponent附加脚本时,RequireComponent指定的组件也会自动附加。如果已经存在,则不执行任何操作。然后,当尝试删除指定的组件时,将显示一个对话框,提示无法删除。

 

using System;
using UnityEngine;

[RequireComponent(typeof(Animator))]
public class EditorTest : MonoBehaviour
{

}

禁止附多个组件 - [DisallowMultipleComponent]

 此属性禁止将同一组件重复附加到一个GameObject上

 

using System;
using UnityEngine;

[DisallowMultipleComponent]
public class EditorTest : MonoBehaviour
{

}

DisallowMultipleComponent也可以用在继承类中。

同步以前的序列化值 - [FormerlySerializedAs("hoge")]

更改变量名称后,此属性用于将数据传输到新的变量名称。

如检查器中所示,序列化数据以变量名作为路径存储。如果您在此处更改变量名称,则序列化的数据将不会被继承并被初始化。这是因为无法再从路径中引用该值。无法检测到变量已被重命名,这是一个可怕的问题。使用FormerlySerializedAs可以解决此问题。

using System;
using UnityEngine;
using UnityEngine.Serialization;

public class EditorTest : MonoBehaviour
{
    [SerializeField]
    string str1;
}

在检查器中输入值。

 

 将变量从Str1重命名为Str2。

using System;
using UnityEngine;
using UnityEngine.Serialization;

public class EditorTest : MonoBehaviour
{
    [SerializeField]
    string str2;
}

这样,在检查器中输入的字符串将不会被继承,也不会显示任何内容。

因此,可以通过使用FormerlySerializedAs来接管它。

using System;
using UnityEngine;
using UnityEngine.Serialization;

public class EditorTest : MonoBehaviour
{
    [SerializeField]
    [FormerlySerializedAs("str1")]
    string str2;
}

 

 

 请注意,必须在更改变量名称时,添加FormerlySerializedAs属性,同时指定使用oldName。如果数据通过编译脚本被丢弃,即使更改了变量名(第一次编译),也忘记了指定FormerlySerializedAs并匆忙添加(第二次编译),但是数据已经被丢弃了。这是因为数据将在第二次编译时被销毁。

将菜单项添加到“Component菜单 - [AddComponentMenu("xxx/xxx")]

using UnityEngine;

[AddComponentMenu("工具/EditorTest")]
public class EditorTest1 : MonoBehaviour
{

}

 

2.5使游戏开发更轻松

编辑器模式下运行脚本 - [ExecuteInEditMode]

 即使不运行游戏,也会继承MonoBehaviour的组件的主要功能。游戏对象更新时调用。双击场景资源并加载场景时,将调用“Awake”和“Start”方法,而在检查器等中更改组件的变量时,将调用“Update”方法。此外,将始终根据编辑器的GUI绘制周期显示由OnGUI实现的GUI。

using UnityEngine;

[ExecuteInEditMode]
public class EditorTest1 : MonoBehaviour
{
    [Range(0, 10)]
    public int number;

    void Awake()
    {
        Debug.Log("Awake");
    }

    void Start()
    {
        Debug.Log("Start");
    }

    void Update()
    {
        Debug.Log("Update");
    }
}

上下文菜单 - [ContextMenuItem]

从组件的上下文菜单中执行方法。

using UnityEngine;

public class EditorTest1 : MonoBehaviour
{
    [Range(0, 10)]
    public int number;

    [ContextMenu("RandomNumber")]
    void RandomNumber()
    {
        number = Random.Range(0, 100);
    }

    [ContextMenu("ResetNumber")]
    void ResetNumber()
    {
        number = 0;
    }
}

自动选中根节点 - [SelectionBase]

 通常,在场景视图中选择一个对象时,将选择根游戏对象。

 新建一个GameObject1,建一个子节点GameObject2,再建一个Cube作为GO2的子节点。注意GO1和GO2都是空的GO。

 这时在Scene里面选择我们刚才创建的Cube,系统会默认选择Cube。现在我们在GO2上加了一个配置信息,需要经常改变,如果一直定位在Cube上就太麻烦了。有两种解决办法,一种是手动去选。。。还有一种就是用SelectionBase。

 编写以下脚本以附加到GO2上,然后再次重复选择操作。

using UnityEngine;

[SelectionBase]
public class EditorTest: MonoBehaviour
{

}

可以看到GO2先被选中了,再点击的话能够轮询到Cube。因此SelectionBase的作用可以让没有实体的GO被选中。

我们在GO1上也加一个SelectionBase,再次点击,还是只能选中GO2,多次点击也无法选到GO1,我把GO2的脚本移除就可以点到GO1了。

我猜测,SelectionBase可能在同一根目录物体下,只有一份会起作用。

 

参考文章:Unity编辑器拓展手册日文版 http://49.233.81.186/guicreation.html

posted @ 2021-05-10 20:44  倾尽天下KO  阅读(722)  评论(0编辑  收藏  举报
Live2D
//播放器 //烟花
//自定义评论