编辑器扩展

1.添加菜单栏:把特性应用于静态方法

参数1:菜单名的空格后面是定义快捷键(单符号得用"_"开头,组合键%=Ctrl,#=Shift,&=Alt)

参数2:通过定义一个验证方法来控制是否启用菜单栏(如:当有选择到物体时,启用,否则禁用)

参数3:菜单栏中显示的顺序(优先级),按这个值可以分组(大概相差10就分一组)

可以为已有菜单添加子菜单,如Assets/MyTools,将显示在Assets菜单栏内,同时也会在Projiect窗口的右键菜单内显示。

[MenuItem("MyTools/test1 _t", false, 12)]

[MenuItem("MyTools/test2 %t", false, 12)]

2.利用Selection类的静态方法,可以在编辑器中获取到当前所选择的对象

3.利用Undo类的静态方法,可以执行一些可以撤销的操作

Undo.DestroyObjectImmediate(Selection.activeGameObject);

4.为组件添加右键菜单栏

方式1:可以为自定义组件、内置组件添加

必须以“CONTEXT”开始,方法的参数MenuCommand mc会被自动赋值为该组件所挂载的游戏物体

[MenuItem("CONTEXT/PlayerController/菜单名")]
static void ResetSize(MenuCommand mc)
{
PlayerController pc = mc.context as PlayerController;
//接下来就可以修改组件对象pc的属性了
pc.Size = 12;
}

方式2:只能为自定义组件添加(可以编辑代码的组件),直接在该组件的代码内添加。

ContextMenu和ContextMenuItem类在UnityEngine命名空间下,与UnityEditor无关

a.为组件添加右键菜单栏

[ContextMenu("Set Color")]
void SetColor()
{
bodyColor = Color.red;
}

b.为组件的属性添加右键菜单栏

[ContextMenuItem("Menu name", "AddSize")]
public int Size = 0; void AddSize()
{
Size += 10;
}

5.自定义Inspector面板

using UnityEngine;
using UnityEditor;
using System.Collections.Generic;
// 为组件EnemyManager自定义Inspector面板显示,CanEditorMutipleObjects 表示可以同时编辑多个物体
[CustomEditor(typeof(EnemyManager)),CanEditMultipleObjects]
public class EnemyManagerInspector : Editor
{
// 这里用简单的显示控制来让大家理解自定义编辑器的流程
public static SerializedProperty enemyList, bossEnemyList,size;
void OnEnable()
{
enemyList = serializedObject.FindProperty("EnemyList");
bossEnemyList = serializedObject.FindProperty("BossEnemyList");
}
private bool isOpenDelete = false;
private bool isOpenAdd = true;
private bool isShow = false;
public override void OnInspectorGUI()
{
//表示只做附加显示,可为内置组件附加新的Inspector面板属性
base.DrawDefaultInspector();
// 更新编辑器显示的序列化属性
serializedObject.Update();
//获取组件对象
EnemyManager enemyManager = (EnemyManager)target;
//显示属性,true表示显示所有包含的成员
EditorGUILayout.PropertyField(enemyList,true);
//开始新的一行
EditorGUILayout.BeginHorizontal();
isOpenDelete = EditorGUILayout.BeginToggleGroup("是否允许删除", isOpenDelete); //包含一组元素,整体控制他们是否可编辑
if (GUILayout.Button("删除成员"))
{
}
EditorGUILayout.EndToggleGroup();
EditorGUILayout.EndHorizontal();
GUILayout.Label("**********分割线*********");
// 接受序列化赋值
serializedObject.ApplyModifiedProperties();
}
}

6.自定义窗口

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEditor;
public class MyWindow : EditorWindow {
[MenuItem("Window/show mywindow")]
static void ShowMyWindow()
{
MyWindow window= EditorWindow.GetWindow<MyWindow>();
window.Show();
}
private string name="";
void OnGUI()
{
GUILayout.Label("这是我的窗口");
name = GUILayout.TextField(name);
if (GUILayout.Button("创建"))
{
GameObject go = new GameObject(name);
//纪录操作,便于撤销
Undo.RegisterCreatedObjectUndo(go, "create gameobject");
}
}
}

7.自定义对话窗口

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEditor;
public class EnemyChange : ScriptableWizard {
[MenuItem("Tools/CreateWizard")]
static void CreateWizard()
{
ScriptableWizard.DisplayWizard<EnemyChange>("统一修改敌人","Change And Close","Change");
}
public int changeStartHealthValue = 10;
public int changeSinkSpeedValue = 1;
const string changeStartHealthValueKey = "EnemyChange.changeStartHealthValue";
const string changeSinkSpeedValueKey = "EnemyChange.changeSinkSpeedValue";
//当窗口被创建出来的时候调用的
void OnEnable()
{
changeStartHealthValue = EditorPrefs.GetInt(changeStartHealthValueKey, changeStartHealthValue);
changeSinkSpeedValue = EditorPrefs.GetInt(changeSinkSpeedValueKey, changeSinkSpeedValue);
}
//检测create按钮的点击
void OnWizardCreate()
{
GameObject[] enemyPrefabs = Selection.gameObjects; //获得选择的物体对象
//显示进度条
EditorUtility.DisplayProgressBar("进度", "0/" + enemyPrefabs.Length + " 完成修改值", 0);
int count = 0;
foreach (GameObject go in enemyPrefabs)
{
CompleteProject.EnemyHealth hp = go.GetComponent<CompleteProject.EnemyHealth>();
Undo.RecordObject(hp, "change health and speed");
hp.startingHealth += changeStartHealthValue;
hp.sinkSpeed += changeSinkSpeedValue;
count++;
EditorUtility.DisplayProgressBar("进度", count+"/" + enemyPrefabs.Length + " 完成修改值", (float)count/enemyPrefabs.Length);
}
EditorUtility.ClearProgressBar();
//显示提示信息
ShowNotification(new GUIContent(Selection.gameObjects.Length + "个游戏物体的值被修改了"));
}
//检测Other按钮的点击
void OnWizardOtherButton()
{
OnWizardCreate();
}
//当前字段值修改的时候会被调用
void OnWizardUpdate()
{
errorString = null;
helpString = null;
if (Selection.gameObjects.Length > 0)
{
helpString = "您当前选择了" + Selection.gameObjects.Length + "个敌人"; //头部提示信息
}
else
{
errorString = "请选择至少一个敌人"; //底部警告信息
}
//保存面板的修改
EditorPrefs.SetInt(changeStartHealthValueKey, changeStartHealthValue);
EditorPrefs.SetInt(changeSinkSpeedValueKey, changeSinkSpeedValue);
}
void OnSelectionChange()
{
OnWizardUpdate();
}
}

8.其它

当脚本挂载到物体上时,自动为它添加指定组件,如:[RequireComponent(typeof(Rigidbody))]

添加进菜单Component中,[AddComponentMenu("companentPathAndName")]

Unity3d编辑器扩展学习笔记的更多相关文章

  1. Unity3D编辑器扩展(六)——模态窗口

    前面我们已经写了5篇关于编辑器的,这是第六篇,也是最后一篇: Unity3D编辑器扩展(一)——定义自己的菜单按钮 Unity3D编辑器扩展(二)——定义自己的窗口 Unity3D编辑器扩展(三)—— ...

  2. Unity3D编辑器扩展(五)——常用特性(Attribute)以及Selection类

    前面写了四篇关于编辑器的: Unity3D编辑器扩展(一)——定义自己的菜单按钮 Unity3D编辑器扩展(二)——定义自己的窗口 Unity3D编辑器扩展(三)——使用GUI绘制窗口 Unity3D ...

  3. Unity3D编辑器扩展(四)——扩展自己的组件

    前面已经写了三篇: Unity3D编辑器扩展(一)——定义自己的菜单按钮 Unity3D编辑器扩展(二)——定义自己的窗口 Unity3D编辑器扩展(三)——使用GUI绘制窗口 今天写第四篇,扩展自己 ...

  4. Unity3D之UGUI学习笔记(一):UGUI介绍以及Canvas

    UGUI是Unity3D4.6官方提供的UI系统,支持2D和3D UI的开发. Unity3D UI史 OnGUI 在Unity4.6之前,官方提供的是OnGUI函数来开发UI界面,当然问题也比较多, ...

  5. Unity3D之UGUI学习笔记(三):EventSystem

    在UGUI中,EventSystem实现了所有关于交互方面的功能,和NGUI不一样的地方是,我们终于可以摆脱添加Box Collider了! 下面我们来学习一下. 对于按钮来说,直接有onClick的 ...

  6. unity3D编辑器扩展

    编辑器扩展只是在编辑项目中运行,发布出来是不会运行的. 固定创建一个文件夹Editor:所有的资源或者代码都不会被打包进去. 01.使用MenuItem添加菜单栏按钮 脚本不需要作为组件存在,可以不用 ...

  7. 【第五课】VIM编辑器(学习笔记)

    4月10日学习笔记打卡

  8. Unity3D编辑器扩展(一)——定义自己的菜单按钮

    Unity3D 引擎的编辑器拥有很强的扩展性,用的好可以帮我们省很多事情.在这里记录下如何去扩展 Unity3D 的编辑器,定制属于我们自己的开发环境. 本篇主要讲解在 Unity3D 引擎的各个窗口 ...

  9. Unity3D之ScriptableObject学习笔记

    不同与C#提供的Serializable序列化功能,ScriptableObject是Unity3D提供的一个数据存储类,我们接下来学习一下这个类的功能. 官方文档 http://docs.unity ...

随机推荐

  1. 如何使用jQuery + css3制作绚丽的网页经验总结

    常见的网页特效有:轮播,滚动,闪烁,渐变,图标GIF效果,翻转,折叠,3D变换,主视觉等.以前没有CSS3时一些复杂的特效都要借助Flash来实现,Flash为什么会被淘汰,个人认为有以下几点: 1. ...

  2. 【译文】不是所有的 bug 都值得修复的

    原文作者:KRISTINE PINEDO 译者:白乐航 欢迎访问网易云社区,了解更多网易技术产品运营经验. 作为软件开发者,您只需要为客户编写和交付出色的产品和功能. 但您也知道软件开发并不总是那么容 ...

  3. 算法 UVA 11300

    例3:题目描述 圆桌旁边坐着n个人,每个人有一定数量的金币,金币的总数能被n整除.每个人可以给他左右相邻的人一些金币,最终使得每个人的金币数量相等.你的任务是求出被转手的金币的数量的最小值. 输入格式 ...

  4. 《Beginning Java 7》 - 2 - Cloning 克隆

    Cloning 分两类:影子克隆 shallow cloning 深度克隆 deep cloning * 调用 clone() 需要 implments Cloneable.此函数为 protecte ...

  5. How to mount a remote directory in Linux using sshfs

    Q. I have access rights to one of the remote server through SSH protocol and there is no File share ...

  6. [Objective-C语言教程]决策结构(10)

    决策结构要求程序员指定一个或多个要由程序评估或测试的条件,以及在条件被确定为真时要执行的一个或多个语句,以及可选的,如果条件要执行的其他语句 被认定是假的. 以下是大多数编程语言中的典型决策结构的一般 ...

  7. [转载]Flip an image in UIImageView using UIView transitionWithView

    View animations on the iPhone are wonderful. Used properly they will delight your users and help you ...

  8. oracle navicat 可视化操作进行数据的修改

    在进行oracle数据库中的数据操作编辑时,需要小心.oracle内置的安全机制是无处不在,并且很有必要存在的. 使用navicat对oracle中数据进行select操作时,查询出的结果是只读的,这 ...

  9. 主流服务器虚拟化技术简单使用——Xen(一)

    Tips:因为博客园网页布局的原因,部分图片显示不清晰,可以放大网页查看清晰图片. 如果系统使用物理机,需要在BIOS里面开启Intel VT-x(或AMD-V),如果是VMware workstat ...

  10. PIE SDK 距离分类和最大似然分类

       1.算法功能简介 监督分类,也叫训练场地法.训练分类法,是遥感图像分类的一种,用被确认类别的样本像元去识别其他未知类别像元的过程.监督分类算法有平行算法.平行六面体法.最小距离法.最大似然法.马 ...