Editor编程 玩转MenuItem(快捷键,校验器,分组,菜单路径)

using UnityEngine;
using UnityEditor;

public class MenuItemTest {

    //普通菜单
    [MenuItem("MenuItemTest/DoIt")]
    static void DoIt() {

    }

    //为菜单增加校验器,不可用的时候置灰
    [MenuItem("MenuItemTest/ValidationTest")]
    static void ValidationTest() {

    }
    //校验器
    //路径填跟你想要校验的菜单的路径要一致
    //校验方法名可以随意
    //方法返回值为bool
    [MenuItem("MenuItemTest/ValidationTest",validate =true)]
    static bool ValidationTestValidator() {
        //如果在场景中找到名为 testobj 的对象的时候,校验为真。
        GameObject go = GameObject.Find("testobj");
        return go != null;
    }

    //为命令添加快捷键
    //◾%—— 在 Windows 上的 CTRL / CMDOSX 上
    //◾#—— Shift
    //◾_—— 单键
    //◾LEFT/RIGHT/UP/DOWN---—Arrow箭头键
    //◾F1......F2 — — F键
    //◾HOME, END,PGUP, PGDN
    [MenuItem("MenuItemTest/Hotkey Ctrl Shift Z %#z")]
    static void hotkeyCtrlShiftZ() {
        Debug.Log("Hotkey Ctrl Shift Z");
    }

    [MenuItem("MenuItemTest/Hotkey G _g")]
    static void HotKeyG() {
        Debug.Log("HotKey G");
    }

    //默认顶层菜单路径是在菜单栏
    //特殊菜单路径
    //◾Assets - 项目将可在“Assets”菜单,以及使用project视图中的右键单击。
    //◾CONTEXT/ComponentName -items将可通过右键单击里面的给定组件inspector检查器。相当于扩展已有组件的菜单。
    //为组件扩展菜单的时候想要获取当前组件脚本对象需要在方法里加入MenuCommand形参。具体看下面关于MenuCommand的介绍。
    //◾CONTEXT/... - 其他系统上下文菜单,比如CONTEXT/ShaderPopup就是shader选择菜单,这些菜单路径都是unity内部使用
    //没有公开,我们可以通过ILSpy反编译去查菜单路径。
    //◾GameObject - Hierarchy里gameobject右键菜单。比较特殊,要在GameOjbect右键菜单根路径显示需要设置MenuItem.priority,不然不能显示。
    //priority范围必须在[0,50),超出范围也不显示。
    
    //其他路径菜单的添加一样,唯独GameObject路径比较特殊,下面侧重演示如何在GameOjbect右键菜单里加菜单
    [MenuItem("GameObject/GameObject根路径菜单",priority =20)]
    static void GameObjectMenuItem() {
        Debug.Log("GameObject菜单");
    }

    /// 
    /// 这个菜单就不会显示,因为没设置MenuItem的priority值。
    /// 
    [MenuItem("GameObject/GameObject根路径菜单2")]
    static void GameObjectMenuItem2() {
        Debug.Log("GameObject菜单2");
    }

    /// 
    /// priority>49 所以不显示
    /// 
    [MenuItem("GameObject/GameObject根路径菜单3",priority = 50)]
    static void GameObjectMenuItem3() {
        Debug.Log("GameObject菜单3");
    }

    //分组(下划线)
    //菜单的分组是靠MenuItem.Priority属性来实现,priority每50划分为一组。
    //比如我们希望 item1 item2 一组,item3 item4 一组,那么item1的priority设置为0,item2的priority设置为1,
    //item3的priority设置为50,item4的priority设置为51。
    [MenuItem("Item Group/Item1", priority = 0)]
    static void ItemGroup1() {
    }
    [MenuItem("Item Group/Item2", priority = 1)]
    static void ItemGroup2() {
    }
    [MenuItem("Item Group/Item3", priority = 50)]
    static void ItemGroup3() {
    }
    [MenuItem("Item Group/Item4", priority = 51)]
    static void ItemGroup4() {
    }

    //MenuCommand
    //其实每一个菜单方法默认都会传入一个MenuCommend的参数进来,默认可以不声明这个形参。
    //一般来讲MenuCommand.context相当于Selection.activeObject,调用方法的时候Unity会自动把当前激活的对象当作上下文封成MenuCommand传入。
    //用MenuCommand来处理目标比用Selection.activeObject要科学,因为当多选的时候unity相当于自动为所有对象都执行一次命令。
    //Selection方式则要用Selection.objects来循环处理。
    //当然如果需要为批处理加进度条之类的,还是需要具体处理。
    [MenuItem("GameObject/打印GameObject名字",priority =20)]
    static void PrintObjectName(MenuCommand command) {
        Debug.Log(command.context);
    }

    //当为组件扩展菜单的时候,要获得当前组件就要为方法设置一个MenuCommand类型形参。
    //MenuCommand.context就是当前组件脚本对象。
    [MenuItem("CONTEXT/Transform/打印名字")]
    static void PrinTransformComponentName(MenuCommand command) {
        Debug.Log(command.context);
    }


}

你可能感兴趣的:(Unity3d)