一、MenuItem:创建菜单项
(1) 描述
MenuItem属性可以让你在主菜单和inspector context菜单中添加菜单项。
MenuItem属性可以将任何static函数转换为菜单命令。只有static函数可以使用MenuItem属性。
创建热键,可以使用以下特殊字符:%(在Windows上表示ctrl,在macOS表示cmd),#(shift)和&(alt)。如果不需要特殊的修饰键组合,则可以在下划线后给出该组合键。例如,菜单绑定快捷键shift-alt-g,可使用"MyMenu/Do Something #&g"。若要创建带有热键g且没有按键修饰符的菜单项,可使用 “MyMenu/Do Something _g”。
也支持一些特殊的键盘键作为热键,例如“ #LEFT”被映射为左移。支持特殊键如下:LEFT,RIGHT,UP,DOWN,F1 … F12,HOME,END,PGUP,PGDN。
热键文本之前必须带有空格字符(例如"MyMenu/Do_g"中g不会被解释为热键,而"MyMenu/Do _g"会被解释为热键)。
将菜单项添加到“ GameObject /”菜单中以创建自定义游戏对象时,确保调用GameObjectUtility.SetParentAndAlign以确保在上下文单击的情况下正确地重新创建了新的GameObject(可参见下面的示例)。函数还应该调用 Undo.RegisterCreatedObjectUndo以创建可撤消的命令,并调用Selection.activeObject 以使新创建的对象被选中。注意,为了将“ GameObject /”中的菜单项传播到hierarchy的Create下拉菜单和hierarchy context菜单中,必须将其与其他GameObject创建菜单项分组。可以通过将其优先级设置为10来实现(请参见下面的示例)。注意,出于传统目的,“ GameObject / Create Other”中未设置显式优先级的MenuItems将获得优先级10,而不是默认的1000-我们鼓励使用比“ Create Other”更具描述性的类别名称,并将显式优先级设置为10 。
创建菜单项
public class EditorTest
{
//在测试菜单中添加测试菜单项
[MenuItem("测试/测试")]
static void DoSomething()
{
Debug.Log("测试...");
}
}
创建带启用条件的菜单项
using UnityEditor;
using UnityEngine;
public class EditorTest
{
//需条件才能点击的菜单项
[MenuItem("测试/测试")]
static void DoSomething()
{
Debug.Log("测试...");
}
//上面菜单的条件
[MenuItem("测试/测试", true)]
static bool ValidateDoSomething()
{
return Selection.activeTransform != null;
}
}
创建带快捷键的菜单项
using UnityEditor;
using UnityEngine;
public class EditorTest
{
//添加带有快捷键的菜单(在windows为ctrl-g,在macOS为cmd-g)
[MenuItem("测试/测试 %g")]
static void DoSomething()
{
Debug.Log("测试...");
}
}
//按住ctrl+g输出测试...
创建组件CONTENT菜单
public class EditorTest
{
//添加CONTEXT菜单
[MenuItem("CONTEXT/Transform/测试")]
static void DoSomething(MenuCommand conmand)
{
Transform body = (Transform)conmand.context;
body.position = new Vector3(10, 10, 10);
Debug.Log("设置Transform position为 " + body.position);
}
}
创建GameObje菜单
//File、Editor、Assets、Component、Window、Help菜单同理,只需吧GameObject改成对应的即可。
using UnityEditor;
using UnityEngine;
public class EditorTest
{
//添加GameObject菜单项,并设置菜单项位置,但如何控制GameObject/测试的位置?
//[MenuItem("GameObject/测试", false, 0)]
//[MenuItem("GameObject/测试", false, 1)]
[MenuItem("GameObject/测试/测试0", false, 0)]
static void CreateCustomGameObject0(MenuCommand conmand)
{
GameObject go = new GameObject("Custom Game Object1");
//设置新建物体未选中物体的子节点
GameObjectUtility.SetParentAndAlign(go, conmand.context as GameObject);
Undo.RegisterCreatedObjectUndo(go, "Create" + go.name);
Selection.activeObject = go;
}
[MenuItem("GameObject/测试/测试1", false, 11)]
static void CreateCustomGameObject1(MenuCommand conmand)
{
GameObject go = new GameObject("Custom Game Object1");
//设置新建物体未选中物体的子节点
GameObjectUtility.SetParentAndAlign(go, conmand.context as GameObject);
Undo.RegisterCreatedObjectUndo(go, "Create" + go.name);
Selection.activeObject = go;
}
//与上一个菜单间隔11个单位有分割线
[MenuItem("GameObject/测试/测试2", false, 22)]
static void CreateCustomGameObject2(MenuCommand conmand)
{
GameObject go = new GameObject("Custom Game Object2");
//设置新建物体未选中物体的子节点
GameObjectUtility.SetParentAndAlign(go, conmand.context as GameObject);
Undo.RegisterCreatedObjectUndo(go, "Create" + go.name);
Selection.activeObject = go;
}
}
(2) Constructors
MenuItem:创建一个菜单项,并在菜单项选中的时候调用其对应的static函数。MenuItem是脚本函数之前的属性。这使该函数出现在Unity菜单系统中。菜单位置由itemName 参数指定。isValidateFunction用于使MenuItem函数成为具有相同itemName参数的脚本函数之前执行的函数。第二个参数是布尔值。如果将此参数设置为该参数true,它将把关联的函数标记为在执行第二个脚本函数之前调用的函数。第二个具有相同功能的脚本功能itemName将在接下来执行。priority确定如何在菜单系统中排序对应的脚本函数。将该整数值与其他脚本函数上的值进行比较。如果该整数值大于其他值,则MenuItem脚本函数将位于列表的底部。priority还可以用于将脚本功能列表分为几组进行管理。
函数定义:
1.public MenuItem(string itemName);
2.public MenuItem(stirng itemName, bool isValidateFunction);
3.public MenuItem(string itemName, bool isValidateFunciton, int priority);
函数参数:
1.itemName:该itemName是类似菜单项路径的名称。例如,菜单项可以是“ GameObject/Do Something”。
2.isValidateFunction:如果isValidateFunction为true,则这是一个菜单项的验证函数,在调用相同itemName的菜单项函数时会先调用此验证函数。
3.priority:菜单项的显示顺序。
代码示例1:
using UnityEditor;
using UnityEngine;
public class EditorTest
{
//添加菜单项1
[MenuItem("测试/测试1",false, 100)]
static void Example1()
{
Debug.Log("测试1...");
}
//添加菜单项2
[MenuItem("测试/测试2", false, 100)]
static void Example2()
{
Debug.Log("测试2...");
}
}
代码示例2:下面这个示例显示了测试菜单如何用分割线分割菜单项。当priority参数间隔超过10个时,就会发生这种情况。注意大于10才能在菜单中创建分割线。但是按照下面的例子,脚本函数之间的优先级差值需要大于等于11.若将下面的111改为110则没有分割线。
using UnityEditor;
using UnityEngine;
public class EditorTest
{
//添加菜单项1
[MenuItem("测试/测试1",false, 100)]
static void Example1()
{
Debug.Log("测试1...");
}
//添加菜单项2
[MenuItem("测试/测试2", false, 111)]
static void Example2()
{
Debug.Log("测试2...");
}
}
二、ScriptableObject:创建保存数据的asset
(1) 描述
如果要创建不需要附加到游戏对象上的对象,可以派生一个类。
这对于仅用于存储数据的资产很有用。
要创建绑定到项目中资产的ScriptableObject实例,可使用CreateAssetMenuAttribute属性。
此类不支持null-conditional operator (?.) 和 null-coalescing operator (??) 。
(2) Static Methods
CreateInstance:创建scriptable对象的实例。若要通过Editor用户界面创建绑定到.asset文件的ScriptableObject实例,可使用CreateAssetMenuAttribute。
函数定义:
1.public static ScriptableObject CreateInstance(string className);
2.public static ScriptableObject CreateInstance(Type type);
3.public static T CreateInstance();
函数参数:
1.className:要创建的ScriptableObject的type对应的名称。
2.type:要创建的ScriptableObject的类型,System.Type实例。
函数返回值:
ScriptableObject:创建的ScriptableObject
T:创建的ScriptableObject
(3) Message
Awake:启动ScriptableObject脚本时将调用此函数。ScriptableObject脚本启动时将调用Awake。 这是在游戏启动时发生的,类似于MonoBehavior.Awake。
函数定义:ScriptableObject.Awake()
代码示例:第一个是ScriptableObject脚本。 这实现了与MonoBehaviour分开的代码。 第二个是与MonoBehaviour相关的小型脚本,该脚本从ScriptableObject脚本访问值。
using UnityEngine;
//添加菜单项到Assets/Create
[CreateAssetMenuAttribute]
//[CreateAssetMenu]
//一个ScriptableObject示例脚本。
// A和B成员变量实现与MonoBehaviour无关的功能。
public class ScriptObjExample : ScriptableObject
{
int a = 10;
int[] b = new int[5] {
0, 17, 34, 42, 67 };
public int A
{
get {
return a; }
}
//返回b数组中的值;如果x超出范围,则返回-1
public int B(int x