Unity開發Hololens應用,自動生成包裹物體大小的三維旋轉和縮放邊框
阿新 • • 發佈:2019-01-31
在開發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預製體。
後續分享一下在Hololens中實現旋轉和縮放的一些功能。