31.Handles自由移动自由旋转

31.Scene窗口拓展-Handles-自由移动自由旋转


31.1 知识点

知识回顾

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

Handles中的自由移动

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

渲染控制手柄的常用回调函数:

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

    // 自由移动
    // 会始终绘制一个矩形对着摄像机,鼠标按下在矩形范围内可以自由移动对象
    testSceneMono.transform.position = Handles.FreeMoveHandle(testSceneMono.transform.position, HandleUtility.GetHandleSize(testSceneMono.transform.position), Vector3.one * 5, Handles.RectangleHandleCap);
}

Handles中的自由旋转

Quaternion Handles.FreeRotateHandle(角度, 位置, 句柄大小);

private void OnSceneGUI()
{        

    // 自由旋转
    // 会始终绘制一个写死在(0,0)位置的圆形对着摄像机,鼠标按下在圆形范围内可以自由旋转对象
    testSceneMono.transform.rotation = Handles.FreeRotateHandle(testSceneMono.transform.rotation, Vector3.zero, HandleUtility.GetHandleSize(Vector3.zero));
}


31.2 知识点代码

Lesson31_Scene窗口拓展_Handles_自由移动自由旋转

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class Lesson31_Scene窗口拓展_Handles_自由移动自由旋转 : MonoBehaviour
{
    void Start()
    {
        #region 知识回顾

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

        #endregion

        #region 知识点一 Handles中的自由移动

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

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

        #endregion

        #region 知识点二 Handles中的自由旋转

        //Quaternion Handles.FreeRotateHandle(角度, 位置, 句柄大小);

        #endregion
    }
}

TestSceneMonoEditor

using System.Collections;
using System.Collections.Generic;
using UnityEditor;
using UnityEngine;

[CustomEditor(typeof(TestSceneMono))]
public class TestSceneMonoEditor : Editor
{
    private TestSceneMono testSceneMono;

    private void OnEnable()
    {
        testSceneMono = target as TestSceneMono;
    }


    private void OnSceneGUI()
    {
        //选中挂载TestSceneMono的对象会打印
        // Debug.Log("Scene窗口拓展相关逻辑");

        #region Lesson28_Scene窗口拓展_Handles_文本线段虚线

        //颜色
        Handles.color = new Color(0, 1, 0, 1f);

        //文本
        Handles.Label(testSceneMono.transform.position, "测试文本显示");

        //线段
        Handles.DrawLine(testSceneMono.transform.position,
            testSceneMono.transform.position + testSceneMono.transform.right * 5, 5);

        //虚线
        Handles.color = new Color(0, 0, 1, 1f);
        Handles.DrawDottedLine(testSceneMono.transform.position,
            testSceneMono.transform.position + testSceneMono.transform.forward * 5, 5);

        #endregion

        #region Lesson29_Scene窗口拓展_Handles_弧线圆立方体几何体

        //弧线(圆弧)
        Handles.color = Color.white;
        //如果向圆弧跟着对象动,第二个参数传入本地坐标 例如testSceneMono.transform.up,
        Handles.DrawWireArc(testSceneMono.transform.position, Vector3.up, testSceneMono.transform.forward, 30, 5);
        // Handles.DrawSolidArc(testSceneMono.transform.position, Vector3.up, testSceneMono.transform.forward, 30, 4);
        //向左旋转15度 这样以人物正前方为等分
        Handles.DrawSolidArc(testSceneMono.transform.position, testSceneMono.transform.up,
            Quaternion.Euler(0, -15, 0) * testSceneMono.transform.forward, 30, 4);


        //圆
        Handles.color = Color.gray;
        Handles.DrawSolidDisc(testSceneMono.transform.position, testSceneMono.transform.up, 2);
        Handles.DrawWireDisc(testSceneMono.transform.position, testSceneMono.transform.up, 3);

        //立方体
        Handles.color = Color.red;
        Handles.DrawWireCube(testSceneMono.transform.position, Vector3.one);


        //几何体
        //(0,0,0)
        //(1,0,0)
        //(1,0,1)
        //(0,0,z)
        Handles.DrawAAConvexPolygon(Vector3.zero, Vector3.right, Vector3.right + Vector3.forward, Vector3.forward);

        #endregion

        #region Lesson30_Scene窗口拓展_Handles_移动旋转缩放

        //移动
        //可以在选择其他默认不显示移动坐标轴工具栏也显示移动轴 以下两个API作用一致
        //注意:假如传入Vector.zero 或者 Quaternion.identity这种写死的全局值,移动轴是不会跟着对象动的
        testSceneMono.transform.position =
            Handles.DoPositionHandle(testSceneMono.transform.position, testSceneMono.transform.rotation);
        //testSceneMono.transform.position = Handles.PositionHandle(testSceneMono.transform.position, testSceneMono.transform.rotation);

        //旋转
        testSceneMono.transform.rotation =
            Handles.DoRotationHandle(testSceneMono.transform.rotation, testSceneMono.transform.position);
        //testSceneMono.transform.rotation = Handles.RotationHandle(testSceneMono.transform.rotation, testSceneMono.transform.position);


        //缩放
        //最后一个参数的括号中传入Vector3.zero的话,缩放轴不会变化,传入testSceneMono.transform.position缩放轴长短会随对象位置变化
        testSceneMono.transform.localScale = Handles.DoScaleHandle(testSceneMono.transform.localScale,
            testSceneMono.transform.position, testSceneMono.transform.rotation,
            HandleUtility.GetHandleSize(testSceneMono.transform.position));

        //testSceneMono.transform.localScale = Handles.ScaleHandle(testSceneMono.transform.localScale, testSceneMono.transform.position, testSceneMono.transform.rotation,
        //                                                 HandleUtility.GetHandleSize(Vector3.zero));

        #endregion

        #region Lesson31_Scene窗口拓展_Handles_自由移动自由旋转

        //自由移动
        //会始终绘制一个矩形对着摄像机 鼠标按下在矩形范围内可以自由移动对象
        testSceneMono.transform.position = Handles.FreeMoveHandle(testSceneMono.transform.position,
            HandleUtility.GetHandleSize(testSceneMono.transform.position),
            Vector3.one * 5, Handles.RectangleHandleCap);

        //自由旋转
        //会始终绘制一个圆形对着摄像机 鼠标按下在圆形范围内可以自由旋转对象
        testSceneMono.transform.rotation = Handles.FreeRotateHandle(testSceneMono.transform.rotation, Vector3.zero,
            HandleUtility.GetHandleSize(Vector3.zero));

        #endregion
    }
}


转载请注明来源,欢迎对文章中的引用来源进行考证,欢迎指出任何有错误或不够清晰的表达。可以在下面评论区评论,也可以邮件至 785293209@qq.com

×

喜欢就点赞,疼爱就打赏