Unity开发Hololens应用,自动生成包裹物体大小的三维旋转和缩放边框

发表于2018-09-28
评论0 4.7k浏览
在开发Hololens应用时,可能会碰到需要实现物体旋转和缩放的功能,在制作物体旋转缩放控制块时,通过此方法可以快速创建与物体等大小的边框,减少部分工作量。


直接上代码:
using System.Collections;
using System.Collections.Generic;
using UnityEditor;
using UnityEngine;
public class InitRotateAndScaleController : Editor
{
    [MenuItem("Tools/InitRotateAndScaleControllerObject")]
    public static void InitRotateAndScaleControllerObject()
    {
        //获取当前选中的物体
        GameObject selectedObject = Selection.activeTransform.gameObject;
        Debug.Log(selectedObject.name);
        //获取当前选中物体的大小
        Vector3 objectSize = GetBoundsSize(selectedObject);
        //获取当前选中物体的中心点
        Vector3 center = GetBoundsCenter(selectedObject);
        //获取Cube的Prefab
        GameObject pointAndLinsPrefab = Resources.Load("Prefabs/PointsAndLines") as GameObject;
        //生成方格的8个坐标点
        Vector3[] PointPositions = new Vector3[8];
        //8个坐标点在坐标系中相乘的因数
        Vector3[] MultiplicationPoints = new Vector3[]
        {
            new Vector3(1,1,1),
            new Vector3(1,1,-1),
            new Vector3(-1,1,-1),
            new Vector3(-1,1,1),
            new Vector3(1,-1,1),
            new Vector3(1,-1,-1),
            new Vector3(-1,-1,-1),
            new Vector3(-1,-1,1)
        };
        //为8个坐标点赋值,即中心点加上每条边的长度的1/2,同时乘以相关的位置因数
        for (int i = 0; i < PointPositions.Length; i++)
        {
            PointPositions[i] = center + new Vector3(objectSize.x * MultiplicationPoints[i].x * 1.0f / 2.0f, 
                objectSize.y * MultiplicationPoints[i].y * 1.0f / 2.0f, 
                objectSize.z * MultiplicationPoints[i].z * 1.0f / 2.0f);
        }
        //12条边的中心点
        Vector3[] LinePositions = new Vector3[12];
        //12条边所对应的两个端点
        Vector2[] PointsConnection = new Vector2[12]
        {
            new Vector2(1,2),
            new Vector2(1,5),
            new Vector2(1,4),
            new Vector2(3,2),
            new Vector2(3,4),
            new Vector2(3,7),
            new Vector2(7,8),
            new Vector2(5,8),
            new Vector2(6,7),
            new Vector2(5,6),
            new Vector2(2,6),
            new Vector2(4,8),
        };
        //12条边的方向
        Vector3[] PointsConnectionDirection = new Vector3[12]
        {
            new Vector3(0,0,1),
            new Vector3(0,1,0),
            new Vector3(1,0,0),
            new Vector3(1,0,0),
            new Vector3(0,0,1),
            new Vector3(0,1,0),
            new Vector3(0,0,1),
            new Vector3(1,0,0),
            new Vector3(1,0,0),
            new Vector3(0,0,1),
            new Vector3(0,1,0),
            new Vector3(0,1,0)
        };
        //12条边的边长,也可以用objectSize的x,y,z表示
        float[] LineLength = new float[12];
        //计算12条边的变成和12条边的中心点
        for (int i = 0; i < LinePositions.Length; i++)
        {
            LinePositions[i] = (PointPositions[System.Convert.ToInt32(PointsConnection[i].x - 1)] + PointPositions[System.Convert.ToInt32(PointsConnection[i].y - 1)]) * 0.5f;
            LineLength[i] = Vector3.Distance(PointPositions[System.Convert.ToInt32(PointsConnection[i].x - 1)], PointPositions[System.Convert.ToInt32(PointsConnection[i].y - 1)]);
        }
        //设置默认的顶点大小
        float PointScale = Mathf.Min(objectSize.x, objectSize.y, objectSize.z) * 0.1f;
        //设置默认的边的粗细
        float LineScale = PointScale * 0.3f;
        //初始化8个顶点
        for (int i = 0; i < PointPositions.Length; i++)
        {
            GameObject point = Instantiate(pointAndLinsPrefab);
            point.name = "Point" + i;
            point.transform.localScale = new Vector3(1, 1, 1) * PointScale;
            point.transform.position = PointPositions[i];
            point.tag = "Point";
        }
        //初始化12条边
        for (int i = 0; i < LinePositions.Length; i++)
        {
            GameObject line = Instantiate(pointAndLinsPrefab);
            line.name = "Line" + i;
            line.transform.localScale = LineLength[i] * PointsConnectionDirection[i];
            line.transform.localScale = new Vector3(line.transform.localScale.x == 0 ? LineScale : line.transform.localScale.x,
                line.transform.localScale.y == 0 ? LineScale : line.transform.localScale.y,
                line.transform.localScale.z == 0 ? LineScale : line.transform.localScale.z);
            line.transform.position = LinePositions[i];
            line.tag = "Line";
        }
    }
    /// <summary>
        /// 获取物体的边界
        /// </summary>
        /// <param name="go">需要计算边界的物体</param>
        /// <returns></returns>
        public static Bounds GetBounds(GameObject go)
        {
            Bounds bound = new Bounds(go.transform.position, Vector3.zero);
            Object[] rList = go.GetComponentsInChildren(typeof(Renderer));
            Vector3 center = Vector3.zero;
            foreach (Renderer render in rList)
            {
                bound.Encapsulate(render.bounds);
                center += render.bounds.center;
            }
            center /= rList.Length;
            bound.center = center;
            return bound;
        }
        /// <summary>
        /// 获取物体边界的大小
        /// </summary>
        /// <param name="go">需要计算边界的物体</param>
        /// <returns></returns>
        public static Vector3 GetBoundsSize(GameObject go)
        {
            Bounds bound = GetBounds(go);
            Vector3 size = bound.size;
            return size;
        }
        /// <summary>
        /// 获取物体边界的中心点
        /// </summary>
        /// <param name="go">需要计算中心点的物体</param>
        /// <returns></returns>
        public static Vector3 GetBoundsCenter(GameObject go)
        {
            Bounds bound = GetBounds(go);
            Vector3 center = bound.center;
            return center;
        }
}
需要在Resources中创建默认大小的Cube预制体。
来自:https://blog.csdn.net/beihuanlihe130/article/details/79413288

如社区发表内容存在侵权行为,您可以点击这里查看侵权投诉指引