Chinar 的初衷是将一种简单的生活方式带给世人 使有限时间 具备无限可能 |
助力快速了解编辑器扩展如何使我们高效的工作 为初学者节省宝贵的时间,避免采坑! |
----------
1
Intro —— 介绍
有些插件会写大量的编辑器类,来便于开发者对插件属性的调整。
这其中就有很多对 Inspector
面板重新绘制,使开发者可以可视化的调整相应参数
2
Custom Inspector Editor ―― 自定义检视面板编辑器
众所周知,一个继承 MonBehaviour 类的脚本
我们可以通过 Public
来使其中变量显示在Inspector
面板,以便于我们对其参数值进行调整
1 —— 首先,我们自定义一个要被扩展的目标脚本
需继承 MonBehaviour
public class ChinarInspector: MonoBehaviour
{
public int A; //字段A
public string B;//字段B
}
2 —— 需要一个与之对应的编辑器脚本,对目标脚本在 Inspector 面板上的显示,进行重写
该脚本需要放在
Editor
文件夹中,并且要继承 Editor
using UnityEditor;
[CustomEditor(typeof(ChinarInspector))] //特性:自定义编辑类 ChinarInspector
public class ChinarEditor : Editor //需要继承 Editor
{
private ChinarInspector chinarInspector; // 类对象
private void OnEnable()
{
chinarInspector = (ChinarInspector) target; //获取当前编辑自定义Inspector的对象(官方解释授检查的对象)
}
//通过对该方法的重写,可以对 Inspector 面板重新绘制,添加自己自定义GUI
//既然说的自定义UI,就会覆盖我们关联脚本本身在面板的绘制
public override void OnInspectorGUI()
{
//不写任何代码,ChinarInspector的面板上不出现任何属性
}
}

OnEnable
函数,在Editor
类中与MonoBehavior
类中是完全不同的
调用时机 | Editor | MonoBehavior |
---|---|---|
OnEnable | 1:每次聚焦 Unity 引擎窗口时 |
脚本挂载的 GameObject 对象激活时 |
OnEnable | 2:点击 脚本挂载的 GameObject 对象时 | |
OnEnable | 3:点击 Inspector ,其他模块(例如scene 面板) |
关联后的自定义脚本前在 Inspector 如下所示:
3
EditorGUILayout ―― 编辑器界面自动布局
- EditorGUILayout :编辑器 UI 自动布局类,绘制的所有控件都具备
自动布局(UI自适应)
效果
与 GUILayout 的差异:
- 拥有部分编辑器专用控件,
- 只能运行在编辑器内
- 自适应性较强
英文好的直接:EditorGUILayout 官方API链接
EditorGUILayout 只能在编辑器中使用,发布时是不会被打包
简单的示例,来向大家演示 EditorGUILayout 如何使 Inspector 面板更加直观,易用
3.1
EditorGUILayout.LabelField ―― 制作一个标签字段(通常用于显示只读信息)
using UnityEditor;
/// <summary>
/// 编辑器类:用于对 ChinarInspector 做编辑器处理
/// </summary>
[CustomEditor(typeof(ChinarInspector))] //关联自定义编辑器脚本 ChinarInspector
public class ChinarEditor : Editor //自定义编辑器需要继承Editor
{
private ChinarInspector chinarInspector; //关联目标对象
private void OnEnable()
{
chinarInspector = (ChinarInspector) target; //获取当前编辑自定义 Inspector 的对象
}
/// <summary>
/// 重绘 Inspector
/// </summary>
public override void OnInspectorGUI()
{
//制作一个标签字段(通常用于显示只读信息)
EditorGUILayout.LabelField("定义信息","它只读不可写");
//参数:label1标签字段前面的标签 label2显示在右侧的标签 --无返回
}
}
3.2
EditorGUILayout.SelectableLabel ―― 可选择标签(通常用于显示只读信息,可以被复制粘贴)
using UnityEditor;
/// <summary>
/// 编辑器类:用于对 ChinarInspector 做编辑器处理
/// </summary>
[CustomEditor(typeof(ChinarInspector))] //关联自定义编辑器脚本 ChinarInspector
public class ChinarEditor : Editor //自定义编辑器需要继承Editor
{
private ChinarInspector chinarInspector; //关联目标对象
private void OnEnable()
{
chinarInspector = (ChinarInspector) target; //获取当前编辑自定义 Inspector 的对象
}
/// <summary>
/// 重绘 Inspector
/// </summary>
public override void OnInspectorGUI()
{
//可选择标签(通常用于显示只读信息,可以被复制粘贴)
//参数:text显示的文本 无返回值
EditorGUILayout.SelectableLabel("此标签可以被复制");
}
}
3.3
EditorGUILayout.TextField ―― 文本字段 (可以有默认值,有返回值,并且可以在Inspector面板赋值)
using UnityEditor;
/// <summary>
/// 编辑器类:用于对 ChinarInspector 做编辑器处理
/// </summary>
[CustomEditor(typeof(ChinarInspector))] //关联自定义编辑器脚本 ChinarInspector
public class ChinarEditor : Editor //自定义编辑器需要继承Editor
{
private ChinarInspector chinarInspector; //关联目标对象
private void OnEnable()
{
chinarInspector = (ChinarInspector) target; //获取当前编辑自定义 Inspector 的对象
}
/// <summary>
/// 重绘 Inspector
/// </summary>
public override void OnInspectorGUI()
{
//文本字段 可读 可写
chinarInspector.gameObject.name = EditorGUILayout.TextField("定义信息", chinarInspector.gameObject.name);
//参数:label1标签字段前面的标签 label2默认显示文本 --有返回值
}
}
3.4
EditorGUILayout.PasswordField ―― 密码字段(通常用于显示只读信息,可以被复制粘贴)
using UnityEditor;
/// <summary>
/// 编辑器类:用于对 ChinarInspector 做编辑器处理
/// </summary>
[CustomEditor(typeof(ChinarInspector))] //关联自定义编辑器脚本 ChinarInspector
public class ChinarEditor : Editor //自定义编辑器需要继承Editor
{
private ChinarInspector chinarInspector; //关联目标对象
private void OnEnable()
{
chinarInspector = (ChinarInspector) target; //获取当前编辑自定义 Inspector 的对象
}
private string text;
/// <summary>
/// 重绘 Inspector
/// </summary>
public override void OnInspectorGUI()
{
//创建密码字段并可视化在密码字段有什么键入
//参数:label开关按钮前面的可选标签 password编辑的密码 有返回值
text = EditorGUILayout.PasswordField("Type Something:", text);
EditorGUILayout.LabelField("显示密码",text);
}
}
3.5
EditorGUILayout.IntField/FloatField ―― 整数字段
using UnityEditor;
/// <summary>
/// 编辑器类:用于对 ChinarInspector 做编辑器处理
/// </summary>
[CustomEditor(typeof(ChinarInspector))] //关联自定义编辑器脚本 ChinarInspector
public class ChinarEditor : Editor //自定义编辑器需要继承Editor
{
private ChinarInspector chinarInspector; //关联目标对象
private void OnEnable()
{
chinarInspector = (ChinarInspector) target; //获取当前编辑自定义 Inspector 的对象
}
private int intNumber = 0;//输入的Int默认值和返回值
private float floatNumber = 0;//输入Float默认值和返回值
/// <summary>
/// 重绘 Inspector
/// </summary>
public override void OnInspectorGUI()
{
intNumber = EditorGUILayout.IntField("输入Int类型:", intNumber);// 整数字段:返回整数,由用户输入的值(参数:标签名,默认整型字段)
floatNumber = EditorGUILayout.FloatField("输入Float类型:", floatNumber);//浮点数字段:返回小数,由用户输入的值(参数:标签名,默认浮点数字段)
}
}
3.6
EditorGUILayout.Slider /IntSlider/MinMaxSlider―― 滑动条/整数滑动条/最小最大滑动条
using UnityEditor;
/// <summary>
/// 编辑器类:用于对 ChinarInspector 做编辑器处理
/// </summary>
[CustomEditor(typeof(ChinarInspector))] //关联自定义编辑器脚本 ChinarInspector
public class ChinarEditor : Editor //自定义编辑器需要继承Editor
{
private ChinarInspector chinarInspector; //关联目标对象
private void OnEnable()
{
chinarInspector = (ChinarInspector) target; //获取当前编辑自定义 Inspector 的对象
}
private int intNumber = 0;//Intslider默认值和返回值
private float floatNumber = 0;//slider默认值和返回值
float minVal = -10.0f;//左侧默认值
float minLimit = -20.0f;//最小值
float maxVal = 10.0f;//右侧默认值
float maxLimit = 20.0f;//最大值
/// <summary>
/// 重绘 Inspector
/// </summary>
public override void OnInspectorGUI()
{
//整数滑动条
intNumber = EditorGUILayout.IntSlider("血量百分比", intNumber, 0, 100); //绘制 Intslider 滑动条 参数(标签名,value编辑的值,最小值,最大值)
//浮点数滑动条
floatNumber = EditorGUILayout.Slider("血量百分比", floatNumber, 0, 100); //绘制 slider 滑动条 参数(标签名,value编辑的值,最小值,最大值)
//最小最大滑动条
EditorGUILayout.MinMaxSlider(ref minVal,ref maxVal, minLimit, maxLimit); //参数:(左侧默认值,右侧默认值,最小值,最大值)
EditorGUILayout.LabelField("最小为:",minVal.ToString());
EditorGUILayout.LabelField("最大为:", maxVal.ToString());
}
}
3.7
EditorGUILayout.Popup/EnumPopup/IntPopup―― 弹出选择菜单/枚举弹出选择菜单/整数弹出选择菜单
using UnityEditor;
/// <summary>
/// 编辑器类:用于对 ChinarInspector 做编辑器处理
/// </summary>
[CustomEditor(typeof(ChinarInspector))] //关联自定义编辑器脚本 ChinarInspector
public class ChinarEditor : Editor //自定义编辑器需要继承Editor
{
private ChinarInspector chinarInspector; //关联目标对象
private void OnEnable()
{
chinarInspector = (ChinarInspector) target; //获取当前编辑自定义 Inspector 的对象
}
/// <summary>
///Popup 看这里:Popup弹出选择菜单
/// </summary>
public string[] PlayerNames = new string[] { "世界好小姐", "中国好声音甲组冠军", "Chinar网站创始淫" };
public string PlayerName; //称谓
public int selectedIndex = 0;//字段选项的索引
/// <summary>
/// IntPopup 看这里:IntPopup弹出选择菜单
/// </summary>
public string[] ageNameList = new string[] { "Chinar小学一年级时", "Chinar小学二年级时", "Chinar小学三年级时", "Chinar小学四年级时" };
public int[] ages = new int[] { 20, 21, 22, 23 };
public int selectedAgeIndex = 0;//字段选项的索引
/// <summary>
/// EnumPopup看这里:EnumPopup弹出选择菜单
/// </summary>
public enum GreatType//创建预制体的枚举类型
{
CUBE = 0,//Cube类型
SPHERE = 1,//Sphere类型
PLANE = 2//Plane类型
}
private GreatType op;
/// <summary>
/// 重绘 Inspector
/// </summary>
public override void OnInspectorGUI()
{
//Popup弹出选择菜单
selectedIndex = EditorGUILayout.Popup("选择菜单", selectedIndex, PlayerNames);
//参数:label字段前面可选标签 selectedIndex字段选项的索引, 菜单集合数组 有返回值 (字段选项的索引)
//IntPopup 整数弹出选择菜单
selectedAgeIndex = EditorGUILayout.IntPopup("整数选择菜单: ", selectedAgeIndex, ageNameList, ages);
EditorGUILayout.LabelField("Chinar这个时候年纪是", selectedAgeIndex.ToString());
//参数:label字段前面的可选标签 selectedValue字段选项的索引 displayOptions弹出菜单項数组 optionValues每个选项带有值的数组。。
//返回:int,用户选择的选项的值
//EnumPopup枚举弹出选择菜单(效果同上)
op = (GreatType)EditorGUILayout.EnumPopup("Primitive to create:", op);
//参数:label字段前面的可选标签 默认枚举类型。
//返回:枚举类型
}
}
3.8
EditorGUILayout (Horizontal/Vertical) ―― 横向布局/纵向布局
using UnityEngine;
/// <summary>
/// 要被扩展的目标脚本
/// </summary>
public class ChinarInspector : MonoBehaviour
{
}
using UnityEngine;
using UnityEditor;
/// <summary>
/// 编辑器类:用于对 ChinarInspector 做编辑器处理
/// </summary>
[CustomEditor(typeof(ChinarInspector))] //关联自定义编辑器脚本 ChinarInspector
public class ChinarEditor : Editor //自定义编辑器需要继承Editor
{
private ChinarInspector chinarInspector; //关联目标对象
private void OnEnable()
{
chinarInspector = (ChinarInspector) target; //获取当前编辑自定义 Inspector 的对象
}
/// <summary>
/// 重绘 Inspector
/// </summary>
public override void OnInspectorGUI()
{
ChinarHorizontalLayout(); //横向布局
}
/// <summary>
/// 横向布局写法
/// </summary>
private void ChinarHorizontalLayout()
{
EditorGUILayout.BeginHorizontal(); //开启一个横向布局 ——(注意一个设置布局的开始 对应一个布局的结束 EditorGUILayout.EndHorizontal)
EditorGUILayout.Space(); //空行 (我们设置的横向布局 所以现在的空行 是横向的空行)
EditorGUILayout.LabelField("位置1"); //设置文本描述
EditorGUILayout.Space();
EditorGUILayout.Space();
EditorGUILayout.LabelField("位置2");
EditorGUILayout.EndHorizontal(); //注意一个设置布局的开始 对应一个布局的结束 (与上面的 EditorGUILayout.BeginHorizontal() 对应起来)
}
}
using UnityEngine;
using UnityEditor;
/// <summary>
/// 编辑器类:用于对 ChinarInspector 做编辑器处理
/// </summary>
[CustomEditor(typeof(ChinarInspector))] //关联自定义编辑器脚本 ChinarInspector
public class ChinarEditor : Editor //自定义编辑器需要继承Editor
{
private ChinarInspector chinarInspector; //关联目标对象
private void OnEnable()
{
chinarInspector = (ChinarInspector) target; //获取当前编辑自定义 Inspector 的对象
}
/// <summary>
/// 重绘 Inspector
/// </summary>
public override void OnInspectorGUI()
{
ChinarVerticalLayout(); //纵向布局
}
/// <summary>
/// 纵向布局写法
/// </summary>
private void ChinarVerticalLayout()
{
EditorGUILayout.BeginVertical(); //开启一个纵向布局 ——(注意一个设置布局的开始 对应一个布局的结束 EditorGUILayout.BeginVertical)
EditorGUILayout.Space(); //空行 (我们设置的纵向布局 所以现在的空行 是纵向的空行)
EditorGUILayout.LabelField("位置1"); //设置文本描述
EditorGUILayout.Space();
EditorGUILayout.Space();
EditorGUILayout.LabelField("位置2");
EditorGUILayout.EndVertical(); //注意一个设置布局的开始 对应一个布局的结束 (与上面的 EditorGUILayout.BeginVertical() 对应起来)
}
}
3.9
EditorGUILayout.ColorField ―― 颜色字段
using UnityEngine;
using UnityEditor;
/// <summary>
/// 编辑器类:用于对 ChinarInspector 做编辑器处理
/// </summary>
[CustomEditor(typeof(ChinarInspector))] //关联自定义编辑器脚本 ChinarInspector
public class ChinarEditor : Editor //自定义编辑器需要继承Editor
{
using UnityEditor;
using UnityEngine;
/// <summary>
/// 编辑器类:用于对 ChinarInspector 做编辑器处理
/// </summary>
[CustomEditor(typeof(ChinarInspector))] //关联自定义编辑器脚本 ChinarInspector
public class ChinarEditor : Editor //自定义编辑器需要继承Editor
{
private ChinarInspector chinarInspector; //关联目标对象
private void OnEnable()
{
chinarInspector = (ChinarInspector) target; //获取当前编辑自定义 Inspector 的对象
}
private Color color = Color.black;
/// <summary>
/// 重绘 Inspector
/// </summary>
public override void OnInspectorGUI()
{
color = EditorGUILayout.ColorField("颜色", color);
//参数:label字段前面的可选标签 value编辑的值
//返回:Color,由用户输入的值
chinarInspector.GetComponent<Renderer>().material.color = color;//目标对象的颜色根据上面我们自定义的颜色所改变
}
}
}
3.10
EditorGUILayout.CurveField ―― 曲线动画编辑器
using UnityEditor;
using UnityEngine;
/// <summary>
/// 编辑器类:用于对 ChinarInspector 做编辑器处理
/// </summary>
[CustomEditor(typeof(ChinarInspector))] //关联自定义编辑器脚本 ChinarInspector
public class ChinarEditor : Editor //自定义编辑器需要继承Editor
{
private ChinarInspector chinarInspector; //关联目标对象
private void OnEnable()
{
chinarInspector = (ChinarInspector) target; //获取当前编辑自定义 Inspector 的对象
}
AnimationCurve scaleCurve = AnimationCurve.Linear(0, 0, 1, 1); //(时间开始 : float, 数值开始 : float, 时间结束 : float, 数值结束 : float)
/// <summary>
/// 重绘 Inspector
/// </summary>
public override void OnInspectorGUI()
{
scaleCurve = EditorGUILayout.CurveField("scaleCurve", scaleCurve);//参数一标签名,默认曲线 返回值 动画曲线
var scaleValue = scaleCurve.Evaluate(0.5f);//:利用时间获取曲线的值 参数时间 横轴为时间轴 Y轴为对应的返回值
chinarInspector.transform.localScale = new Vector3(scaleValue, scaleValue, scaleValue);//对象的localScale赋值
}
}
3.11
EditorGUILayout.Foldout &EditorGUILayout.HelpBox ―― 树节点 下拉框显示 &显示一个提示框
using UnityEditor;
using UnityEngine;
/// <summary>
/// 编辑器类:用于对 ChinarInspector 做编辑器处理
/// </summary>
[CustomEditor(typeof(ChinarInspector))] //关联自定义编辑器脚本 ChinarInspector
public class ChinarEditor : Editor //自定义编辑器需要继承Editor
{
private ChinarInspector chinarInspector; //关联目标对象
private void OnEnable()
{
chinarInspector = (ChinarInspector) target; //获取当前编辑自定义 Inspector 的对象
}
private bool isList;
/// <summary>
/// 重绘 Inspector
/// </summary>
public override void OnInspectorGUI()
{
isList = EditorGUILayout.Foldout(isList, "List");//树节点 下拉框显示 参数(1 bool(true 为下拉 ,false 上折)2 标签描述)
if (isList)
{
//显示一个提示框 参数(标签显示,枚举( // None = 0, Info = 1,Warning = 2,Error = 3))
EditorGUILayout.HelpBox("HelpBox None :演示", MessageType.None);
EditorGUILayout.HelpBox("HelpBox Info :演示", MessageType.Info);
EditorGUILayout.HelpBox("HelpBox Warning :演示", MessageType.Warning);
EditorGUILayout.HelpBox("HelpBox Error :演示", MessageType.Error);
}
}
}
3.12
EditorGUILayout.BeginToggleGroup&EditorGUILayout.Toggle/ToggleLeft ―― 开关组 &右开关/左开关
using UnityEditor;
using UnityEngine;
/// <summary>
/// 编辑器类:用于对 ChinarInspector 做编辑器处理
/// </summary>
[CustomEditor(typeof(ChinarInspector))] //关联自定义编辑器脚本 ChinarInspector
public class ChinarEditor : Editor //自定义编辑器需要继承Editor
{
private ChinarInspector chinarInspector; //关联目标对象
private void OnEnable()
{
chinarInspector = (ChinarInspector) target; //获取当前编辑自定义 Inspector 的对象
}
private bool isToogleGroup;//创建开关组
private bool isToogleRight;//右侧开关bool
private bool isToogleLeft;//左侧开关bool
/// <summary>
/// 重绘 Inspector
/// </summary>
public override void OnInspectorGUI()
{
isToogleGroup = EditorGUILayout.BeginToggleGroup("开关组", isToogleGroup);//创建开关组 :参数 标签名,默认bool类型 返回值 bool
isToogleRight = EditorGUILayout.Toggle("开关在右侧", isToogleRight);//创建一个切换区域,其中的开关在右边,标签立即在它的左边 :参数 标签名,默认bool类型 返回值 bool
isToogleLeft = EditorGUILayout.ToggleLeft("开关在左侧", isToogleLeft);//ToggleLeft():创建一个切换区域,其中的开关在左边,标签立即在它的右边。
EditorGUILayout.EndToggleGroup();//一个BeginToggleGroup 对应一个EndToggleGroup语句 (固定写法)
}
}
3.13
EditorGUILayout.ObjectField ―― 物体字段(拖拽物体或拾取器选择物体)
using UnityEditor;
using UnityEngine;
/// <summary>
/// 编辑器类:用于对 ChinarInspector 做编辑器处理
/// </summary>
[CustomEditor(typeof(ChinarInspector))] //关联自定义编辑器脚本 ChinarInspector
public class ChinarEditor : Editor //自定义编辑器需要继承Editor
{
private ChinarInspector chinarInspector; //关联目标对象
private void OnEnable()
{
chinarInspector = (ChinarInspector) target; //获取当前编辑自定义 Inspector 的对象
}
Object obj;
/// <summary>
/// 重绘 Inspector
/// </summary>
public override void OnInspectorGUI()
{
obj = EditorGUILayout.ObjectField("obj", obj, typeof(Object));
//label字段前面的可选标签 obj字段显示的物体 objType物体的类型 allowSceneObjects允许指定场景物体..
//返回:Object,用户设置的物体
}
}
3.14
GUILayout.Button ―― 添加一个按钮
using UnityEditor;
using UnityEngine;
/// <summary>
/// 编辑器类:用于对 ChinarInspector 做编辑器处理
/// </summary>
[CustomEditor(typeof(ChinarInspector))] //关联自定义编辑器脚本 ChinarInspector
public class ChinarEditor : Editor //自定义编辑器需要继承Editor
{
private ChinarInspector chinarInspector; //关联目标对象
private void OnEnable()
{
chinarInspector = (ChinarInspector) target; //获取当前编辑自定义 Inspector 的对象
}
Object obj;
/// <summary>
/// 重绘 Inspector
/// </summary>
public override void OnInspectorGUI()
{
obj = EditorGUILayout.ObjectField("obj", obj, typeof(Object));
//label字段前面的可选标签 obj字段显示的物体 objType物体的类型 allowSceneObjects允许指定场景物体..
//返回:Object,用户设置的物体
if (GUILayout.Button("DebugObjName"))//创建一个按钮 参数:标签名 返回值bool
{
Debug.Log("调用按钮成功 obj的名字为"+ obj.name);
}
}
}
支持
May Be ―― 开发者,总有一天要做的事!
Chinar 提供一站式《零》基础教程 使有限时间 具备无限可能! |
先点击领取 ―― 阿里全产品优惠券 (享受最低优惠)
Chinar 免费服务器、建站教程全攻略!( Chinar Blog )


本博客为非营利性个人原创,除部分有明确署名的作品外,所刊登的所有作品的著作权均为本人所拥有,本人保留所有法定权利。违者必究
对于需要复制、转载、链接和传播博客文章或内容的,请及时和本博主进行联系,留言,Email: ichinar@icloud.com
对于经本博主明确授权和许可使用文章及内容的,使用时请注明文章或内容出处并注明网址
来源:CSDN
作者:Chinar-July_csdn
链接:https://blog.csdn.net/qq_36478821/article/details/91601183