目录
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的刷新而调用,触发对应逻辑。
usingUnityEngine;publicclassHandlesScript:MonoBehaviour{}
usingUnityEditor;usingUnityEngine;[CustomEditor(typeof(HandlesScript))]publicclassHandlesEditor:Editor{privatevoidOnSceneGUI(){
Debug.Log("在Editor OnSceneGUI中 调用....");}}
- 在【Hierarchy】中新建空对象,挂载脚本,点击对象在【Inspector】中显示【HandlesScript】信息,就可以看见信息打印:注:下文实例代码都是在OnSceneGUI中编写调用。
3.2 基于EditorWindow
- 有些时候,我们更想在一个Window中进行数据编辑与操作,但是EditorWindow可没有OnSceneGUI,怎么办呢?这时候,需要手动对SceneView的刷新事件进行注册了。
usingUnityEngine;usingUnityEditor;publicclassHandlesWindow:EditorWindow{publicstaticHandlesWindow m_mainWindow;[MenuItem("MyWindows/HandlesWindow")]publicstaticvoidOpenWindow()//打开窗口{
m_mainWindow = EditorWindow.GetWindow<HandlesWindow>();
m_mainWindow.Show();}privatevoidOnEnable(){
SceneView.duringSceneGui += OnSceneGUI;//对SceneView的刷新事件进行注册}privatevoidOnDisable(){
SceneView.duringSceneGui -= OnSceneGUI;//对SceneView的刷新事件取消注册}privatevoidOnSceneGUI(SceneView sceneView)//自定义刷新事件的委托方法{
Debug.Log("在 Window OnSceneGUI中 调用....");//具体逻辑}}
4 Handles绘制
4.1 Draw:绘制元几何体(点、线、面)
4.1.1 抗锯齿: DrawAAPolyLine 、 DrawAAConvexPolygon
- DrawAAPolyLine: 绘制使用点数组和宽度指定的抗锯齿线。 - 注意:如果您希望拥有恒定屏幕大小的手柄,请使用 HandleUtility.GetHandleSize。- 注意:要获得抗锯齿效果,请使用 1x2 像素(一个透明的白色像素和一个不透明的白色像素)的纹理。
- DrawAAConvexPolygon: 绘制使用点数组指定的抗锯齿凸多边形。
DrawAAPolyLine
usingUnityEditor;usingUnityEngine;[CustomEditor(typeof(HandlesScript))]publicclassHandlesEditor:Editor{privatevoidOnSceneGUI(){
Handles.DrawAAPolyLine(newVector3[]{ Vector3.zero, Vector3.one,newVector3(2,0,2)});}}
DrawAAConvexPolygon
usingUnityEditor;usingUnityEngine;[CustomEditor(typeof(HandlesScript))][CanEditMultipleObjects]publicclassHandlesEditor:Editor{privatevoidOnSceneGUI(){
Handles.DrawAAConvexPolygon(newVector3[]{ Vector3.zero, Vector3.one,newVector3(2,0,2)});}}
4.1.2 绘制实线: DrawLine 、 DrawLines 、DrawPolyLine
- DrawLine:从 p1 到 p2 绘制一条线。
- DrawLines:绘制一系列线段。
- DrawPolyLine:绘制一条穿过 points 列表的线。
DrawLine
usingUnityEditor;usingUnityEngine;[CustomEditor(typeof(HandlesScript))]publicclassHandlesEditor:Editor{privatevoidOnSceneGUI(){
Handles.DrawLine(Vector3.zero, Vector3.one);}}
DrawLines
usingUnityEditor;usingUnityEngine;[CustomEditor(typeof(HandlesScript))]publicclassHandlesEditor:Editor{Vector3[] lineSegments =newVector3[4]{//线段一
Vector3.zero, Vector3.one,//线段二
Vector3.one,newVector3(2,0,2)};privatevoidOnSceneGUI(){
Handles.DrawLines(lineSegments);}}
DrawPolyLine
usingUnityEditor;usingUnityEngine;[CustomEditor(typeof(HandlesScript))]publicclassHandlesEditor:Editor{Vector3[] positions =newVector3[4]{
Vector3.zero, Vector3.one,newVector3(2,0,2), Vector3.zero
};privatevoidOnSceneGUI(){
Handles.DrawPolyLine(positions);}}
4.1.3 绘制虚线: DrawDottedLine 、 DrawDottedLines
- DrawDottedLine:绘制一条从 p1 到 p2 的虚线。
- DrawDottedLines:绘制一系列虚线段。
DrawDottedLine
usingUnityEditor;usingUnityEngine;[CustomEditor(typeof(HandlesScript))]publicclassHandlesEditor:Editor{//线段长度及其间距的大小(以像素为单位)。float screenSpaceSize =4.0f;privatevoidOnSceneGUI(){
Handles.DrawDottedLine(Vector3.zero, Vector3.one, screenSpaceSize);}}
DrawDottedLines
usingUnityEditor;usingUnityEngine;[CustomEditor(typeof(HandlesScript))]publicclassHandlesEditor:Editor{Vector3[] lineSegments =newVector3[4]{//线段一
Vector3.zero, Vector3.one,//线段二
Vector3.one,newVector3(2,0,2)};//线段长度及其间距的大小(以像素为单位)。float screenSpaceSize =4.0f;privatevoidOnSceneGUI(){
Handles.DrawDottedLines(lineSegments, screenSpaceSize);}}
4.1.4 绘制贝塞尔曲线: DrawBezier
- DrawBezier:绘制通过给定切线的起点和终点的纹理化贝塞尔曲线。
usingUnityEditor;usingUnityEngine;[CustomEditor(typeof(HandlesScript))]publicclassHandlesEditor:Editor{publicVector3 startPoint =newVector3(-0.0f,0.0f,0.0f);//贝塞尔曲线的起点。publicVector3 endPoint =newVector3(-2.0f,1.0f,0.0f);//贝塞尔曲线的终点。publicVector3 startTangent =newVector3(-2.0f,2.0f,0.0f);//贝塞尔曲线的起始切线。publicVector3 endTangent = Vector3.zero;//贝塞尔曲线的终点切线。privatevoidOnSceneGUI(){
Handles.DrawBezier(startPoint, endPoint, startTangent, endTangent, Color.red,null,2f);}}
4.1.5 绘制圆形圆盘: DrawSolidDisc 、 DrawSolidArc 、 DrawSolidRectangleWithOutline
- DrawSolidDisc:在 3D 空间中绘制一个实心平面圆盘。
- DrawSolidArc:在 3D 空间中绘制一个圆扇形(饼图)。
- DrawSolidRectangleWithOutline :在 3D 空间中绘制一个实心轮廓矩形。
DrawSolidDisc
usingUnityEditor;usingUnityEngine;[CustomEditor(typeof(HandlesScript))]publicclassHandlesEditor:Editor{//圆盘的中心。Vector3 center = Vector3.zero;//圆盘的法线。Vector3 normal = Vector3.up;//该圆盘的半径。float radius =1.0f;privatevoidOnSceneGUI(){
Handles.DrawSolidDisc(center, normal, radius);}}
DrawSolidArc
usingUnityEditor;usingUnityEngine;[CustomEditor(typeof(HandlesScript))]publicclassHandlesEditor:Editor{//圆盘的中心。Vector3 center = Vector3.zero;//圆盘的法线。Vector3 normal = Vector3.up;//圆周上的点相对于圆心的方向,即扇形的起点。Vector3 from = Vector3.left;//扇形的角度(以度为单位)。float angle =180;//该圆盘的半径。float radius =1.0f;privatevoidOnSceneGUI(){
Handles.DrawSolidArc(center, normal, from, angle, radius);}}
DrawSolidRectangleWithOutline
usingUnityEditor;usingUnityEngine;[CustomEditor(typeof(HandlesScript))]publicclassHandlesEditor:Editor{privatevoidOnSceneGUI(){HandlesScript t = target asHandlesScript;Vector3 pos = t.transform.position;Vector3[] verts =newVector3[]{newVector3(pos.x -2, pos.y, pos.z -2),newVector3(pos.x -2, pos.y, pos.z +2),newVector3(pos.x +2, pos.y, pos.z +2),newVector3(pos.x +2, pos.y, pos.z -2)};
Handles.DrawSolidRectangleWithOutline(verts,newColor(0.5f,0.5f,0.5f,0.1f),newColor(0,0,0,1));}}
4.1.6 绘制圆弧: DrawWireDisc 、 DrawWireArc 、 DrawWireCube
- DrawWireDisc:在 3D 空间中绘制扁平圆盘的轮廓。
- DrawWireArc:在 3D 空间中绘制圆弧。
- DrawWireCube:使用 center 和 size 绘制一个线框盒体。
DrawWireDisc
usingUnityEditor;usingUnityEngine;[CustomEditor(typeof(HandlesScript))]publicclassHandlesEditor:Editor{//圆盘的中心。Vector3 center = Vector3.zero;//圆盘的法线。Vector3 normal = Vector3.up;//条粗细(零粗细绘制单像素线条)。float thickness =3;//该圆盘的半径。float radius =1.0f;privatevoidOnSceneGUI(){
Handles.color = Color.red;
Handles.DrawWireDisc(center, normal, radius, thickness);}}
DrawWireArc
usingUnityEditor;usingUnityEngine;[CustomEditor(typeof(HandlesScript))]publicclassHandlesEditor:Editor{//圆盘的中心。Vector3 center = Vector3.zero;//圆盘的法线。Vector3 normal = Vector3.up;//圆周上的点相对于圆心的方向,即圆弧的起点。Vector3 from = Vector3.left;//条粗细(零粗细绘制单像素线条)。float thickness =3;//圆的半径。float angle =180;//该圆盘的半径。float radius =1.0f;privatevoidOnSceneGUI(){
Handles.color = Color.red;
Handles.DrawWireArc(center, normal, from, angle, radius, thickness);}}
DrawWireCube
usingUnityEditor;usingUnityEngine;[CustomEditor(typeof(HandlesScript))]publicclassHandlesEditor:Editor{Vector3 center = Vector3.zero;Vector3 size = Vector3.one;privatevoidOnSceneGUI(){
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
usingUnityEditor;usingUnityEngine;[CustomEditor(typeof(HandlesScript))][CanEditMultipleObjects]publicclassHandlesEditor:Editor{//要绘制的体积纹理。publicTexture 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;privatevoidOnSceneViewGUI(SceneView sv){
Handles.DrawTexture3DVolume(texture, opacity, qualityModifier, filterMode,
useColorRamp,useColorRamp ? customColorRamp :null);}}
DrawTexture3DSlice
usingUnityEditor;usingUnityEngine;[CustomEditor(typeof(HandlesScript))][CanEditMultipleObjects]publicclassHandlesEditor:Editor{//要绘制的体积纹理。publicTexture texture;//纹理采样平面的位置。publicVector3 slicePositions;//设置要使用的纹理过滤模式。FilterMode filterMode = FilterMode.Trilinear;//启用颜色渐变可视化。bool useColorRamp =true;//Unity 用作颜色渐变的自定义渐变。如果未指定,Unity 将使用 Google Turbo 色带。Gradient customColorRamp;privatevoidOnSceneViewGUI(SceneView sv){
Handles.DrawTexture3DSlice(texture, slicePositions, filterMode,
useColorRamp,useColorRamp ? customColorRamp :null);}}
DrawTexture3DSDF
usingUnityEditor;usingUnityEngine;[CustomEditor(typeof(HandlesScript))][CanEditMultipleObjects]publicclassHandlesEditor:Editor{//要绘制的体积纹理。publicTexture texture;//与光线步长相乘的数字。光线步长是两个相邻像素之间的距离。默认值为 1。float stepScale;//渲染表面时的像素强度。当该值为正数时,Unity 将扩展渲染表面。//当该值为负数时,Unity 会将空的空间渲染为表面,并将表面渲染为空的空间。默认值为 0。float surfaceOffset;//Unity 用作颜色渐变的自定义渐变。如果未指定,Unity 将使用 Google Turbo 色带。Gradient customColorRamp;privatevoidOnSceneViewGUI(SceneView sv){
Handles.DrawTexture3DSDF(texture, stepScale, surfaceOffset, customColorRamp);}}
4.2 Handle:可视化操作数值(Vector3、Vector2、float等)
4.2.1 FreeMoveHandle
- FreeMoveHandle: 创建一个不受约束的移动手柄。
protectedvirtualvoidOnSceneGUI(){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();}}
usingUnityEngine;publicclassHandlesScript:MonoBehaviour{publicVector3 targetPosition {get{return m_TargetPosition;}set{ m_TargetPosition =value;}}[SerializeField]privateVector3 m_TargetPosition =newVector3(1f,0f,2f);publicvirtualvoidUpdate(){
transform.LookAt(m_TargetPosition);}}
4.2.2 FreeRotateHandle
- FreeRotateHandle: 创建一个不受约束的旋转手柄。
publicvoidOnSceneGUI(){HandlesScript t =(target asHandlesScript);
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();}}
usingUnityEngine;publicclassHandlesScript:MonoBehaviour{publicQuaternion rot = Quaternion.identity;publicvoidUpdate(){
transform.rotation = rot;}}
4.2.3 PositionHandle
- PositionHandle: 创建一个位置手柄。
protectedvirtualvoidOnSceneGUI(){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();}}
usingUnityEngine;publicclassHandlesScript:MonoBehaviour{publicVector3 targetPosition {get{return m_TargetPosition;}set{ m_TargetPosition =value;}}[SerializeField]privateVector3 m_TargetPosition =newVector3(1f,0f,2f);publicvirtualvoidUpdate(){
transform.LookAt(m_TargetPosition);}}
4.2.4 RadiusHandle
- RadiusHandle: 创建一个场景视图半径手柄。
usingUnityEngine;publicclassHandlesScript:MonoBehaviour{publicfloat areaOfEffect =1;}
publicvoidOnSceneGUI(){HandlesScript t =(target asHandlesScript);
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: 创建一个场景视图旋转手柄。
usingUnityEngine;publicclassHandlesScript:MonoBehaviour{publicQuaternion rot = Quaternion.identity;publicvoidUpdate(){
transform.rotation = rot;}}
publicvoidOnSceneGUI(){HandlesScript t =(target asHandlesScript);
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:创建一个场景视图缩放手柄。
usingUnityEngine;publicclassHandlesScript:MonoBehaviour{publicVector3 scale = Vector3.one;publicvoidUpdate(){
transform.localScale = scale;}}
publicvoidOnSceneGUI(){HandlesScript t =(target asHandlesScript);
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 手柄。
usingUnityEngine;publicclassHandlesScript:MonoBehaviour{[SerializeField]privateColor m_Color1 = Color.red;[SerializeField]privateColor m_Color2 = Color.green;publicfloat amount {get{return m_Amount;}set{ m_Amount = Mathf.Clamp01(value);}}[SerializeField,Range(0f,1f)]privatefloat m_Amount =1f;privateLight m_Light;protectedvirtualvoidOnEnable(){
m_Light =GetComponent<Light>();}publicvirtualvoidUpdate(){
m_Light.color = Color.Lerp(m_Color1, m_Color2, m_Amount);}}
protectedvirtualvoidOnSceneGUI(){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:绘制一个类似于移动工具所用箭头的箭头。
usingSystem.Drawing.Drawing2D;usingUnityEditor;usingUnityEngine;[CustomEditor(typeof(HandlesScript))][CanEditMultipleObjects]publicclassHandlesEditor:Editor{float size =1f;protectedvirtualvoidOnSceneGUI(){if(Event.current.type == EventType.Repaint){Transform transform =((HandlesScript)target).transform;
Handles.color = Handles.yAxisColor;
Handles.ArrowHandleCap(0,
transform.position +newVector3(3f,0f,0f),
transform.rotation * Quaternion.LookRotation(Vector3.right),
size,
EventType.Repaint
);
Handles.color = Handles.yAxisColor;
Handles.ArrowHandleCap(0,
transform.position +newVector3(0f,3f,0f),
transform.rotation * Quaternion.LookRotation(Vector3.up),
size,
EventType.Repaint
);
Handles.color = Handles.yAxisColor;
Handles.ArrowHandleCap(0,
transform.position +newVector3(0f,0f,3f),
transform.rotation * Quaternion.LookRotation(Vector3.forward),
size,
EventType.Repaint
);}}}
4.3.2 CircleHandleCap
- CircleHandleCap:绘制一个圆形手柄。将此手柄传递给 handle 函数。
usingSystem.Drawing.Drawing2D;usingUnityEditor;usingUnityEngine;[CustomEditor(typeof(HandlesScript))][CanEditMultipleObjects]publicclassHandlesEditor:Editor{float size =1f;protectedvirtualvoidOnSceneGUI(){if(Event.current.type == EventType.Repaint){Transform transform =((HandlesScript)target).transform;
Handles.color = Handles.xAxisColor;
Handles.CircleHandleCap(0,
transform.position +newVector3(3f,0f,0f),
transform.rotation * Quaternion.LookRotation(Vector3.right),
size,
EventType.Repaint
);
Handles.color = Handles.yAxisColor;
Handles.CircleHandleCap(0,
transform.position +newVector3(0f,3f,0f),
transform.rotation * Quaternion.LookRotation(Vector3.up),
size,
EventType.Repaint
);
Handles.color = Handles.zAxisColor;
Handles.CircleHandleCap(0,
transform.position +newVector3(0f,0f,3f),
transform.rotation * Quaternion.LookRotation(Vector3.forward),
size,
EventType.Repaint
);}}}
4.3.3 ConeHandleCap
- ConeHandleCap:绘制一个锥体手柄。将此手柄传递给 handle 函数。
usingUnityEditor;usingUnityEngine;[CustomEditor(typeof(HandlesScript))][CanEditMultipleObjects]publicclassHandlesEditor:Editor{float size =1f;protectedvirtualvoidOnSceneGUI(){if(Event.current.type == EventType.Repaint){Transform transform =((HandlesScript)target).transform;
Handles.color = Handles.xAxisColor;
Handles.ConeHandleCap(0,
transform.position +newVector3(3f,0f,0f),
transform.rotation * Quaternion.LookRotation(Vector3.right),
size,
EventType.Repaint
);
Handles.color = Handles.yAxisColor;
Handles.ConeHandleCap(0,
transform.position +newVector3(0f,3f,0f),
transform.rotation * Quaternion.LookRotation(Vector3.up),
size,
EventType.Repaint
);
Handles.color = Handles.zAxisColor;
Handles.ConeHandleCap(0,
transform.position +newVector3(0f,0f,3f),
transform.rotation * Quaternion.LookRotation(Vector3.forward),
size,
EventType.Repaint
);}}}
4.3.4 CubeHandleCap
- CubeHandleCap:绘制一个立方体手柄。将此手柄传递给 handle 函数。
usingUnityEditor;usingUnityEngine;[CustomEditor(typeof(HandlesScript))][CanEditMultipleObjects]publicclassHandlesEditor:Editor{float size =1f;protectedvirtualvoidOnSceneGUI(){if(Event.current.type == EventType.Repaint){Transform transform =((HandlesScript)target).transform;
Handles.color = Handles.xAxisColor;
Handles.CubeHandleCap(0,
transform.position +newVector3(3f,0f,0f),
transform.rotation * Quaternion.LookRotation(Vector3.right),
size,
EventType.Repaint
);
Handles.color = Handles.yAxisColor;
Handles.CubeHandleCap(0,
transform.position +newVector3(0f,3f,0f),
transform.rotation * Quaternion.LookRotation(Vector3.up),
size,
EventType.Repaint
);
Handles.color = Handles.zAxisColor;
Handles.CubeHandleCap(0,
transform.position +newVector3(0f,0f,3f),
transform.rotation * Quaternion.LookRotation(Vector3.forward),
size,
EventType.Repaint
);}}}
4.3.5 CylinderHandleCap
- CylinderHandleCap:绘制一个圆柱体手柄。将此手柄传递给 handle 函数。
usingUnityEditor;usingUnityEngine;[CustomEditor(typeof(HandlesScript))][CanEditMultipleObjects]publicclassHandlesEditor:Editor{float size =1f;protectedvirtualvoidOnSceneGUI(){if(Event.current.type == EventType.Repaint){Transform transform =((HandlesScript)target).transform;
Handles.color = Handles.xAxisColor;
Handles.CylinderHandleCap(0,
transform.position +newVector3(3f,0f,0f),
transform.rotation * Quaternion.LookRotation(Vector3.right),
size,
EventType.Repaint
);
Handles.color = Handles.yAxisColor;
Handles.CylinderHandleCap(0,
transform.position +newVector3(0f,3f,0f),
transform.rotation * Quaternion.LookRotation(Vector3.up),
size,
EventType.Repaint
);
Handles.color = Handles.zAxisColor;
Handles.CylinderHandleCap(0,
transform.position +newVector3(0f,0f,3f),
transform.rotation * Quaternion.LookRotation(Vector3.forward),
size,
EventType.Repaint
);}}}
4.3.6 DotHandleCap
- DotHandleCap:绘制一个圆点手柄。将此手柄传递给 handle 函数。
usingUnityEditor;usingUnityEngine;[CustomEditor(typeof(HandlesScript))]publicclassHandlesEditor:Editor{float size =1f;protectedvirtualvoidOnSceneGUI(){if(Event.current.type == EventType.Repaint){Transform transform =((HandlesScript)target).transform;
Handles.color = Handles.xAxisColor;
Handles.DotHandleCap(0,
transform.position +newVector3(3f,0f,0f),
transform.rotation * Quaternion.LookRotation(Vector3.right),
size,
EventType.Repaint
);
Handles.color = Handles.yAxisColor;
Handles.DotHandleCap(0,
transform.position +newVector3(0f,3f,0f),
transform.rotation * Quaternion.LookRotation(Vector3.up),
size,
EventType.Repaint
);
Handles.color = Handles.zAxisColor;
Handles.DotHandleCap(0,
transform.position +newVector3(0f,0f,3f),
transform.rotation * Quaternion.LookRotation(Vector3.forward),
size,
EventType.Repaint
);}}}
4.3.7 RectangleHandleCap
- RectangleHandleCap:绘制一个矩形手柄。将此手柄传递给 handle 函数。
usingUnityEditor;usingUnityEngine;[CustomEditor(typeof(HandlesScript))]publicclassHandlesEditor:Editor{float size =1f;protectedvirtualvoidOnSceneGUI(){if(Event.current.type == EventType.Repaint){Transform transform =((HandlesScript)target).transform;
Handles.color = Handles.xAxisColor;
Handles.RectangleHandleCap(0,
transform.position +newVector3(3f,0f,0f),
transform.rotation * Quaternion.LookRotation(Vector3.right),
size,
EventType.Repaint
);
Handles.color = Handles.yAxisColor;
Handles.RectangleHandleCap(0,
transform.position +newVector3(0f,3f,0f),
transform.rotation * Quaternion.LookRotation(Vector3.up),
size,
EventType.Repaint
);
Handles.color = Handles.zAxisColor;
Handles.RectangleHandleCap(0,
transform.position +newVector3(0f,0f,3f),
transform.rotation * Quaternion.LookRotation(Vector3.forward),
size,
EventType.Repaint
);}}}
4.4 GUI
4.4.1 Label
- Label:为位于 3D 空间中的手柄创建文本标签。
usingUnityEditor;usingUnityEngine;[CustomEditor(typeof(HandlesScript))]publicclassHandlesEditor:Editor{protectedvirtualvoidOnSceneGUI(){
Handles.color = Color.red;
Handles.Label(Vector3.zero,"测试Label");}}
4.4.2 Button
- Button:创建一个 3D 按钮。
usingUnityEditor;usingUnityEngine;[CustomEditor(typeof(HandlesScript))]publicclassHandlesEditor:Editor{protectedvirtualvoidOnSceneGUI(){if(Handles.Button(Vector3.zero, Quaternion.identity,1,2, Handles.RectangleHandleCap))
Debug.Log("The button was pressed!");}}
4.4.3 ScaleSlider
- ScaleSlider:创建一个定向缩放滑动条。
usingUnityEditor;usingUnityEngine;[CustomEditor(typeof(HandlesScript))]publicclassHandlesEditor:Editor{protectedvirtualvoidOnSceneGUI(){float scale = Handles.ScaleSlider(1, Vector3.zero, Vector3.right, Quaternion.identity,1,0.5f);}}
4.4.4 Slider
- Slider:创建一个沿着一个轴移动的 3D 滑动条。
usingUnityEditor;usingUnityEngine;[CustomEditor(typeof(HandlesScript))]publicclassHandlesEditor:Editor{protectedvirtualvoidOnSceneGUI(){Vector3 newTargetPosition = Handles.Slider(Vector3.zero, Vector3.right,1, Handles.ConeHandleCap,0.5f);}}
4.4.5 Slider2D
- Slider2D:创建一个沿两个轴定义的平面移动的 3D 滑动条。
usingUnityEditor;usingUnityEngine;[CustomEditor(typeof(HandlesScript))]publicclassHandlesEditor:Editor{protectedvirtualvoidOnSceneGUI(){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 只能为正数。
版权归原作者 游戏开发小Y 所有, 如有侵权,请联系我们删除。