目录
- 1. 前言
- 2 参数总览
- 3 Handles两种使用方式
- 3.1 基于Editor类的OnSceneGUI
- 3.2 基于EditorWindow
- 4 Handles绘制
- 4.1 Draw:绘制元几何体(点、线、面)
- 4.1.1 抗锯齿: DrawAAPolyLine 、 DrawAAConvexPolygon
- 4.1.2 绘制实线: DrawLine 、 DrawLines 、DrawPolyLine
- 4.1.3 绘制虚线: DrawDottedLine 、 DrawDottedLines
- 4.1.4 绘制贝塞尔曲线: DrawBezier
- 4.1.5 绘制圆形圆盘: DrawSolidDisc 、 DrawSolidArc 、 DrawSolidRectangleWithOutline
- 4.1.6 绘制圆弧: DrawWireDisc 、 DrawWireArc 、 DrawWireCube
- 4.1.7 绘制 3D 纹理: DrawTexture3DVolume 、 DrawTexture3DSlice 、 DrawTexture3DSDF
- 4.2 Handle:可视化操作数值(Vector3、Vector2、float等)
- 4.2.1 FreeMoveHandle
- 4.2.2 FreeRotateHandle
- 4.2.3 PositionHandle
- 4.2.4 RadiusHandle
- 4.2.5 RotationHandle
- 4.2.6 ScaleHandle
- 4.2.7 ScaleValueHandle
- 4.3 Caps:绘制多边形几何体(如方块,点精灵,球形,圆锥等)
- 4.3.1 ArrowHandleCap
- 4.3.2 CircleHandleCap
- 4.3.3 ConeHandleCap
- 4.3.4 CubeHandleCap
- 4.3.5 CylinderHandleCap
- 4.3.6 DotHandleCap
- 4.3.7 RectangleHandleCap
- 4.4 GUI
- 4.4.1 Label
- 4.4.2 Button
- 4.4.3 ScaleSlider
- 4.4.4 Slider
- 4.4.5 Slider2D
- 4.5 Camera:摄像机
1. 前言
- 在Sceneview(场景视图中)自定义3D GUI 控制器与绘制的类
- Handles是Unity在场景视图中,用于操控物体的3D控制器,已内置许多操作GUI,比如我们熟悉的基于Transform对位置、缩放、旋转坐标的操作工具。当然,我们使用自定义的Editor,定义自己的Handle GUI操作显示也是可能的。这种GUIs将会非常有用于程序化生成的场景内容、“不可见”的子对象与组。比如路径点与坐标标记点。
2 参数总览
静态函数 | 描述 |
---|---|
ArrowHandleCap | 绘制一个类似于移动工具所用箭头的箭头。 |
BeginGUI | 在 3D 手柄 GUI 内开始一个 2D GUI 块。 |
Button | 创建一个 3D 按钮。 |
CircleHandleCap | 绘制一个圆形手柄。将此手柄传递给 handle 函数。 |
ClearCamera | 清除摄像机。 |
ConeHandleCap | 绘制一个锥体手柄。将此手柄传递给 handle 函数。 |
CubeHandleCap | 绘制一个立方体手柄。将此手柄传递给 handle 函数。 |
CylinderHandleCap | 绘制一个圆柱体手柄。将此手柄传递给 handle 函数。 |
Disc | 创建一个可使用鼠标拖动的 3D 圆盘。 |
DotHandleCap | 绘制一个圆点手柄。将此手柄传递给 handle 函数。 |
DrawAAConvexPolygon | 绘制使用点数组指定的抗锯齿凸多边形。 |
DrawAAPolyLine | 绘制使用点数组和宽度指定的抗锯齿线。 |
DrawBezier | 绘制通过给定切线的起点和终点的纹理化贝塞尔曲线。 |
DrawCamera | 在矩形内绘制一个摄像机。 |
DrawDottedLine | 绘制一条从 p1 到 p2 的虚线。 |
DrawDottedLines | 从 p1 到 p2 绘制一条线。 |
DrawGizmos | 在给定相机的后处理之前或之后绘制 GizmoSubset。 |
DrawLine | 绘制一系列虚线段。 |
DrawLines | 绘制一系列线段。 |
DrawOutline | 在场景视图中围绕指定游戏对象绘制轮廓。 |
DrawPolyLine | 绘制一条穿过 points 列表的线。 |
DrawSelectionFrame | 在指定位置和旋转处创建一个具有指定大小的正方形。 |
DrawSolidArc | 在 3D 空间中绘制一个圆扇形(饼图)。 |
DrawSolidDisc | 在 3D 空间中绘制一个实心平面圆盘。 |
DrawSolidRectangleWithOutline | 在 3D 空间中绘制一个实心轮廓矩形。 |
DrawTexture3DSDF | 在 3D 空间中使用有符号距离场渲染模式绘制 3D 纹理。 |
DrawTexture3DSlice | 在 3D 空间中使用切片渲染模式绘制 3D 纹理。 |
DrawTexture3DVolume | 在 3D 空间中使用体积渲染模式绘制 3D 纹理。 |
DrawWireArc | 在 3D 空间中绘制圆弧。 |
DrawWireCube | 使用 center 和 size 绘制一个线框盒体。 |
DrawWireDisc | 在 3D 空间中绘制扁平圆盘的轮廓。 |
EndGUI | 结束一个 2D GUI 块并返回到 3D 手柄 GUI。 |
FreeMoveHandle | 创建一个不受约束的移动手柄。 |
FreeRotateHandle | 创建一个不受约束的旋转手柄。 |
GetMainGameViewSize | 获取主游戏视图的宽度和高度。 |
Label | 为位于 3D 空间中的手柄创建文本标签。 |
MakeBezierPoints | 返回表示贝塞尔曲线的点数组。 |
PositionHandle | 创建一个位置手柄。 |
RadiusHandle | 创建一个场景视图半径手柄。 |
RectangleHandleCap | 绘制一个矩形手柄。将此手柄传递给 handle 函数。 |
RotationHandle | 创建一个场景视图旋转手柄。 |
ScaleHandle | 创建一个场景视图缩放手柄。 |
ScaleSlider | 创建一个定向缩放滑动条。 |
ScaleValueHandle | 创建一个缩放单个浮点的 3D 手柄。 |
SetCamera | 设置当前摄像机,以便所有手柄和辅助图标均使用相应设置进行绘制。 |
ShouldRenderGizmos | 确定是否绘制 Gizmos。 |
Slider | 创建一个沿着一个轴移动的 3D 滑动条。 |
Slider2D | 创建一个沿两个轴定义的平面移动的 3D 滑动条。 |
SnapToGrid | 将每个 Transform.position 或 Vector3 舍入为 EditorSnapSettings.gridSize 的最接近倍数。 |
SnapValue | 如果对齐为 active,则将 value 四舍五入到 snap 的最接近倍数。注意,snap 只能为正数。 |
SphereHandleCap | 绘制一个球体手柄。将此手柄传递给 handle 函数。 |
TransformHandle | 创建变换手柄。 |
3 Handles两种使用方式
3.1 基于Editor类的OnSceneGUI
- 在继承自Editor的类中,可以定义【OnSceneGUI()】
- 这样当此Edtior在活跃状态时(比如一个Inspector面板展开),在【OnSceneGUI()】方法内的内容将根据SceneView的刷新而调用,触发对应逻辑。
using UnityEngine;public class HandlesScript : MonoBehaviour
{}
using UnityEditor;
using UnityEngine;[CustomEditor(typeof(HandlesScript))]
public class HandlesEditor : Editor
{private void OnSceneGUI(){Debug.Log("在Editor OnSceneGUI中 调用....");}
}
- 在【Hierarchy】中新建空对象,挂载脚本,点击对象在【Inspector】中显示【HandlesScript】信息,就可以看见信息打印:
注:下文实例代码都是在OnSceneGUI中编写调用。
3.2 基于EditorWindow
- 有些时候,我们更想在一个Window中进行数据编辑与操作,但是EditorWindow可没有OnSceneGUI,怎么办呢?这时候,需要手动对SceneView的刷新事件进行注册了。
using UnityEngine;
using UnityEditor;
public class HandlesWindow : EditorWindow
{public static HandlesWindow m_mainWindow;[MenuItem("MyWindows/HandlesWindow")]public static void OpenWindow() //打开窗口{m_mainWindow = EditorWindow.GetWindow<HandlesWindow>();m_mainWindow.Show();}private void OnEnable() {SceneView.duringSceneGui += OnSceneGUI; //对SceneView的刷新事件进行注册}private void OnDisable() {SceneView.duringSceneGui -= OnSceneGUI; //对SceneView的刷新事件取消注册}private void OnSceneGUI(SceneView sceneView) //自定义刷新事件的委托方法{Debug.Log("在 Window OnSceneGUI中 调用...."); //具体逻辑}
}
4 Handles绘制
4.1 Draw:绘制元几何体(点、线、面)
4.1.1 抗锯齿: DrawAAPolyLine 、 DrawAAConvexPolygon
- DrawAAPolyLine: 绘制使用点数组和宽度指定的抗锯齿线。
- 注意:如果您希望拥有恒定屏幕大小的手柄,请使用 HandleUtility.GetHandleSize。
- 注意:要获得抗锯齿效果,请使用 1x2 像素(一个透明的白色像素和一个不透明的白色像素)的纹理。
- DrawAAConvexPolygon: 绘制使用点数组指定的抗锯齿凸多边形。
DrawAAPolyLine
using UnityEditor;
using UnityEngine;[CustomEditor(typeof(HandlesScript))]
public class HandlesEditor : Editor
{private void OnSceneGUI(){Handles.DrawAAPolyLine(new Vector3[] { Vector3.zero, Vector3.one, new Vector3(2, 0, 2) });}
}
DrawAAConvexPolygon
using UnityEditor;
using UnityEngine;[CustomEditor(typeof(HandlesScript))]
[CanEditMultipleObjects]
public class HandlesEditor : Editor
{private void OnSceneGUI(){Handles.DrawAAConvexPolygon(new Vector3[] { Vector3.zero, Vector3.one, new Vector3(2, 0, 2) });}
}
4.1.2 绘制实线: DrawLine 、 DrawLines 、DrawPolyLine
- DrawLine:从 p1 到 p2 绘制一条线。
- DrawLines:绘制一系列线段。
- DrawPolyLine:绘制一条穿过 points 列表的线。
DrawLine
using UnityEditor;
using UnityEngine;[CustomEditor(typeof(HandlesScript))]
public class HandlesEditor : Editor
{private void OnSceneGUI(){Handles.DrawLine(Vector3.zero, Vector3.one);}
}
DrawLines
using UnityEditor;
using UnityEngine;[CustomEditor(typeof(HandlesScript))]
public class HandlesEditor : Editor
{Vector3[] lineSegments = new Vector3[4]{//线段一Vector3.zero, Vector3.one,//线段二Vector3.one, new Vector3(2,0,2)};private void OnSceneGUI(){ Handles.DrawLines(lineSegments);}
}
DrawPolyLine
using UnityEditor;
using UnityEngine;[CustomEditor(typeof(HandlesScript))]
public class HandlesEditor : Editor
{Vector3[] positions = new Vector3[4]{Vector3.zero, Vector3.one, new Vector3(2,0,2), Vector3.zero};private void OnSceneGUI(){Handles.DrawPolyLine(positions);}
}
4.1.3 绘制虚线: DrawDottedLine 、 DrawDottedLines
- DrawDottedLine:绘制一条从 p1 到 p2 的虚线。
- DrawDottedLines:绘制一系列虚线段。
DrawDottedLine
using UnityEditor;
using UnityEngine;[CustomEditor(typeof(HandlesScript))]
public class HandlesEditor : Editor
{//线段长度及其间距的大小(以像素为单位)。float screenSpaceSize = 4.0f;private void OnSceneGUI(){Handles.DrawDottedLine(Vector3.zero, Vector3.one, screenSpaceSize);}
}
DrawDottedLines
using UnityEditor;
using UnityEngine;[CustomEditor(typeof(HandlesScript))]
public class HandlesEditor : Editor
{Vector3[] lineSegments = new Vector3[4]{//线段一Vector3.zero, Vector3.one,//线段二Vector3.one, new Vector3(2,0,2)};//线段长度及其间距的大小(以像素为单位)。float screenSpaceSize = 4.0f;private void OnSceneGUI(){Handles.DrawDottedLines(lineSegments, screenSpaceSize);}
}
4.1.4 绘制贝塞尔曲线: DrawBezier
- DrawBezier:绘制通过给定切线的起点和终点的纹理化贝塞尔曲线。
using UnityEditor;
using UnityEngine;[CustomEditor(typeof(HandlesScript))]
public class HandlesEditor : Editor
{public Vector3 startPoint = new Vector3(-0.0f, 0.0f, 0.0f);//贝塞尔曲线的起点。public Vector3 endPoint = new Vector3(-2.0f, 1.0f, 0.0f);//贝塞尔曲线的终点。public Vector3 startTangent = new Vector3(-2.0f, 2.0f, 0.0f);//贝塞尔曲线的起始切线。public Vector3 endTangent = Vector3.zero;//贝塞尔曲线的终点切线。private void OnSceneGUI(){Handles.DrawBezier(startPoint, endPoint, startTangent, endTangent, Color.red, null, 2f);}
}
4.1.5 绘制圆形圆盘: DrawSolidDisc 、 DrawSolidArc 、 DrawSolidRectangleWithOutline
- DrawSolidDisc:在 3D 空间中绘制一个实心平面圆盘。
- DrawSolidArc:在 3D 空间中绘制一个圆扇形(饼图)。
- **DrawSolidRectangleWithOutline **:在 3D 空间中绘制一个实心轮廓矩形。
DrawSolidDisc
using UnityEditor;
using UnityEngine;[CustomEditor(typeof(HandlesScript))]
public class HandlesEditor : Editor
{//圆盘的中心。Vector3 center = Vector3.zero;//圆盘的法线。Vector3 normal = Vector3.up;//该圆盘的半径。float radius = 1.0f;private void OnSceneGUI(){Handles.DrawSolidDisc(center, normal, radius);}
}
DrawSolidArc
using UnityEditor;
using UnityEngine;[CustomEditor(typeof(HandlesScript))]
public class HandlesEditor : Editor
{//圆盘的中心。Vector3 center = Vector3.zero;//圆盘的法线。Vector3 normal = Vector3.up;//圆周上的点相对于圆心的方向,即扇形的起点。Vector3 from = Vector3.left;//扇形的角度(以度为单位)。float angle = 180;//该圆盘的半径。float radius = 1.0f;private void OnSceneGUI(){Handles.DrawSolidArc(center, normal, from, angle, radius);}
}
DrawSolidRectangleWithOutline
using UnityEditor;
using UnityEngine;[CustomEditor(typeof(HandlesScript))]
public class HandlesEditor : Editor
{private void OnSceneGUI(){HandlesScript t = target as HandlesScript;Vector3 pos = t.transform.position;Vector3[] verts = new Vector3[]{new Vector3(pos.x -2, pos.y, pos.z -2),new Vector3(pos.x -2, pos.y, pos.z + 2),new Vector3(pos.x + 2, pos.y, pos.z + 2),new Vector3(pos.x +2, pos.y, pos.z -2)};Handles.DrawSolidRectangleWithOutline(verts, new Color(0.5f, 0.5f, 0.5f, 0.1f), new Color(0, 0, 0, 1));}
}
4.1.6 绘制圆弧: DrawWireDisc 、 DrawWireArc 、 DrawWireCube
- DrawWireDisc:在 3D 空间中绘制扁平圆盘的轮廓。
- DrawWireArc:在 3D 空间中绘制圆弧。
- DrawWireCube:使用 center 和 size 绘制一个线框盒体。
DrawWireDisc
using UnityEditor;
using UnityEngine;[CustomEditor(typeof(HandlesScript))]
public class HandlesEditor : Editor
{//圆盘的中心。Vector3 center = Vector3.zero;//圆盘的法线。Vector3 normal = Vector3.up;//条粗细(零粗细绘制单像素线条)。float thickness = 3;//该圆盘的半径。float radius = 1.0f;private void OnSceneGUI(){Handles.color = Color.red;Handles.DrawWireDisc(center, normal, radius, thickness);}
}
DrawWireArc
using UnityEditor;
using UnityEngine;[CustomEditor(typeof(HandlesScript))]
public class HandlesEditor : Editor
{//圆盘的中心。Vector3 center = Vector3.zero;//圆盘的法线。Vector3 normal = Vector3.up;//圆周上的点相对于圆心的方向,即圆弧的起点。Vector3 from = Vector3.left;//条粗细(零粗细绘制单像素线条)。float thickness = 3;//圆的半径。float angle = 180;//该圆盘的半径。float radius = 1.0f;private void OnSceneGUI(){Handles.color = Color.red;Handles.DrawWireArc(center, normal, from, angle, radius, thickness);}
}
DrawWireCube
using UnityEditor;
using UnityEngine;[CustomEditor(typeof(HandlesScript))]
public class HandlesEditor : Editor
{Vector3 center = Vector3.zero;Vector3 size = Vector3.one;private void OnSceneGUI(){Handles.color = Color.red;Handles.DrawWireCube(center, size);}
}
4.1.7 绘制 3D 纹理: DrawTexture3DVolume 、 DrawTexture3DSlice 、 DrawTexture3DSDF
- DrawTexture3DVolume:在 3D 空间中使用体积渲染模式绘制 3D 纹理。
- DrawTexture3DSlice:在 3D 空间中使用切片渲染模式绘制 3D 纹理。
- DrawTexture3DSDF:在 3D 空间中使用有符号距离场渲染模式绘制 3D 纹理。
DrawTexture3DVolume
using UnityEditor;
using UnityEngine;[CustomEditor(typeof(HandlesScript))]
[CanEditMultipleObjects]
public class HandlesEditor : Editor
{//要绘制的体积纹理。public Texture texture;//非线性体积不透明度修改器。使用它来控制可视化的不透明度。有效值为 0-1(含)。//值为 1 时完全不透明,值为 0 时完全透明。默认值为 1。float opacity = 0;//设置每个纹理像素计数的样本。值越高,渲染质量越高。默认值为 1。float qualityModifier = 0;//设置要使用的纹理过滤模式。FilterMode filterMode = FilterMode.Trilinear;//启用颜色渐变可视化。bool useColorRamp = true;//Unity 用作颜色渐变的自定义渐变。如果未指定,Unity 将使用 Google Turbo 色带。Gradient customColorRamp;private void OnSceneViewGUI(SceneView sv){Handles.DrawTexture3DVolume(texture, opacity, qualityModifier, filterMode,useColorRamp, useColorRamp ? customColorRamp : null);}
}
DrawTexture3DSlice
using UnityEditor;
using UnityEngine;[CustomEditor(typeof(HandlesScript))]
[CanEditMultipleObjects]
public class HandlesEditor : Editor
{//要绘制的体积纹理。public Texture texture;//纹理采样平面的位置。public Vector3 slicePositions;//设置要使用的纹理过滤模式。FilterMode filterMode = FilterMode.Trilinear;//启用颜色渐变可视化。bool useColorRamp = true;//Unity 用作颜色渐变的自定义渐变。如果未指定,Unity 将使用 Google Turbo 色带。Gradient customColorRamp;private void OnSceneViewGUI(SceneView sv){Handles.DrawTexture3DSlice(texture, slicePositions, filterMode,useColorRamp, useColorRamp ? customColorRamp : null);}
}
DrawTexture3DSDF
using UnityEditor;
using UnityEngine;[CustomEditor(typeof(HandlesScript))]
[CanEditMultipleObjects]
public class HandlesEditor : Editor
{//要绘制的体积纹理。public Texture texture;//与光线步长相乘的数字。光线步长是两个相邻像素之间的距离。默认值为 1。float stepScale;//渲染表面时的像素强度。当该值为正数时,Unity 将扩展渲染表面。//当该值为负数时,Unity 会将空的空间渲染为表面,并将表面渲染为空的空间。默认值为 0。float surfaceOffset;//Unity 用作颜色渐变的自定义渐变。如果未指定,Unity 将使用 Google Turbo 色带。Gradient customColorRamp;private void OnSceneViewGUI(SceneView sv){Handles.DrawTexture3DSDF(texture, stepScale, surfaceOffset, customColorRamp);}
}
4.2 Handle:可视化操作数值(Vector3、Vector2、float等)
4.2.1 FreeMoveHandle
- FreeMoveHandle: 创建一个不受约束的移动手柄。
protected virtual void OnSceneGUI(){HandlesScript example = (HandlesScript)target;float size = HandleUtility.GetHandleSize(example.targetPosition) * 0.5f;Vector3 snap = Vector3.one * 0.5f;EditorGUI.BeginChangeCheck();Vector3 newTargetPosition = Handles.FreeMoveHandle(example.targetPosition, Quaternion.identity, size, snap, Handles.RectangleHandleCap);if (EditorGUI.EndChangeCheck()){Undo.RecordObject(example, "Change Look At Target Position");example.targetPosition = newTargetPosition;example.Update();}}
using UnityEngine;public class HandlesScript : MonoBehaviour
{public Vector3 targetPosition { get { return m_TargetPosition; } set { m_TargetPosition = value; } }[SerializeField]private Vector3 m_TargetPosition = new Vector3(1f, 0f, 2f);public virtual void Update(){transform.LookAt(m_TargetPosition);}
}
4.2.2 FreeRotateHandle
- FreeRotateHandle: 创建一个不受约束的旋转手柄。
public void OnSceneGUI(){HandlesScript t = (target as HandlesScript);EditorGUI.BeginChangeCheck();Quaternion rot = Handles.FreeRotateHandle(0, t.rot, Vector3.zero, 2);if (EditorGUI.EndChangeCheck()){Undo.RecordObject(target, "Free Rotate");t.rot = rot;t.Update();}}
using UnityEngine;public class HandlesScript : MonoBehaviour
{public Quaternion rot = Quaternion.identity;public void Update(){transform.rotation = rot;}
}
4.2.3 PositionHandle
- PositionHandle: 创建一个位置手柄。
protected virtual void OnSceneGUI(){HandlesScript example = (HandlesScript)target;EditorGUI.BeginChangeCheck();Vector3 newTargetPosition = Handles.PositionHandle(example.targetPosition, Quaternion.identity);if (EditorGUI.EndChangeCheck()){Undo.RecordObject(example, "Change Look At Target Position");example.targetPosition = newTargetPosition;example.Update();}}
using UnityEngine;public class HandlesScript : MonoBehaviour
{public Vector3 targetPosition { get { return m_TargetPosition; } set { m_TargetPosition = value; } }[SerializeField]private Vector3 m_TargetPosition = new Vector3(1f, 0f, 2f);public virtual void Update(){transform.LookAt(m_TargetPosition);}
}
4.2.4 RadiusHandle
- RadiusHandle: 创建一个场景视图半径手柄。
using UnityEngine;public class HandlesScript : MonoBehaviour
{public float areaOfEffect = 1;
}
public void OnSceneGUI()
{HandlesScript t = (target as HandlesScript);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;}
}
4.2.5 RotationHandle
- RotationHandle: 创建一个场景视图旋转手柄。
using UnityEngine;public class HandlesScript : MonoBehaviour
{public Quaternion rot = Quaternion.identity;public void Update(){transform.rotation = rot;}
}
public void OnSceneGUI(){HandlesScript t = (target as HandlesScript );EditorGUI.BeginChangeCheck();Quaternion rot = Handles.RotationHandle(t.rot, Vector3.zero);if (EditorGUI.EndChangeCheck()){Undo.RecordObject(target, "Rotated RotateAt Point");t.rot = rot;t.Update();}}
4.2.6 ScaleHandle
- ScaleHandle:创建一个场景视图缩放手柄。
using UnityEngine;public class HandlesScript : MonoBehaviour
{public Vector3 scale = Vector3.one;public void Update(){transform.localScale = scale;}
}
public void OnSceneGUI(){HandlesScript t = (target as HandlesScript );EditorGUI.BeginChangeCheck();Vector3 scale = Handles.ScaleHandle(t.scale, Vector3.zero, Quaternion.identity, 1);if (EditorGUI.EndChangeCheck()){Undo.RecordObject(target, "Scaled ScaleAt Point");t.scale = scale;t.Update();}}
4.2.7 ScaleValueHandle
- ScaleValueHandle:创建一个缩放单个浮点的 3D 手柄。
using UnityEngine;public class HandlesScript : MonoBehaviour
{[SerializeField]private Color m_Color1 = Color.red;[SerializeField]private Color m_Color2 = Color.green;public float amount { get { return m_Amount; } set { m_Amount = Mathf.Clamp01(value); } }[SerializeField, Range(0f, 1f)]private float m_Amount = 1f;private Light m_Light;protected virtual void OnEnable(){m_Light = GetComponent<Light>();}public virtual void Update(){m_Light.color = Color.Lerp(m_Color1, m_Color2, m_Amount);}
}
protected virtual void OnSceneGUI(){LightColorLerp colorLerp = (LightColorLerp)target;float size = HandleUtility.GetHandleSize(colorLerp.transform.position) * 5f;float snap = 0.1f;EditorGUI.BeginChangeCheck();float newAmount = Handles.ScaleValueHandle(colorLerp.amount, colorLerp.transform.position, Quaternion.identity, size, Handles.ArrowHandleCap, snap);if (EditorGUI.EndChangeCheck()){Undo.RecordObject(colorLerp, "Change Light Color Interpolation");colorLerp.amount = newAmount;colorLerp.Update();}}
4.3 Caps:绘制多边形几何体(如方块,点精灵,球形,圆锥等)
4.3.1 ArrowHandleCap
- ArrowHandleCap:绘制一个类似于移动工具所用箭头的箭头。
using System.Drawing.Drawing2D;
using UnityEditor;
using UnityEngine;[CustomEditor(typeof(HandlesScript))]
[CanEditMultipleObjects]
public class HandlesEditor : Editor
{float size = 1f;protected virtual void OnSceneGUI(){if (Event.current.type == EventType.Repaint){Transform transform = ((HandlesScript)target).transform;Handles.color = Handles.yAxisColor;Handles.ArrowHandleCap(0,transform.position + new Vector3(3f, 0f, 0f),transform.rotation * Quaternion.LookRotation(Vector3.right),size,EventType.Repaint);Handles.color = Handles.yAxisColor;Handles.ArrowHandleCap(0,transform.position + new Vector3(0f, 3f, 0f),transform.rotation * Quaternion.LookRotation(Vector3.up),size,EventType.Repaint);Handles.color = Handles.yAxisColor;Handles.ArrowHandleCap(0,transform.position + new Vector3(0f, 0f, 3f),transform.rotation * Quaternion.LookRotation(Vector3.forward),size,EventType.Repaint);}}
}
4.3.2 CircleHandleCap
- CircleHandleCap:绘制一个圆形手柄。将此手柄传递给 handle 函数。
using System.Drawing.Drawing2D;
using UnityEditor;
using UnityEngine;[CustomEditor(typeof(HandlesScript))]
[CanEditMultipleObjects]
public class HandlesEditor : Editor
{float size = 1f;protected virtual void OnSceneGUI(){if (Event.current.type == EventType.Repaint){Transform transform = ((HandlesScript)target).transform;Handles.color = Handles.xAxisColor;Handles.CircleHandleCap(0,transform.position + new Vector3(3f, 0f, 0f),transform.rotation * Quaternion.LookRotation(Vector3.right),size,EventType.Repaint);Handles.color = Handles.yAxisColor;Handles.CircleHandleCap(0,transform.position + new Vector3(0f, 3f, 0f),transform.rotation * Quaternion.LookRotation(Vector3.up),size,EventType.Repaint);Handles.color = Handles.zAxisColor;Handles.CircleHandleCap(0,transform.position + new Vector3(0f, 0f, 3f),transform.rotation * Quaternion.LookRotation(Vector3.forward),size,EventType.Repaint);}}
}
4.3.3 ConeHandleCap
- ConeHandleCap:绘制一个锥体手柄。将此手柄传递给 handle 函数。
using UnityEditor;
using UnityEngine;[CustomEditor(typeof(HandlesScript))]
[CanEditMultipleObjects]
public class HandlesEditor : Editor
{float size = 1f;protected virtual void OnSceneGUI(){if (Event.current.type == EventType.Repaint){Transform transform = ((HandlesScript)target).transform;Handles.color = Handles.xAxisColor;Handles.ConeHandleCap(0,transform.position + new Vector3(3f, 0f, 0f),transform.rotation * Quaternion.LookRotation(Vector3.right),size,EventType.Repaint);Handles.color = Handles.yAxisColor;Handles.ConeHandleCap(0,transform.position + new Vector3(0f, 3f, 0f),transform.rotation * Quaternion.LookRotation(Vector3.up),size,EventType.Repaint);Handles.color = Handles.zAxisColor;Handles.ConeHandleCap(0,transform.position + new Vector3(0f, 0f, 3f),transform.rotation * Quaternion.LookRotation(Vector3.forward),size,EventType.Repaint);}}
}
4.3.4 CubeHandleCap
- CubeHandleCap:绘制一个立方体手柄。将此手柄传递给 handle 函数。
using UnityEditor;
using UnityEngine;[CustomEditor(typeof(HandlesScript))]
[CanEditMultipleObjects]
public class HandlesEditor : Editor
{float size = 1f;protected virtual void OnSceneGUI(){if (Event.current.type == EventType.Repaint){Transform transform = ((HandlesScript)target).transform;Handles.color = Handles.xAxisColor;Handles.CubeHandleCap(0,transform.position + new Vector3(3f, 0f, 0f),transform.rotation * Quaternion.LookRotation(Vector3.right),size,EventType.Repaint);Handles.color = Handles.yAxisColor;Handles.CubeHandleCap(0,transform.position + new Vector3(0f, 3f, 0f),transform.rotation * Quaternion.LookRotation(Vector3.up),size,EventType.Repaint);Handles.color = Handles.zAxisColor;Handles.CubeHandleCap(0,transform.position + new Vector3(0f, 0f, 3f),transform.rotation * Quaternion.LookRotation(Vector3.forward),size,EventType.Repaint);}}
}
4.3.5 CylinderHandleCap
- CylinderHandleCap:绘制一个圆柱体手柄。将此手柄传递给 handle 函数。
using UnityEditor;
using UnityEngine;[CustomEditor(typeof(HandlesScript))]
[CanEditMultipleObjects]
public class HandlesEditor : Editor
{float size = 1f;protected virtual void OnSceneGUI(){if (Event.current.type == EventType.Repaint){Transform transform = ((HandlesScript)target).transform;Handles.color = Handles.xAxisColor;Handles.CylinderHandleCap(0,transform.position + new Vector3(3f, 0f, 0f),transform.rotation * Quaternion.LookRotation(Vector3.right),size,EventType.Repaint);Handles.color = Handles.yAxisColor;Handles.CylinderHandleCap(0,transform.position + new Vector3(0f, 3f, 0f),transform.rotation * Quaternion.LookRotation(Vector3.up),size,EventType.Repaint);Handles.color = Handles.zAxisColor;Handles.CylinderHandleCap(0,transform.position + new Vector3(0f, 0f, 3f),transform.rotation * Quaternion.LookRotation(Vector3.forward),size,EventType.Repaint);}}
}
4.3.6 DotHandleCap
- DotHandleCap:绘制一个圆点手柄。将此手柄传递给 handle 函数。
using UnityEditor;
using UnityEngine;[CustomEditor(typeof(HandlesScript))]
public class HandlesEditor : Editor
{float size = 1f;protected virtual void OnSceneGUI(){if (Event.current.type == EventType.Repaint){Transform transform = ((HandlesScript)target).transform;Handles.color = Handles.xAxisColor;Handles.DotHandleCap(0,transform.position + new Vector3(3f, 0f, 0f),transform.rotation * Quaternion.LookRotation(Vector3.right),size,EventType.Repaint);Handles.color = Handles.yAxisColor;Handles.DotHandleCap(0,transform.position + new Vector3(0f, 3f, 0f),transform.rotation * Quaternion.LookRotation(Vector3.up),size,EventType.Repaint);Handles.color = Handles.zAxisColor;Handles.DotHandleCap(0,transform.position + new Vector3(0f, 0f, 3f),transform.rotation * Quaternion.LookRotation(Vector3.forward),size,EventType.Repaint);}}
}
4.3.7 RectangleHandleCap
- RectangleHandleCap:绘制一个矩形手柄。将此手柄传递给 handle 函数。
using UnityEditor;
using UnityEngine;[CustomEditor(typeof(HandlesScript))]
public class HandlesEditor : Editor
{float size = 1f;protected virtual void OnSceneGUI(){if (Event.current.type == EventType.Repaint){Transform transform = ((HandlesScript)target).transform;Handles.color = Handles.xAxisColor;Handles.RectangleHandleCap(0,transform.position + new Vector3(3f, 0f, 0f),transform.rotation * Quaternion.LookRotation(Vector3.right),size,EventType.Repaint);Handles.color = Handles.yAxisColor;Handles.RectangleHandleCap(0,transform.position + new Vector3(0f, 3f, 0f),transform.rotation * Quaternion.LookRotation(Vector3.up),size,EventType.Repaint);Handles.color = Handles.zAxisColor;Handles.RectangleHandleCap(0,transform.position + new Vector3(0f, 0f, 3f),transform.rotation * Quaternion.LookRotation(Vector3.forward),size,EventType.Repaint);}}
}
4.4 GUI
4.4.1 Label
- Label:为位于 3D 空间中的手柄创建文本标签。
using UnityEditor;
using UnityEngine;[CustomEditor(typeof(HandlesScript))]
public class HandlesEditor : Editor
{protected virtual void OnSceneGUI(){Handles.color = Color.red;Handles.Label(Vector3.zero,"测试Label");}
}
4.4.2 Button
- Button:创建一个 3D 按钮。
using UnityEditor;
using UnityEngine;[CustomEditor(typeof(HandlesScript))]
public class HandlesEditor : Editor
{protected virtual void OnSceneGUI(){if (Handles.Button(Vector3.zero, Quaternion.identity, 1, 2, Handles.RectangleHandleCap))Debug.Log("The button was pressed!");}
}
4.4.3 ScaleSlider
- ScaleSlider:创建一个定向缩放滑动条。
using UnityEditor;
using UnityEngine;[CustomEditor(typeof(HandlesScript))]
public class HandlesEditor : Editor
{protected virtual void OnSceneGUI(){float scale = Handles.ScaleSlider(1, Vector3.zero, Vector3.right, Quaternion.identity, 1, 0.5f);}
}
4.4.4 Slider
- Slider:创建一个沿着一个轴移动的 3D 滑动条。
using UnityEditor;
using UnityEngine;[CustomEditor(typeof(HandlesScript))]
public class HandlesEditor : Editor
{protected virtual void OnSceneGUI(){Vector3 newTargetPosition = Handles.Slider(Vector3.zero, Vector3.right, 1, Handles.ConeHandleCap, 0.5f);}
}
4.4.5 Slider2D
- Slider2D:创建一个沿两个轴定义的平面移动的 3D 滑动条。
using UnityEditor;
using UnityEngine;[CustomEditor(typeof(HandlesScript))]
public class HandlesEditor : Editor
{protected virtual void OnSceneGUI(){Vector3 newTargetPosition = Handles.Slider2D(Vector3.zero, Vector3.up, Vector3.right, Vector3.forward, 1, Handles.CircleHandleCap, 0.5f);}
}
4.5 Camera:摄像机
- DrawCamera:在矩形内绘制一个摄像机。此函数还将 Camera.current 设置为 camera。它将摄像机的 pixelRect 设置为 position,但采用屏幕坐标。如果您使用高 DPI 显示屏,这可能会与 GUI 坐标有所不同。
- ClearCamera:清除摄像机。Handle 类使用的摄像机将在使用前被清除
- SnapValue:如果对齐为 active,则将 value 四舍五入到 snap 的最接近倍数。注意,snap 只能为正数。