UEDL8-4——自由移动、自由旋转

本章代码关键字

1
2
3
HandleUtility.GetHandleSize()    //该方法需要传入一个位置,返回一个float值,该值可以用于缩放,使绘制在Scene窗口上的内容相对于摄像机的大小不变
Handles.FreeMoveHandle() //为点或者对象添加自由移动的控制器
Handles.FreeRotateHandle() //为点或者对象添加自由旋转的控制器

让句柄(控制器)在Scene窗口上显示的大小恒定

HandleUtility.GetHandleSize()方法用于获取在 Scene 窗口中的一个单位距离所对应的屏幕空间大小
这个方法主要用于根据物体的距离来动态调整控制手柄的大小,使其在不同距离下能够在视图中显示合适的大小
一般我们把对象位置传递进去,他会自动得到一个句柄大小

简单来说,该方法需要传入一个位置,根据这个位置与摄像机的距离返回一个float值,该值可以用于控制缩放,
使得某个绘制在Scene窗口上的内容相对于摄像机的大小不变,无论其距离摄像机多远

例如下面的这段代码,使用HandleUtility.GetHandleSize()返回的值修改红色线框立方体的缩放,使其相对于摄像机的大小不变

1
2
3
4
5
6
7
8
9
10
11
12
private Lesson26 targetObj;

private void OnEnable()
{
targetObj = target as Lesson26;
}

private void OnSceneGUI()
{
Handles.color = Color.red;
Handles.DrawWireCube(targetObj.transform.position, Vector3.one * HandleUtility.GetHandleSize(targetObj.transform.position));
}

效果如下:

image
image

image

Handles中的自由移动

一个不受约束的移动控制柄,这个把手可以在所有方向上自由移动
Handles.FreeMoveHandle(位置, 句柄大小, 移动步进值(按住ctrl键时会按该单位移动), 渲染控制手柄的回调函数);​,返回值为Vector3

  • 返回值:由移动控制柄控制移动后返回的位置

  • 参数一:要移动的点的位置

  • 参数二:句柄大小,句柄大小一般配合HandleUtility.GetHandleSize()函数使用

  • 参数三:移动步进值(按住ctrl键时该单位移动固定距离的值)

  • 参数四:渲染控制手柄的回调函数

    渲染控制手柄的常用回调函数,它们的区别仅在于绘制出来的控制器形状不一样

    • Handles.RectangleHandleCap:一个矩形形状的控制手柄,通常用于表示一个平面的控制面
    • Handles.CircleHandleCap:一个圆形的控制手柄,通常用于表示一个球体的控制面
    • Handles.ArrowHandleCap:一个箭头形状的控制手柄,通常用于表示方向

以上是Unity2022版的Handles.FreeMoveHandle​方法的参数列表,
但值得一提的是,Unity2021版及以前的版本的Handles.FreeMoveHandle​方法的参数列表会在参数一后面额外要求一个点的旋转角度的四元数参数
因此Unity2021版及以前的版本的参数列表为:

  • 返回值:由移动控制柄控制移动后返回的位置
  • 参数一:移动位置
  • 参数二:旋转角度
  • 参数三:句柄大小
  • 参数四:移动步进值(按住ctrl键时该单位移动固定距离的值)
  • 参数五:渲染控制手柄的回调函数
1
2
3
4
5
6
7
8
9
10
11
12
13
14
private Lesson26 targetObj;

private void OnEnable()
{
targetObj = target as Lesson26;
}

private void OnSceneGUI()
{
targetObj.transform.position = Handles.FreeMoveHandle(targetObj.transform.position,
HandleUtility.GetHandleSize(targetObj.transform.position),
Vector3.one,
Handles.RectangleHandleCap);
}

实现效果:image

拖到该白框可以让点或者对象在(渲染Scene窗口的)摄像机的拍摄范围的横截面上自由移动

Handles中的自由旋转

Handles.FreeRotateHandle(角度, 位置, 句柄大小);​,返回值是Quaternion

  • 返回值:由旋转控制柄控制旋转后返回的四元数
  • 参数一:要移动的点的旋转角度(四元数)
  • 参数二:句柄的位置
  • 参数三:句柄大小,句柄大小一般配合HandleUtility.GetHandleSize()函数使用
1
2
3
4
5
6
7
8
9
10
11
12
13
private Lesson26 targetObj;

private void OnEnable()
{
targetObj = target as Lesson26;
}

private void OnSceneGUI()
{
targetObj.transform.rotation = Handles.FreeRotateHandle(targetObj.transform.rotation,
targetObj.transform.position,
HandleUtility.GetHandleSize(targetObj.transform.position));
}

显示效果:image

拖到该白框可以让点或者对象如转动球体那样让点或者对象自由旋转