一.什么是编辑器拓展
Unity是一个编辑器,编辑器就是可以进行编辑的工具,比如我们的文本Text就是一个文本编辑器,那我们的Unity其实就是用来编辑游戏的,编辑的扩展就是对编辑器本身的功能进行添加。但是由于Unity是不开源的引擎,所以我们只能使用特定的功能去编辑。
UNITY3D的IDE本身的强大,除了表现在其提供的强大功能外,更让人喜欢的,是它高度的可扩展特性。这也是一个项目开发中,必不可少的环节。
二.菜单按钮的拓展
对菜单按钮进行拓展,首先新建一个C#脚本MenuItemTool。
首先引入命名空间 UnityEditor
1.使用方法MenuItem来创建菜单
比如我们创建一个用来清除缓存的按钮。引号里面是菜单的名字,ClearMemory是一级菜单,二级和三级菜单用/表示。
[MenuItem("ClearMemory/ClearAll")]
我们想在点击ClearAll的时候执行某些方法,需要在下面创建一个和菜单名相同的静态方法。
static void ClearAll()
{
Debug.Log("清除所有缓存");
}
在这里,创建的方法必须是静态的,如果不是静态的,菜单就不能显示
因为静态成员是和类一起存在的,有了类就有了静态成员,我们可以直接通过类来调用静态成员,非静态成员是和对象一起存在的,有了对象才有非静态成员,非静态成员通过对象来访问。
2.修改优先级
MenuItem里面除了添加菜单名字外,还可以添加两个参数,F12点进MenuItem可以查看
优先级和是否可用,数字越小,优先级越高
[MenuItem("ClearMemory/ClearAll",false,1)]
static void ClearAll()
{
Debug.Log("清除所有缓存");
}
[MenuItem("ClearMemory/ClearOther/ClearShopInfor", false, 2)]
static void ClearShopInfor()
{
Debug.Log("清除商店缓存");
}
这里:true代表不可用,False可用,true的时候,菜单不显示,没有设置优先级的菜单取子菜单的最大优先级。
3.菜单分组
我们会发现在菜单中会有一条线把二级菜单分开,这个就是多二级菜单进行分组。
只要两个菜单的优先级相差11,就会进行分组
4.在系统自带的菜单下面添加二级菜单
比如在GameObject中添加菜单,我们只需要添加GameObject/
没有添加优先级,是在最下面的,我们可以测试一下在什么优先级对应的排名。
也可以把我们的Text插入到二级菜单中。
三.属性面板拓展
1.贴图的增加
在Script中新建一个脚本ChangeInspector,首先我们让脚本显示一张贴图
public Texture texture;
回到场景中,创建一个空的物体Enemy,将我们创建的脚本挂在上面,此时,我们的属性面板中就会显示TexTure属性,但是我们发现,我们只能在这里选择贴图,但是看不见贴图。那我们就通过编辑Inspector面板来显示出贴图
我们在Editor中新建一个脚本InspectorEditor。继承Editor类,并导入命名空间
然后我们给他自定义脚本
[CustomEditor(typeof(ChangeInspector))]
我们要把贴图显示出来,就要绘制一个贴图层
重写一下OnInspectorGUI,我们要拓展面板里的属性,必须要重写这个方法
获取一下对象
接下来开始绘制贴图层
objectField有四个参数:标签 贴图 类型 是否允许指定物体,最后转换成Texture类型
public override void OnInspectorGUI()
{
base.OnInspectorGUI();
ChangeInspector inspectorObj = (ChangeInspector)target;
//绘制帖图槽
inspectorObj.texture =EditorGUILayout.ObjectField("选择贴图", inspectorObj.texture, typeof(Texture), true) as Texture;
}
回到面板中,我们就可以看到我们的贴图可以显示出来了
此时我们就可以把Texture属性隐藏了
[HideInInspector]
public Texture texture;
2.修改Rect
我们再创建一个Rect类型的属性rectValue
public Rect rectValue;
回到Editor中修改
RectField中的参数:标签 显示的目标
inspectorObj.rectValue = EditorGUILayout.RectField("窗口坐标", inspectorObj.rectValue);
3.文本输入框
inspectorObj.remark = EditorGUILayout.TextField("输入姓名", inspectorObj.remark);
4.滑动条
public float sliderValue = 0.8f;
inspectorObj.sliderValue = EditorGUILayout.Slider("进度值",inspectorObj.sliderValue, 0f, 1f);
三个参数,初始值 最小值最大值
5.复选框
public bool isOpen = true;
inspectorObj.isOpen = EditorGUILayout.Toggle("开始", inspectorObj.isOpen);
6.下拉列表
我们在Script中新建一个脚本ToolType,添加一个命名空间Tool,并添加一个枚举类型EdirType
namespace Tool
{
public enum EdirType
{
up,
down,
left,
right
}
public class ToolType : MonoBehaviour {
}
}
回到ChangeInspector脚本中,引用一下Tool命名空间
定义一个枚举值theType默认为up
private EdirType theType = EdirType.up;
public EdirType TheType
{
get {
return theType;
}
set {
theType = value;
}
}
回到Editor中,也引用一下命名空间
绘制下拉列表
inspectorObj.TheType = (EdirType)EditorGUILayout.EnumPopup("方向", inspectorObj.TheType);
7.绘制一个分组,通过复选框决定是否开启
到Editor中
声明一个bool值 GroundEnable=false
GUILayout.Label("*****以下是附加设置*****");//首先绘制一个Label
groundEnable = EditorGUILayout.BeginToggleGroup("是否开启附加设置", groundEnable);//用GroundEnable来控制开启分组
inspectorObj.theValue1 = EditorGUILayout.FloatField("1", inspectorObj.theValue1);//绘制两个float类型的值
inspectorObj.theValue2 = EditorGUILayout.FloatField("2", inspectorObj.theValue2);
inspectorObj.isAdd = EditorGUILayout.Toggle("开启", inspectorObj.isAdd);//绘制一个复选框
EditorGUILayout.EndToggleGroup();//闭合分组
8.扩展自带组件
在Editor中新建一个脚本CameraEditor
继承Editor 引用命名空间
自定义脚本
[CustomEditor(typeof(Camera))]
重写一下GUI
这里因为我们要重写自带的属性,所以应该使用base.DrawDefaultInspector
public override void OnInspectorGUI()
{
base.DrawDefaultInspector();
GUILayout.Label("1111111111111");//我们添加一个Label
if (GUILayout.Button("点击处理"))//绘制一个按钮
{
Debug.Log("检测到点击了");
}
}
其他的组件也是一样,想要扩展哪一个组件,我们就把组件的名字传进来