Chinar 的初衷是将一种简单的生活方式带给世人 使有限时间 具备无限可能 |
助力快速了解编辑器扩展如何使我们高效的工作 为初学者节省宝贵的时间,避免采坑! |
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的面板上不出现任何属性
}
}
![](https://i-blog.csdnimg.cn/blog_migrate/4bd882b635251eea4ef7120940d7006e.png)
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 只能在编辑器中使用,发布时是不会被打包
以下所有示例代码,都需要写到 OnInspectorGUI()
函数中
- 简单的示例,来向大家演示 EditorGUILayout 如何使
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()
{
//以下所有绘制函数都写到这里
}
}
3.1 EditorGUILayout.LabelField ―― 标签字段
- EditorGUILayout.LabelField :标签字段。
常用于显示文字描述,作提示使用
//制作一个标签字段。参数:label1标签字段前面的标签 label2显示在右侧的标签
EditorGUILayout.LabelField("定义信息","它只读不可写");
3.2 EditorGUILayout.SelectableLabel ―― 可选择标签
- SelectableLabel :可选择标签。
常用于显示文字描述,作提示使用
- 与 LabelField 不同的是,
它可以被复制,选择
//可选择标签。参数(显示信息)
EditorGUILayout.SelectableLabel("此标签可以被复制");
3.3 EditorGUILayout.TextField ―― 文本框
- TextField :文本输入框。
填写我们需要的文本到框中
//将文本框中的文本信息,赋值到游戏对象名
//参数:label1 文本框提示信息 label2显示的文本
//返回值:显示的文本
chinarInspector.gameObject.name = EditorGUILayout.TextField("定义信息", chinarInspector.gameObject.name);
3.4 EditorGUILayout.PasswordField ―― 密码框
- PasswordField :密码输入框。
输入框为加密显示
private string passwordText; //填充临时字符
/// <summary>
/// 重绘 Inspector
/// </summary>
public override void OnInspectorGUI()
{
//允许输入密码,并在下方显示明文(密码可见)
//参数:label标签信息 password加密密码文本
//返回:string
passwordText = EditorGUILayout.PasswordField("Type Something", passwordText);
EditorGUILayout.LabelField("显示密码", passwordText);
}
3.5 EditorGUILayout.IntField / FloatField ―― 整数、小数框
- IntField :整数输入框。
限制输入文本须为 Int 类型
- FloatField :浮点数输入框。
限制输入文本须为 float 类型
private int intNumber = 0; //输入的Int默认值和返回值
private float floatNumber = 0; //输入Float默认值和返回值
/// <summary>
/// 重绘 Inspector
/// </summary>
public override void OnInspectorGUI()
{
intNumber = EditorGUILayout.IntField("输入Int类型:", intNumber); //IntField(标签名, 输入值),返回:Int
floatNumber = EditorGUILayout.FloatField("输入Float类型:", floatNumber); //FloatField(标签名, 输入值),返回:Float
}
3.6 EditorGUILayout.Slider ―― 滑动条
- Slider :滑动条。
默认滑动条,值为 Float 类型
- IntSlider :整数滑动条。
Int类型
- MinMaxSlider :范围区域滑动条。
设定最小-最大范围区间的滑动条。滑动值是一个范围
以下脚本,添加至 3.0 脚本模板
private int intValue; //Intslider默认值和返回值
private float floatValue; //slider默认值和返回值
float minVal = -10.0f; //区间滑动条:左侧默认值
float minLimit = -20.0f; //最小值
float maxVal = 10.0f; //右侧默认值
float maxLimit = 20.0f; //最大值
/// <summary>
/// 重绘 Inspector
/// </summary>
public override void OnInspectorGUI()
{
//整数滑动条
intValue = EditorGUILayout.IntSlider("血量百分比", intValue, 0, 100); //参数(标签名,滑动值,最小值,最大值)
//浮点数滑动条
floatValue = EditorGUILayout.Slider("血量百分比", floatValue, 0, 100); //参数(标签名,滑动值,最小值,最大值)
//区间滑动条
EditorGUILayout.MinMaxSlider(ref minVal, ref maxVal, minLimit, maxLimit); //参数:(ref 左侧默认值,ref 右侧默认值,最小值,最大值)
EditorGUILayout.LabelField("最小为:", minVal.ToString());
EditorGUILayout.LabelField("最大为:", maxVal.ToString());
}
ref
可将变量 minVal、maxVal的值传递出去- 我们通过
minVal - maxVal
可得到滑动的一个区间值
3.7 EditorGUILayout.Popup―― 弹出选择菜单
- Slider :滑动条。
默认滑动条,值为 Float 类型
- IntSlider :整数滑动条。
Int类型
- MinMaxSlider :范围区域滑动条。
设定最小-最大范围区间的滑动条。滑动值是一个范围
using UnityEditor;
/// <summary>
/// 编辑器类:用于对 ChinarInspector 做编辑器处理
/// </summary>
[CustomEditor(typeof(ChinarInspector))] //关联自定义编辑器脚本 ChinarInspector
public class ChinarEditor : Editor //自定义编辑器需要继承Editor
{
private ChinarInspector chinarInspector; //关联目标对象
private bool isList; //
private void OnEnable()
{
chinarInspector = (ChinarInspector) target; //获取当前编辑自定义 Inspector 的对象
}
/// <summary>
///Popup :弹出选择菜单
/// </summary>
private readonly string[] _playerNames = {"世界好小姐", "中国好声音甲组冠军", "Chinar网站创始人"}; //数据
private int selectedIndex; //字段选项的索引
/// <summary>
/// IntPopup :弹出 Int 类型选择菜单
/// </summary>
private readonly string[] _ageNameArray = {"Chinar小学一年级时", "Chinar小学二年级时", "Chinar小学三年级时", "Chinar小学四年级时"}; //数据
private readonly int[] _ages = {20, 21, 22, 23}; // 设置 _ageNameArray 对应的int 组,用于返回
private int selectedAgeIndex; //字段选项的索引
/// <summary>
/// EnumPopup:弹出 枚举 选择菜单
/// </summary>
private enum GreatType //枚举类型
{
CUBE = 0, //Cube类型
SPHERE = 1, //Sphere类型
PLANE = 2 //Plane类型
}
private GreatType defaultGreatType; //默认枚举类型
/// <summary>
/// 重绘 Inspector
/// </summary>
public override void OnInspectorGUI()
{
//Popup - 弹出选择菜单
//Popup(提示标签,选择索引,数据数组) 返回:Int
selectedIndex = EditorGUILayout.Popup("选择菜单", selectedIndex, _playerNames);
//IntPopup - 整数弹出选择菜单
//IntPopup(提示标签,选择索引,数据数组,数据数组对应的 int 数组) 返回:int 数组中的对应 int 值
selectedAgeIndex = EditorGUILayout.IntPopup("整数选择菜单: ", selectedAgeIndex, _ageNameArray, _ages);
EditorGUILayout.LabelField("Chinar这个时候年纪是", selectedAgeIndex.ToString());
//EnumPopup - 枚举弹出选择菜单
//EnumPopup(提示标签,枚举对象) 返回:枚举类型
defaultGreatType = (GreatType) EditorGUILayout.EnumPopup("Primitive to create:", defaultGreatType);
}
}
3.8
EditorGUILayout (Horizontal/Vertical) ―― 横向布局/纵向布局
- BeginHorizontal :开始
绘制横向布局
,以 EndHorizontal 结束。两者成对出现- BeginVertical :开始
绘制竖向布局
,以 EndVertical 结束。两者成对出现
纵向布局就不提供代码了 ( 只需替换 BeginHorizontal 与 EndHorizontal )
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() 对应起来)
}
}
支持
May Be ―― 开发者,总有一天要做的事!
Chinar 提供一站式《零》基础教程 使有限时间 具备无限可能! |
先点击领取 ―― 阿里全产品优惠券 (享受最低优惠)
Chinar 免费服务器、建站教程全攻略!( Chinar Blog )
![](https://i-blog.csdnimg.cn/blog_migrate/d2702ccd2c6f465492f4a8db351a76e1.png)
![Chinar交流群 Chinar](http://pub.idqqimg.com/wpa/images/group.png)
本博客为非营利性个人原创,除部分有明确署名的作品外,所刊登的所有作品的著作权均为本人所拥有,本人保留所有法定权利。违者必究
对于需要复制、转载、链接和传播博客文章或内容的,请及时和本博主进行联系,留言,Email: ichinar@icloud.com
对于经本博主明确授权和许可使用文章及内容的,使用时请注明文章或内容出处并注明网址