Unity 编辑器扩展五 Handles 扩展Scene视图
2021-12-10 本文已影响0人
合肥黑
参考
Unity Editor 基础篇(四):Handles
【Unity 编辑器】扩展总结六:扩展Scene视图
官方文档 https://docs.unity.cn/cn/current/ScriptReference/Handles.RadiusHandle.html
一、Handles.RadiusHandle 半径控制器
如图,调节areaOfEffect值时,场景中会出现一个球体,展示这个值的影响范围。

EffectRadius.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class EffectRadius : MonoBehaviour
{
public float areaOfEffect = 1;
}
EffectRadiusEditor.cs
// Name this script "EffectRadiusEditor"
using UnityEngine;
using UnityEditor;
[CustomEditor(typeof(EffectRadius))]
public class EffectRadiusEditor : Editor
{
public void OnSceneGUI()
{
EffectRadius t = (target as EffectRadius);
EditorGUI.BeginChangeCheck();
float areaOfEffect = Handles.RadiusHandle(Quaternion.identity, t.transform.position, t.areaOfEffect);
if (EditorGUI.EndChangeCheck())
{
Undo.RecordObject(target, "Changed Area Of Effect");
t.areaOfEffect = areaOfEffect;
}
}
}
注意OnSceneGUI。视图的扩展主要通过OnSceneGUI()方法实现,因为场景扩展是基于场景对象的,所以可以选择不同的对象实现不同的场景视图操作。
二、示例
点选场景对象,显示该场景的坐标位置信息。

using UnityEngine;
public class SceneExt : MonoBehaviour
{
}
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));
三、示例
该脚本挂载在场景对象身上
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();
}
}
}