0%

Unity 插件开发基础(一)

前言

不必废话,既然要学 Unity ,那么开发个插件很理所应当吧。
下面将是我总结的插件学习笔记,不定期更新。

菜单项相关

1. MenuItem 特性

使用 MenuItem 特性增加菜单项

1
2
3
4
[MenuItem("Tools/Test1")]
public static void TheTest1(){
Debug.Log("you click the Tools/Test1 ");
}

在一般的 CShape 脚本文件中,为一个公有静态类添加 MenuItem 特性,可将相关逻辑显示到菜单栏中。上面的这句的结果就是(下图):
1

点击后的结果就是(下图)
2

注意

  • 不需要代码所在的脚本被挂载在某个 GameObject 上,直接存放在 Assets 中就行了
  • 使用 MenuItem 特性需要引入命名空间 using UnityEditor
  • MenuItem 的参数是一个字符串 string ,用 / 可以表示目录层级
  • 作为插件逻辑的代码必须是静态的,public 和 private 倒是无所谓

增加快捷键

可以为我们刚创建的一个菜单项增加快捷键。

1
2
3
4
[MenuItem("Tools/Test1 _w")]
public static void TheTest1(){
Debug.Log("you click the Tools/Test1 ");
}

再参数字符串中加入** “空格 + 下划线 + 按键”** ,就能增加快捷键,如下图(按下 W 就会启动)
3

注意

  • 必须是 ** 空格 + 下划线(或其他符号) + 按键”** ,其中空格千万不要忘了
  • 符号结合按键,就是我们要定制的快捷键,其中:
  1. 下划线 ( _ ) :表示单一按键,后跟一般按键(按键不区分大小写),_W 就相当于 W
  2. # : 表示 shift 按键,#W 就相当于 shift + W
  3. % : 表示 ctrl 按键, %W 就相当于 ctrl + W
  4. & : 表示 alt 按键, &W 就相当于 alt + W
  • 其实按键可以组合使用,比如 %#W 就相当于 ctrl+ shift + W
  • 还要注意设定的快捷键可能会和原本热键有冲突,需要注意

其他参数

1
MenuItem(string itemName, bool isValidateFunction, int priority);
  1. itemName : 则是菜单项名称以及目录层级
  2. isValidateFunction :默认为 false ,true 则不会在菜单栏出现,会有同名 ItemName 项调用前被调用
  3. priority : 优先级,其实是菜单项之间的顺序,越小则越靠前



2. AddComponent 特性

用于添加在 Component 下的菜单项。

1
2
3
4
[AddComponentMenu("BB/MyComponent")]
public class MyPlugins : MonoBehaviour
{
}

效果:
4

注意

  • 同样需要引入命名空间 using UnityEditor
  • 由于是用于增加组件的选项,因此特性应该加载我们定义的组件的类名上(与类同级
  • 重载:AddComponentMenu(string menuName, int order)



3. ContextMenu 特性

上下文菜单则是提供在 Inspector 上对组件进行额外的操作的特性。因此特性必须写在 实例方法上。

1
2
3
4
5
[ContextMenu("test")]
public void ThisIsContext()
{

}

效果:
5

注意

  • 必须加在对应组件的实例方法(非静态方法)
  • 当点击添加的选项就会执行我们编写的逻辑
  • 重载:ContextMenu(string itemName, bool isValidateFunction, int priority)



4. RequireComponent 特性

1
2
3
4
[RequireComponent(typeof(Rigidbody))]
public class MyPlugins : MonoBehaviour
{
}

很简单,当我们挂载这个脚本时,会自动为所在对象增加 Rigidbody 组件。
一般用于防止我们会遗漏增加某些组件。

注意

  • 如果组件已经挂载在对象上,之后再添加 RequireComponent 特性,是没有效果的,必须重新挂载组件,才会自动增添 RequireComponent 的组件。
  • RequireComponent 可以有多个
  • 一旦组件增加了 RequireComponent 特性,则 Inspector 上的对应组件是无法删除的。除非去掉 RequireComponent



Inspector 相关特性

1. HideInInspector 特性

一般我们将成员变量访问性改为 public ,就能在 Inspector 界面中显示并对其数值进行初始化。

但有时我们希望 public 访问性的参数不显示在 Inspector 面板中,因为我们可能只在运行时才去根据情况进行特定初始化。

HideInInspector 特性可以使得 public 访问性变量不在面板中显示。

1
2
[HideInInspector]
public float range;



2. NoSerialized 特性

1
2
[NonSerialized]
public float speed;

不序列化,和 HideInInspector 相同作用,不过需要注意的,此特性是 System 命名空间下的特性,非 Unity 内置特性。与其相应的有 Serializable 特性,即序列化。

注意

  • 这属于数据序列化的相关特性,序列化往往被用于数据的传输。(具体可自行了解)
  • 不过 Serializable 特性,标识我们自定义的类,这样可以使得我们定义的类的属性可展示在 Inspector 上,如:
1
2
3
4
5
6
7
8
[Serializable]
public class MyType{
public int speed;
}

public class MyComponent : MonoBehaviour{
public MyType typr = new MyType(); // typr 就会显示在 Inspector 面板上
}
  • NonSerialized 与 HideInspector 不同在于,前者并不保存对变量初始化的修改,后者只是单纯的隐藏,而对参数进行的修改依旧会被应用。


3. SerializeField 特性

1
2
3
[SerializeField]
private float speed;

可将我们定义的私有变量显示在 Inspector 上,并且可修改。效果和访问符为 public 相同。

不过并不影响变量是私有的访问域。


# 结语 这就是基本的菜单项相关的特性,后续会继续更新其余部分。