当前位置:   article > 正文

Unity编辑器扩展之Menu菜单扩展

Unity编辑器扩展之Menu菜单扩展

内容将会持续更新,有错误的地方欢迎指正,谢谢!
 

Unity编辑器扩展之Menu菜单扩展
     
TechX 坚持将创新的科技带给世界!

拥有更好的学习体验 —— 不断努力,不断进步,不断探索
TechX —— 心探索、心进取!

助力快速掌握 Menu 菜单扩展

为初学者节省宝贵的学习时间,避免困惑!

在这里插入图片描述



一、AddComponentMenu 添加组件菜单


使用AddComponentMenu 属性允许你将脚本放在 "Component "菜单的任何位置,而不仅仅是 "Component->Scripts "菜单。

这样可以更好地组织组件菜单,从而改善添加脚本时的工作流程。

在这里插入图片描述

menuNameComponent 菜单的路径。
orderComponent 菜单中用于添加新项目的位置。

1、组件菜单基本用法


using UnityEngine;

[AddComponentMenu("MyComponent/MyComponent1")]
public class MyComponent1 : MonoBehaviour
{
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

设置menuName的值为"MyComponent/MyComponent1"作为菜单的路径。

在这里插入图片描述

2、设置组件在组件菜单中的位置


using UnityEngine;

[AddComponentMenu("MyComponent/MyComponent1",2)]
public class MyComponent1 : MonoBehaviour
{
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
using UnityEngine;

[AddComponentMenu("MyComponent/MyComponent2",1)]
public class MyComponent2 : MonoBehaviour
{
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

通过设置order参数,可以调整组件在组件菜单中的位置,order顺序越低,位置越高 。

在这里插入图片描述



二、 CreateAssetMenuAttribute 创建资源菜单


对 ScriptableObject 派生类型进行标记,使其自动列在 Assets/Create 子菜单中,以便能够轻松创建该类型的实例并将其作为“.asset”文件存储在项目中。


在这里插入图片描述

menuNameAssets/Create 菜单中显示的此类型的显示名称。
fileName此类型的新建实例使用的默认文件名。
orderAssets/Create 菜单中菜单项的位置。

1、资源菜单基本用法


using UnityEngine;

// 创建一个自定义资源类
[CreateAssetMenu(fileName = "NewCustomResource", menuName = "Custom Resources/MyCustomResource")]
public class MyCustomResource : ScriptableObject
{
    // 在这个类中定义资源的属性和行为
    public string resourceName;
    public int resourceValue;
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10

fileName 是创建的新ScriptableObject实例资源的文件名。

menuName 菜单项的路径,你可以自定义菜单项的路径。例如:“Assets/Create/Custom Assets”。

menuName 参数可以忽略,当该参数呗忽略时,将以ScriptableObject示例的类名作为菜单。

在这里插入图片描述

2、设置资源菜单位置


using UnityEngine;

// 创建一个自定义资源类
[CreateAssetMenu(fileName = "NewCustomResource", menuName = "Custom Resources/MyCustomResource", order = 1)]
public class MyCustomResource : ScriptableObject
{
    // 在这个类中定义资源的属性和行为
    public string resourceName;
    public int resourceValue;
}

[CreateAssetMenu(fileName = "NewCustomResource1", menuName = "Custom Resources/MyCustomResource1", order = 2)]
public class MyCustomResource1 : ScriptableObject
{
    // 在这个类中定义资源的属性和行为
    public string resourceName;
    public int resourceValue;
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18

orde用于指定菜单项的顺序,如果有多个菜单项,可以使用order参数来设置它们的显示顺序。较小的order值将优先显示。

在这里插入图片描述



三、ContextMenu 上下文菜单


ContextMenu属性,允许我们在Inspect检视面板对Component组件添加菜单功能。

在这里插入图片描述

itemName此上下文菜单路径。
isValidateFunction这是否为验证函数(默认为 false)。
priority优先级,用于重写菜单项的排序(默认为 1000000)。数字越低,其在该菜单中将越先显示。

1、上下文菜单基本用法


using UnityEngine;
using UnityEditor;

public class ContextMenuExample : MonoBehaviour
{
    [ContextMenu("My Context Menu")]
    private void MyContextMenuFunction()
    {
        Debug.Log("Context menu item clicked!");
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11

itemName为菜单路径,可以设置为一级,也可以设置为多级菜单,比如"My Context Menu/Item。"

在这里插入图片描述

2、菜单验证


public class ContextMenuExample : MonoBehaviour
	{
        [ContextMenu("My Context Menu",false)]
        private void MyContextMenuFunction()
        {
            Debug.Log("Context menu item clicked!");
        }

        // 验证函数,如果返回值为 true,上下文菜单项将处于激活状态
        [ContextMenu("My Context Menu",true)]
        private bool ValidateMenuItem()
        {
            // 在这里,你可以根据条件来决定是否激活上下文菜单项
            return false;
        }
    }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16

当isValidateFunction为true时表明这是一个验证函数,当返回值为true时,该菜单项才可以进行选择,否则不可选择。

在这里插入图片描述


3、设置上下文菜单位置


public class ContextMenuExample : MonoBehaviour
	{
        [ContextMenu("My Context Menu1",false,20)]
        private void MyContextMenuFunction1()
        {
            Debug.Log("Context menu item clicked!");
        }

        [ContextMenu("My Context Menu2", false, 10)]
        private void MyContextMenuFunction2()
        {
            Debug.Log("Context menu item clicked!");
        }

        [ContextMenu("My Context Menu3", false, 31)]
        private void MyContextMenuFunction3()
        {
            Debug.Log("Context menu item clicked!");
        }
    }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20

priority 优先级,表示菜单的显示顺序,默认为1000000,数值越小的越靠上显示,当值大于600时,显示在菜单最下面,若相邻菜单间差距大于11则会被分割线进行分割。

在这里插入图片描述



四、ContextMenuItemAttribute 上下文菜单-字段菜单


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

在这里插入图片描述

name此上下文菜单项的路径。
function 应调用的函数的名称。

using UnityEngine;

public class MyScript : MonoBehaviour
{
    [ContextMenuItem("CustomAction", "MyCustomFunction")]
    public int myValue = 42;

    // 自定义方法
    private void MyCustomFunction()
    {
        // 这个方法将在右键点击时被调用
        Debug.Log("Custom action executed!");
    }
}

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15

functionName 表示将在 Inspector 中右键点击时调用的方法的名称。

menuItem 用于表示在右键上下文菜单中显示的菜单项名称。可以包括路径以创建子菜单。例如,如果你指定 menuItem 为 “MyScript/CustomAction”,则菜单项将显示在 “MyScript” 子菜单下,并命名为 “CustomAction”。

在这里插入图片描述



五、MenuItem


通过 MenuItem 属性,您可以在主菜单和 Inspector窗口上下文菜单中添加菜单项。

MenuItem 属性能够将任何静态函数转变为菜单命令。仅静态函数可使用 MenuItem 属性。

在这里插入图片描述

itemNameitemName 是指表示方式类似于路径名的菜单项。 例如,菜单项可能为“GameObject/Do Something”。
isValidateFunction如果 isValidateFunction 为 true,它将表示一个验证 函数,并在系统调用具有相同 itemName 的菜单函数之前进行调用。
priority菜单项显示的顺序。

1、基本用法

using UnityEditor;
using UnityEngine;
public class MenuTest : MonoBehaviour
{
    //添加一个Do Something菜单项到MyMenu 菜单中。
    [MenuItem("MyMenu/Do Something")]
    static void DoSomething()
    {
        Debug.Log("Doing Something...");
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11

添加一个Do Something菜单项到MyMenu 菜单中。

在这里插入图片描述

2、验证菜单

using UnityEditor;
using UnityEngine;
public class MenuTest : MonoBehaviour
{
   
    // 验证菜单项
    // 添加菜单项 "Log Selected Transform Name" 到菜单 MyMenu中。
    // 当选中transform时菜单启用。
    [MenuItem("MyMenu/Log Selected Transform Name")]
    static void LogSelectedTransformName()
    {
        Debug.Log("Selected Transform is on " + Selection.activeTransform.gameObject.name + ".");
    }

    // 验证上面的定义的菜单项
    // 如果返回false时,菜单项被禁用。
    [MenuItem("MyMenu/Log Selected Transform Name", true)]
    static bool ValidateLogSelectedTransformName()
    {
        //如果没有选中Transform时返回false。
        return Selection.activeTransform != null;
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23

一个方法和它的验证方法的第一个参数,也就是路径,必须是一样的,这样两个方法才会关联起来。并且验证方法的第2个参数填true,返回值为bool类型。

当验证函数返回false时,菜单禁用。

在这里插入图片描述

当验证函数返回true时,菜单启用。

在这里插入图片描述

3、菜单顺序

using UnityEngine;
using UnityEditor;
using System.Collections;

public class ExampleClass : MonoBehaviour
{
    // 设置菜单项Example1优先级为100
    [MenuItem("Example/Example1", false, 100)]
    public static void Example1()
    {
        print("Example/Example1");
    }
    
    // 设置菜单项Example2优先级为101
    [MenuItem("Example/Example2", false, 101)]
    public static void Example2()
    {
        print("Example/Example2");
    }

    // 设置菜单项Example3优先级为112,比菜单项Example2优先级大11。 
    // 这将生成一个分割线。
    [MenuItem("Example/Example3", false, 112)]
    public static void Example3()
    {
        print("Example/Example3");
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28

priority优先级,主要影响菜单出现的先后顺序,不填默认是1000。值越小,出现在越上层的位置。

此外,当一个菜单的优先级比它上一个菜单的优先级 >= 11,菜单之间还能看到分界线。

这里Example3菜单的priority值比Example2的priority值大11,因此Example3和Example2之间出现了分界线。

在这里插入图片描述

4、菜单快捷键

using UnityEditor;
using UnityEngine;
public class MenuTest : MonoBehaviour
{
    // 添加菜单项 "Do Something with a Shortcut Key" 到菜单 MyMenu中
    // 并且为这个菜单项添加一个快捷键 Ctrl+G。
    [MenuItem("MyMenu/Do Something with a Shortcut Key1 %g")]
    static void DoSomethingWithAShortcutKey1()
    {
        Debug.Log("使用快捷键Ctrl+G");
    }
    
	[MenuItem("MyMenu/Do Something with a Shortcut Key2 _A")]
    static void DoSomethingWithAShortcutKey2()
    {
        Debug.Log("使用快捷键G");
    }
    
	[MenuItem("MyMenu/Do Something with a Shortcut Key3 _F1")]
    static void DoSomethingWithAShortcutKey2()
    {
        Debug.Log("使用快捷键F1");
    }
    
	[MenuItem("MyMenu/Do Something with a Shortcut Key4 _LEFT")]
    static void DoSomethingWithAShortcutKey2()
    {
        Debug.Log("使用快捷键左箭头←");
    }
    
	[MenuItem("MyMenu/Do Something with a Shortcut Key5 _HOME")]
    static void DoSomethingWithAShortcutKey2()
    {
        Debug.Log("使用快捷键HOME");
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36

可以为MenuItem可以添加快捷键,Ctrl,Shift,Alt 都有对应的字符,比如表示shift键的字符是#。

那么快捷键shift + q,可以写成 #q。使用组合键时可以直接进行字符组合,当使用单个键时,需要在前面添加下划线"_",比如想用F1快捷键,那么就写成_F1。

在这里插入图片描述

快捷键对应字符
Ctrl%
Shift#
Alt&
A ~ Z_A ~ _Z
F1 ~ F12_F1 ~ _F12
_LEFT
_RIGHT
_UP
_DOWN
HOME_HOME
END_END
PageUP_PageUP
PageDown_PageDown

5、添加上下文菜单

using UnityEditor;
using UnityEngine;
public class MenuTest : MonoBehaviour
{
    // 为Rigidbody添加一个上下文菜单项 "Double Mass" 。
    [MenuItem("CONTEXT/Rigidbody/Double Mass")]
    static void DoubleMass(MenuCommand command)
    {
        Rigidbody body = (Rigidbody)command.context;
        body.mass = body.mass * 2;
        Debug.Log("Doubled Rigidbody's Mass to " + body.mass + " from Context Menu.");
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13

使用MenuItem也可以给脚本或组件添加上下文菜单,使用[MenuItem(“CONTEXT/组件名/显示方法名”)]的形式。

函数里使用了MenuCommand类,这个类是为菜单项来获取上下文。

MenuCommand类有一个重要的属性context,可以用于获取当前菜单项的上下文。

在这里插入图片描述

6、添加GameObject菜单

using UnityEditor;
using UnityEngine;
public class MenuTest : MonoBehaviour
{
    // 为创建自定义对象添加一个菜单。
    // 优先级为10确保它与其他同类菜单项在一组,并传播到hierarchy 下拉菜单和hierarchy 上下文菜单。
    [MenuItem("GameObject/MyCategory/Custom Game Object", false, 10)]
    static void CreateCustomGameObject(MenuCommand menuCommand)
    {
        // 创建一个自定义对象
        GameObject go = new GameObject("Custom Game Object");
        // 如果是右键单击,确保菜单被重置。
        GameObjectUtility.SetParentAndAlign(go, menuCommand.context as GameObject);
        // 设置这个创建动作可撤回。
        Undo.RegisterCreatedObjectUndo(go, "Create " + go.name);
        Selection.activeObject = go;
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18

将菜单项添加到“GameObject/”菜单,以在创建自定义游戏对象时,确保 调用 GameObjectUtility.SetParentAndAlign,从而确保在发生上下文单击事件时, 对新的游戏对象进行正确地重定父级。

调用 Undo.RegisterCreatedObjectUndo,以使创建操作可撤销并将 Selection.activeObject 设置到新创建的对象上。

为了将“GameObject/”中的菜单项 传播到层级视图 Create 下拉菜单和层级视图上下文菜单,它必须与其他游戏对象创建菜单项归为一组。这可以通过将其优先级 设为 10 来实现。

在这里插入图片描述

7、可以被勾选的MenuItem

using UnityEditor;
using UnityEngine;
public class MenuTest : MonoBehaviour
{
	 static bool isSelect = false;
    [MenuItem("Example/Example4")]
    static void ToggleMenu()
    {
        isSelect = !isSelect;
        Menu.SetChecked("Example/Example4", isSelect);
    }
}
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13

Menu.SetChecked为设置给定菜单的检查状态,当第二个参数为true时,菜单为勾选状态。

在这里插入图片描述

8、MenuItem的复用

using UnityEditor;
using UnityEngine;
public class MenuTest : MonoBehaviour
{
	 [MenuItem("Example/Example5")]
	 static void OpenDirectorReuse()
	 {
	     EditorApplication.ExecuteMenuItem("Example/Example1");
	 }
	
	 [MenuItem("Example/Example6")]
	 static void OpenAssignDirectorReuse()
	 {
	     EditorApplication.ExecuteMenuItem("Example/Example2");
	 }
}

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17

EditorApplication.ExecuteMenuItem 方法允许你执行 Unity 编辑器中的任何菜单项。它接受一个字符串参数,该参数是菜单项的路径,用于指定要执行的菜单项。

using UnityEditor;
using UnityEditor.SceneManagement;

public class ExampleClass
{
    [MenuItem("Examples/Execute menu items")]
    static void EditorPlaying()
    {
        var newScene = EditorSceneManager.NewScene(NewSceneSetup.EmptyScene, NewSceneMode.Single);

        EditorApplication.ExecuteMenuItem("GameObject/3D Object/Cube");
        EditorApplication.ExecuteMenuItem("GameObject/Create Empty");

        EditorSceneManager.SaveScene(newScene, "Assets/MyNewScene.unity");
        EditorApplication.Exit(0);
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17




TechX —— 心探索、心进取!

每一次跌倒都是一次成长

每一次努力都是一次进步

END
感谢您阅读本篇博客!希望这篇内容对您有所帮助。如果您有任何问题或意见,或者想要了解更多关于本主题的信息,欢迎在评论区留言与我交流。我会非常乐意与大家讨论和分享更多有趣的内容。
如果您喜欢本博客,请点赞和分享给更多的朋友,让更多人受益。同时,您也可以关注我的博客,以便及时获取最新的更新和文章。
在未来的写作中,我将继续努力,分享更多有趣、实用的内容。再次感谢大家的支持和鼓励,期待与您在下一篇博客再见!
声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/我家自动化/article/detail/125072
推荐阅读
相关标签
  

闽ICP备14008679号