Unity编译器扩展(Advanced Editor Scripting)

Untiy编译器扩展允许我们对编译器的增加自己编写的的功能菜单栏,让我们能够编写出增加工作效率的独一无二编辑器

  • MenuItem
  • ContextMenu和ContextMenuItem
    • ContextMenu
    • ContextMenuItem
  • 使用ScriptableWizard创建编辑窗口

MenuItem

该属性允许您将菜单项添加到主菜单和检查器窗口上下文菜单。
该属性将任何静态函数转换为菜单命令。只有静态函数可以使用该属性。

MenuItem的API地址

使用MenuItem需要的命名空间(class in UnityEditor)

using UnityEditor;
1.使用MenuItem添加菜单栏按钮 
//添加一个Do Someing的MenuItem到MyMenu的菜单栏下
//第一个参数路径采用  "菜单栏/MenuItem name"的形式,
//如果菜单栏不存才则会自动创建
[MenuItem("MyMenu/DoSomeing")]
static void DoSomeing() {
	Debug.Log("Doing Someing ...");
}

[MenuItem("MyMenu/DoSomeing/test")]
static void DoSomeingTest() {
	Debug.Log("Doing Someing ...");
}
效果

请添加图片描述


2.Menuitem层级的设置
菜单栏的层级设置是第三个参数,
把是否验证的参数传入false代表这个静态不是验证函数
当相邻的两个菜单栏相差的优先级相差11时就会被分层。

官方建议我们将层级优先级设置为10,而不是默认优先级的1000
原文:请注意,对于“GameObject/Create Other” 中没有明确优先级设置且支持旧版项目的 MenuItem 来说,接收到的优先级为 10 而非默认的 1000, 我们建议使用比“Create Other”更具描述性的类别名称,并将优先级 显式设置为 10

[MenuItem("MyMenu/DoSomeing")]
static void DoSomeing() {
	Debug.Log("Doing Someing ...");
}

[MenuItem("MyMenu/DoSoming_1",false, 21)]
static void DoSomeingTest1() {
	Debug.Log("Doing Someing ...");
}

//多级分层
[MenuItem("MyMenu/DoSomeing/test",false , 10)]
static void DoSomeingTest() {
	Debug.Log("Doing Someing ...");
}
效果:

请添加图片描述


3.验证菜单项
//被验证菜单栏
//添加一个Log Select Transform Name到MyMenu菜单下
//使用验证函数来判断是否有物体被选中
//如果有物体被选中则可以点击,输出相应的内容
[MenuItem("MyMenu/Log Selected Transform Name")]
static void LogSelectTransformName() {
    Debug.Log("选中的的transfor物体名字是" + Selection.activeTransform.name + ".");
}

//验证上述的菜单栏
[MenuItem("MyMenu/Log Selected Transform Name", true)]
static bool ValidateLogSelectedTransformName() {
//如果没有选中的物体就会返回false
	return Selection.activeTransform != null;
}
没有选择时的效果:


4.给组件加上菜单栏

MenuCommand 用于提取MenuItem的上下文,MenuCommand对象传递到使用MenuItem属性定义的自定义菜单项函数。
context属性是上下文传递对象的内容,可以使用强制转换

格式:[Menu(“CONTEXT/组件名/菜单栏名”)]

[MenuItem("CONTEXT/Rigidbody/Double Mass")]
static void DoubleMass(MenuCommand command) {
	Rigidbody body =(Rigidbody)command.context;
	body.mass *= 2;
    Debug.Log("我该变了缸体的重量为"+ body.mass);
}

效果:

Unity编译器扩展(Advanced Editor Scripting)_第1张图片

不支持多态,请严格拼写组件的名字


5.使用Undo注册操作,能够使用组合键 Ctrl + Z 撤销

注意:需要将注册操作放在操作生效的之前,如果你需要删除物体,那么就把Undo的代码放在删除之前

Undo的其他一些常用方法

[MenuItem("GameObject/MyCategory/Custom Game Object #G",false , 10)]
static void DoubleMas(MenuCommand command) {
	GameObject go = new GameObject("Custom Game Object");
	GameObjectUtility.SetParentAndAlign(go, command.context as GameObject);

	//注册操作
	Undo.RegisterCreatedObjectUndo(go, "Create" + go.name);
	Selection.activeObject = go;
}
不会做动图,效果就是按下Ctrl + Z 可以撤销,

ContextMenu和ContextMenuItem

ContextMenu

所需要的命名空间UnityEngine(class in UnityEngine)

ContextMenu的API地址

描述:
ContextMenu 属性用于向上下文菜单添加命令。
在该附加脚本的 Inspector 中,当用户选择该上下文菜单时, 将执行此函数。
这对于从该脚本自动设置场景数据非常有用。 此函数必须是非静态的。

using UnityEngine;

使用Context一定要在可挂载的脚本上(脚本要继承MonoBehaviour)
使用鼠标右键点击就能看到函数

using UnityEngine;

public class ContextTesting : MonoBehaviour {
    [ContextMenu("Do Something")]
    static void DoSomething() {
        Debug.Log("Perform operation");
    }
}
效果:

Unity编译器扩展(Advanced Editor Scripting)_第2张图片


ContextMenuItem

所需要的命名空间UnityEngine(class in UnityEngine / 继承自PropertyAttribute)

ContextMenuItem的API

使用该属性可将上下文菜单添加到调用命名方法的字段。
即为脚本中的属性添加菜单栏

using UnityEngine;

public class ContextTesting : MonoBehaviour {

    [ContextMenuItem("Add Text", "Add")]
    public int test = 0;

    void Add() {
        test += 20;
    }
}

效果:

Unity编译器扩展(Advanced Editor Scripting)_第3张图片
点击后:
请添加图片描述


使用ScriptableWizard创建编辑窗口

class in UnityEditor / 继承自:EditorWindow

描述:
从此类派生以创建编辑器向导。
编辑器向导通常使用菜单项打开。

ScriptableWizard的API

using UnityEngine;
using UnityEditor;

//继承ScriptableWizard
public class WizardCreateLight : ScriptableWizard {

    public float range = 500;
    public Color color = Color.red;

    [MenuItem("GameObject/Create Light Wizard")]
    static void CreateWizard() {
        ScriptableWizard.DisplayWizard<WizardCreateLight>("Create Light","Create", "Apply");
    }

    private void OnWizardCreate() {
        GameObject go = new GameObject("New Light");
        Light lt = go.AddComponent<Light>();

        lt.range = range;
        lt.color = color;
    }


    private void OnWizardUpdate() {
        helpString = "请设置光颜色";
    }


    private void OnWizardOtherButton() {
        if (Selection.activeTransform != null) {
            Light lt = Selection.activeTransform.GetComponent<Light>();
            if(lt != null) {
                lt.color = Color.red;
            }
        }
    }
}

效果:
按照路径知道菜单项后点击能够出现一个类似的对话框,
Unity编译器扩展(Advanced Editor Scripting)_第4张图片

如果你使用过DOTween插件就能明白,制作这也同样实现了一个这样的对话框。
如下:
请添加图片描述
Unity编译器扩展(Advanced Editor Scripting)_第5张图片

参考上述DOTween的对话框,我们能够实现对插件的设置首选项的修改,并且能够看出使用对话框能够实现的功能也十分强大。

你可能感兴趣的:(unity,游戏引擎)