目录
- 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 只能为正数。