编辑器扩展总结
工欲善其事必先利其器
引言: 在项目开发中,编辑器扩展为开发者提供了开发自定义工具的功能,让开发者更加便利地使用编辑器开发项目。如若博客中存在错误,还请不吝赐教。所有参考的博客或者视频来源将在文末展示。
开发版本: Unity 2019.4.9f1
相关博客传送门
一、编辑器开发入门
八、EditorPrefs、ScriptableObject、Undo
扩展Scene视图
OnSceneGUI的使用
场景视图是编辑游戏对象的窗口,扩展场景视图可以实现网格编辑,地形绘制或高级Gizmos等操作。视图的扩展主要通过OnSceneGUI()方法实现,因为场景扩展是基于场景对象的,所以可以选择不同的对象实现不同的场景视图操作。
如下示例实现了点选场景对象,显示该场景的坐标位置信息。
先创建一个脚本,挂载在场景对象身上。
using UnityEngine;
public class SceneExt : MonoBehaviour
{
}
再编写编辑器脚本,方式和创建Inspector扩展方式差不多,也需要放在Editor文件夹内
using UnityEditor;
using UnityEngine;
[CustomEditor(typeof(SceneExt))]
public class SceneExtEditor : Editor
{
//获取SceneExt脚本对象
private SceneExt _target { get { return target as SceneExt; } }
private void OnSceneGUI()
{
//操作句柄
Handles.Label(_target.transform.position,_target.transform.name + " : " + _target.transform.position);
//绘制GUI的内容必须要在BeginGUI、EndGUI的方法对中
Handles.BeginGUI();
//设置GUI绘制的区域
GUILayout.BeginArea(new Rect(50, 50, 200, 200));
GUILayout.Label("Scene 扩展练习");
GUILayout.EndArea();
Handles.EndGUI();
}
}
注意:OnSceneGUI方法是通过Handles来绘制内容的,Handles类提供了大量用于绘制句柄的API。如果想要绘制GUI,则必须要在BeginGUI、EndGUI的方法对中。
有时候希望选择了场景对象后,点击场景窗口进行操作的时候,场景视图扩展依旧显示,这就需要设置场景对象的焦点为消极模式。
在OnSceneGUI方法内调用如下API:
HandleUtility.AddDefaultControl(GUIUtility.GetControlID(FocusType.Passive));
Handles简单使用
该脚本挂载在场景对象身上
using UnityEngine;
public class SceneExt : MonoBehaviour
{
public bool showLabel = true;
public bool showLine = true;
public bool showSlider = true;
public bool showRadius = true;
public bool showCircleHandleCap = true;
public bool showSphereHandleCap = true;
public bool showGUI = true;
public Vector3 sliderPos = Vector3.forward;
public float areaRadius = 1;
public float circleSize = 1;
}
该编辑器脚本放在Editor文件夹内
using UnityEditor;
using UnityEngine;
[CustomEditor(typeof(SceneExt))]
public class SceneExtEditor : Editor
{
//获取SceneExt脚本对象
private SceneExt _target { get { return target as SceneExt; } }
private void OnSceneGUI()
{
if (_target.showLabel)
{
//操作句柄,显示文本
Handles.Label(_target.transform.position + Vector3.up * 0.5f, _target.transform.name + " : " + _target.transform.position);
}
if (_target.showLine)
{
//修改句柄的颜色
Handles.color = Color.yellow;
//绘制一条线
Handles.DrawLine(_target.transform.position, Vector3.up * 5);
}
if (_target.showSlider)
{
Handles.color = Color.red;
//绘制一个可以沿着某个轴向的3D滑动条
_target.sliderPos = Handles.Slider(_target.sliderPos, _target.transform.forward);
}
if (_target.showRadius)
{
Handles.color = Color.blue;
//绘制一个半径控制手柄
_target.areaRadius = Handles.RadiusHandle(Quaternion.identity, _target.transform.position, _target.areaRadius);
}
if (_target.showCircleHandleCap)
{
//获取Y轴的颜色
Handles.color = Handles.yAxisColor;
//绘制一个圆环
Handles.CircleHandleCap(0, _target.transform.position + Vector3.up * 2, Quaternion.Euler(90, 0, 0), _target.circleSize, EventType.Repaint);
}
if (_target.showSphereHandleCap)
{
Handles.color = Color.green;
//绘制一个球形
Handles.SphereHandleCap(1, _target.transform.position, Quaternion.identity, HandleUtility.GetHandleSize(_target.transform.position), EventType.Repaint);
}
if (_target.showGUI)
{
//绘制GUI的内容必须要在BeginGUI、EndGUI的方法对中
Handles.BeginGUI();
//设置GUI绘制的区域
GUILayout.BeginArea(new Rect(50, 50, 200, 200));
GUILayout.Label("Scene 扩展练习");
GUILayout.EndArea();
Handles.EndGUI();
}
}
}