【Unity编辑器开发与拓展Handles】
以下是 Unity 中 Handles 的详细介绍及其与 Gizmos 的区别,结合官方文档和技术解析整理:
一、Handles 的核心功能
Handles 是 UnityEditor 命名空间下的类,用于在 Scene 视图中创建交互式 3D 控件,支持编辑场景对象属性。其核心特点包括:
- 
交互性
- 提供可拖拽、旋转、缩放的控件(如箭头、滑块、圆弧),用户可通过鼠标直接操作修改对象属性。
 - 示例:通过 
Handles.ScaleValueHandle调整护盾半径,实时更新数值。 
// 修改 shieldArea 的交互式手柄myObj.shieldArea = (float)Handles.ScaleValueHandle( myObj.shieldArea, myObj.transform.position + myObj.transform.forward * myObj.shieldArea, myObj.transform.rotation, 1, Handles.ConeHandleCap, 1); - 
自定义绘制
- 支持绘制复杂图形(如圆弧 
DrawWireArc、圆盘DrawWireDisc),并叠加 2D GUI 控件(按钮、标签)。 - 需在 
Editor.OnSceneGUI方法中使用,且配合Handles.BeginGUI()/EndGUI()包裹 2D UI 代码。 
 - 支持绘制复杂图形(如圆弧 
 - 
坐标系转换
- 通过 
HandleUtility实现 2D 屏幕坐标与 3D 世界坐标的转换(如GUIPointToWorldRay)。 
 - 通过 
 
二、Handles 与 Gizmos 的关键区别
以下是两者核心差异的对比:
Editor 并在 OnSceneGUI 中调用MonoBehaviour 的 OnDrawGizmos 中使用PositionHandle, Button, DrawWireArcDrawWireCube, DrawLine, DrawSphere代码示例对比
// Handles 示例:自定义旋转手柄(仅编辑器生效)[CustomEditor(typeof(MyComponent))]public class MyEditor : Editor { void OnSceneGUI() { MyComponent comp = target as MyComponent; comp.rotation = Handles.RotationHandle(comp.rotation, comp.position); }}// Gizmos 示例:显示选中对象的球体范围(运行时也可见)public class GizmoDemo : MonoBehaviour { void OnDrawGizmosSelected() { Gizmos.color = Color.green; Gizmos.DrawWireSphere(transform.position, 1.0f); }}
三、Handles 的典型应用场景
- 
路径点编辑器
- 用 
PositionHandle拖拽编辑路径点位置,DrawPolyLine连接点形成路径。 
 - 用 
 - 
自定义属性控件
- 为数值型属性(如半径、角度)创建滑块 (
Slider)、旋钮 (Knob),替代 Inspector 输入。 
 - 为数值型属性(如半径、角度)创建滑块 (
 - 
程序化生成内容的编辑
- 编辑程序生成的地形标记点或不可见对象(如触发器区域),通过 
Handles.Label显示关键信息。 
 - 编辑程序生成的地形标记点或不可见对象(如触发器区域),通过 
 
四、开发注意事项
- 
性能优化
- 避免在 
OnSceneGUI中频繁计算复杂逻辑,否则会导致 Scene 视图卡顿。 
 - 避免在 
 - 
条件编译
- 使用 
#if UNITY_EDITOR包裹 Handle 代码,避免发布版本包含编辑器依赖。 
 - 使用 
 - 
坐标系问题
- 绘制图形时需通过 
Handles.SetCamera(Camera.main)指定相机,否则可能显示错位。 
 - 绘制图形时需通过 
 
总结
Handles:专注编辑器交互,为自定义组件提供类 Unity 原生工具的操控体验(如拖拽手柄、按钮),是编辑器扩展的核心工具。Gizmos:专注运行时可视化,用于调试信息展示(如碰撞体、射线方向),无交互能力。
建议结合使用两者:例如用 Gizmos 显示对象范围,用 Handles 提供编辑控件。更多用例可参考 官方手册


