Unity编辑器拓展(脚本标签)

1.常用的脚本标签:调整脚本组件的数据编辑以及编辑器上的一些功能菜单的拓展

using System;
using System.Collections;
using System.Collections.Generic;
using UnityEditor;
using UnityEngine;
using UnityEngine.Serialization;

[RequireComponent(typeof(AudioSource))] //给类添加。在给物体添加该标签标记的脚本类后,如果物体没有typeof中的组件则会自动给物体添加
[AddComponentMenu("Test/ComponentTest")] //给类添加。会出现在Component菜单中,点击后可以为物体添加对应的脚本类
[HelpURL("https://www.baidu.com")]//给类添加。将标记的脚本组件的右上角的小问号链接到给定的URL(那个小问号本身是链接到官方脚本文档的,相当于这里的标签修改了它的链接地址)
[DisallowMultipleComponent]//给类添加。标记的脚本只能对同一个物体添加一个该标记脚本,而不能添加多个该脚本
[ExecuteInEditMode]//给类添加。使脚本在编辑模式下也能执行生命周期函数,如Start、Update等。但是使用起来效果并不好。
public class Test : MonoBehaviour
{
    private void Start()
    {
        Debug.Log("Start");
    }
    [HideInInspector]//隐藏公有变量在Inspector面板上显示
    public int num;
    [NonSerialized]//序列化属性,并可以隐藏公有属性
    public int Nonnum;
    [SerializeField]//使非公有属性序列化,并显示在面板上
    private string playerName;
    public Student stu;
    [Header("文章标题")]//给变量加个标题
    public string title;
    [Space(30)]//设置上边距
    public int edgeDistance;
    [Tooltip("鼠标悬停在属性名上")]//鼠标悬停在属性名上显示的信息
    public int hover;
    [Range(0, 10)]//限制int、float、double类型变量的大小范围
    public int hitDamage;
    [Multiline(3)]//给string类型变量设置行数
    public string text;
    [TextArea]//给string类型变量设置成文本区域的形式显示
    public string area;
    [ColorUsage(true)]//调用颜色复选框,其中的true表示显示透明度设置
    //注:如果要调节3D物体的透明度,需要将3D物体的材质的渲染模式改为Fade
    public Color color;
    [FormerlySerializedAs("obj")]//防止GameObject类型变量在拖拽赋值后,因改变了变量名而使引用丢失的情况,里面的参数是最初拖拽赋值时的变量名
    public GameObject obj;
    [MenuItem("菜单/菜单项 &%Q", priority =1)]//给unity菜单栏加功能菜单,该标签下可以加静态方法,表示功能按钮调用的方法,&%Q表示快捷键,%:Ctrl #:Shift &:Alt。存在多个菜单项时priority可以控制菜单项的显示优先级
    static void ShowMenuItem()
    {
        Debug.Log("MenuItem");
    }
    [MenuItem("CONTEXT/Test/buttonl")]//Test表示脚本名,button1表示功能按钮名。在对应的脚本组件右上角的三个小点或齿轮的那里,点击button1,就会调用下面的静态方法
    static void ShowInpectorInfo()
    {
        Debug.Log("InpectorInfo");
    }
    [ContextMenuItem("Test", "MyTest")]//给属性添加右键菜单功能按钮,Test表示右键菜单的功能按钮名,MyTest表示该功能对应得触发方法
    public string printMyTest;
    void MyTest()
    {
        Debug.Log("MyTest");
    }
}
[System.Serializable]//使序列化的类中的公有变量可以在Inspector上显示
public class Student
{
    public int id;
    public string name;
    private int age;
}

2.CreateAssetMenu标签:在Project的Create菜单中可以看到该标签表现得功能

(1)写一个继承ScriptableObject的脚本,给脚本类加上CreateAssetMenu标签

using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

[CreateAssetMenu(fileName = "ScriptFile", menuName = "玩家/玩家信息", order = 1)]//Project的Create菜单下可以看到,点击“玩家信息”会自动创建名为“ScriptFile”的文件。order表示显示顺序
public class ScriptObject : ScriptableObject
{
    //添加一些属性
    [Header("ID")]
    public int id=2;
    [Tooltip("Name")]
    public string playerName="张三";
    [Range(1, 90)]
    public int age=40;
    [Tooltip("PlayerHitDamage")]
    public float hitDamage=40;
    //.........常用标签基本都可以使用
    //添加一些非生命周期函数也行
    public void Attack()
    {
        Debug.Log("Attack");
    }
    public void Hurt()
    {
        Debug.Log("Hurt");
    }
    public void ShowInfo()
    {
        Debug.Log($"id:{id},playerName:{playerName},age:{age},hitDamage:{hitDamage}");
    }
}

(2)方法一:右键Project窗口中的Resources文件夹(不是必须的,看个人如何引用),在Create菜单中创建.asset玩家信息文件,会生成一个ScriptFile文件。(需要使用CreateAssetMenu标签)

方法二:ScriptObject文件是通过ScriptableObject的静态方法创建的。虽然方法不一样,但是使用效果没有太大区别。(不需要使用CreateAssetMenu标签)

(3)挂载下面的脚本(脚本中两种方法都使用了),运行unity,查看控制台输出的信息

using System.Collections;
using System.Collections.Generic;
using UnityEditor;
using UnityEngine;

public class ScriptableObjectTest : MonoBehaviour
{
    delegate void DelegateTest();//委托
    public ScriptObject objTest;//方法一:以拖拽复制的方式引用ScriptObjec
    // Start is called before the first frame update
    void Start()
    {
        //方法一:可在Inspector面板上实时调整,使用更方便,需要用到CreateAssetMenu标签
        DelegateTest test = new DelegateTest(objTest.ShowInfo);//注册方法
        test += objTest.Attack;//注册方法
        test += objTest.Hurt;
        test();
        //方法二:不需要用到CreateAssetMenu标签
        ScriptObject obj = ScriptableObject.CreateInstance<ScriptObject>();//创建ScriptObject实例
        AssetDatabase.CreateAsset(obj, "Assets/Resources/ScriptObject.asset"); //在Assets/Resources文件夹创建资源文件ScriptObject.asset
        AssetDatabase.SaveAssets();//保存创建的资源
        AssetDatabase.Refresh();//刷新
        DelegateTest test2 = new DelegateTest(obj.ShowInfo);//注册方法
        test2 += obj.Attack;//注册方法
        test2 += obj.Hurt;
        test2();
    }
}

 注:ScriptableObject脚本类说明:在项目中经常需要创建多个相同的预制体,而这些预制体上又都挂载了相同的脚本,相当于同一脚本中的属性方法等数据被复制了多份,造成了资源的浪费,而使用一个继承ScriptableObject的脚本去保存哪些需要重复使用的属性方法等数据,然后在需要使用到这些数据的预制体的脚本组件上定义一个指向该ScriptableObject脚本对象的引用去获得数据,可以提高性能,尤其是这类数据非常多的时候是相当有用的。
平时我们从Inspector面板上为脚本组件公开的变量输入数据去改变项目效果,实际上是当你输入数据后,unity编辑器会实时自动去修改对应的.asset场景文件中的数据从而改变项目效果。在需要频繁修改大量数据时,这样是不方便的,unity也会很卡。而使用ScriptableObject脚本就可以将一些需要经常修改的属性或方法从主要的逻辑脚本中隔离出来,方便策划修改数据参数。

参考:

Unity编辑器扩展——标签属性Attribute_mb60e5417d375b8的技术博客_51CTO博客

Unity常用标签-CSDN博客

Unity进阶:ScriptableObject使用指南_YY-nb的博客-CSDN博客

结语:合抱之木,生于毫末;九层之台,起于累土;千里之行,始于足下。

猜你喜欢

转载自blog.csdn.net/falsedewuxin/article/details/130052271