using System.Collections;
using System.Collections.Generic;
using Unity.VisualScripting;
using UnityEngine;
using UnityEngine.UI;
public enum DimensionUnit
{
m,
cm,
mm
}
/// <summary>
/// 一个盒子包裹在物体外面,使用时,这个预制体在物体的最小的角落
/// </summary>
public class MeasureBox : MonoBehaviour
{
[HideInInspector] public Text[] texts;
[HideInInspector] public LineRenderer[] xs;
[HideInInspector] public LineRenderer[] ys;
[HideInInspector] public LineRenderer[] zs;
private void Awake()
{
string[] aixs = { "x", "y", "z" };
texts = GetLineText<Text>(3, "Box_Canvas/{0}Text", aixs);
xs = GetLineRenderer<LineRenderer>(4, "{0}_{1}", aixs[0]);
ys = GetLineRenderer<LineRenderer>(4, "{0}_{1}", aixs[1]);
zs = GetLineRenderer<LineRenderer>(4, "{0}_{1}", aixs[2]);
}
public GameObject target;
private void Start()
{
//SetMeasureBoxVal(Vector3.one, new Vector3(0.5f, 0.2f, 0.3f));
//SetMeasureBoxVal(target);
}
private T[] GetLineText<T>(int len, string name, string[] aixs) where T : Component
{
T[] arr = new T[len];
for (int i = 0; i < len; i++)
{
string nameStr = string.Format(name, aixs[i]);
arr[i] = transform.Find(nameStr).GetComponent<T>();
}
return arr;
}
private T[] GetLineRenderer<T>(int len, string name, string aixs) where T : Component
{
T[] arr = new T[len];
for (int i = 0; i < len; i++)
{
string nameStr = string.Format(name, aixs, i);
arr[i] = transform.Find(nameStr).GetComponent<T>();
}
return arr;
}
public void SetMeasureBoxVal(GameObject target, DimensionUnit du = DimensionUnit.m, bool islookcam = false, float bian = 0.1f)
{
if (target == null)
return;
Vector3 size = Vector3.zero;
Vector3 pos = Vector3.zero;
if (GetComponent<BoxCollider>())
{
pos = ZBH_Utils.Get_BoxCollider_min(target);
size = ZBH_Utils.Get_BoxCollider_size(target);
}
else
{
pos = ZBH_Utils.Get_GameObject_min(target);
size = ZBH_Utils.Get_GameObject_size(target);
}
SetMeasureBoxVal(pos, size, du, islookcam, bian);
}
public void SetMeasureBoxVal(Vector3 pos, Vector3 size, DimensionUnit du = DimensionUnit.m, bool islookcam = false, float bian = 0.1f)
{
if (islookcam)
{
foreach (Text txt in texts)
{
txt.AddComponent<LookAtCamera>();
}
}
UpdateInfo(pos, size, bian);
ShowText(du, size.x, size.y, size.z);
}
void UpdateInfo(Vector3 pos, Vector3 measure, float bianyuan)
{
transform.position = pos;
// x
xs[0].SetPosition(0, this.transform.position + new Vector3(-bianyuan, 0f, 0f));
xs[0].SetPosition(1, this.transform.position + new Vector3(measure.x + bianyuan, 0f, 0f));
xs[1].SetPosition(0, this.transform.position + new Vector3(-bianyuan, measure.y, 0f));
xs[1].SetPosition(1, this.transform.position + new Vector3(measure.x + bianyuan, measure.y, 0f));
xs[2].SetPosition(0, this.transform.position + new Vector3(-bianyuan, measure.y, measure.z));
xs[2].SetPosition(1, this.transform.position + new Vector3(measure.x + bianyuan, measure.y, measure.z));
xs[3].SetPosition(0, this.transform.position + new Vector3(-bianyuan, 0f, measure.z));
xs[3].SetPosition(1, this.transform.position + new Vector3(measure.x + bianyuan, 0f, measure.z));
// y
ys[0].SetPosition(0, this.transform.position + new Vector3(0f, -bianyuan, 0f));
ys[0].SetPosition(1, this.transform.position + new Vector3(0f, measure.y + bianyuan, 0f));
ys[1].SetPosition(0, this.transform.position + new Vector3(measure.x, -bianyuan, 0f));
ys[1].SetPosition(1, this.transform.position + new Vector3(measure.x, measure.y + bianyuan, 0f));
ys[2].SetPosition(0, this.transform.position + new Vector3(measure.x, -bianyuan, measure.z));
ys[2].SetPosition(1, this.transform.position + new Vector3(measure.x, measure.y + bianyuan, measure.z));
ys[3].SetPosition(0, this.transform.position + new Vector3(0f, -bianyuan, measure.z));
ys[3].SetPosition(1, this.transform.position + new Vector3(0f, measure.y + bianyuan, measure.z));
// z
zs[0].SetPosition(0, this.transform.position + new Vector3(0f, 0f, -bianyuan));
zs[0].SetPosition(1, this.transform.position + new Vector3(0f, 0f, measure.z + bianyuan));
zs[1].SetPosition(0, this.transform.position + new Vector3(measure.x, 0f, -bianyuan));
zs[1].SetPosition(1, this.transform.position + new Vector3(measure.x, 0f, measure.z + bianyuan));
zs[2].SetPosition(0, this.transform.position + new Vector3(measure.x, measure.y, -bianyuan));
zs[2].SetPosition(1, this.transform.position + new Vector3(measure.x, measure.y, measure.z + bianyuan));
zs[3].SetPosition(0, this.transform.position + new Vector3(0f, measure.y, -bianyuan));
zs[3].SetPosition(1, this.transform.position + new Vector3(0f, measure.y, measure.z + bianyuan));
// 位置变动
this.texts[0].transform.position = ZBH_Utils.GetBetweenPoint(xs[0].GetPosition(0), xs[0].GetPosition(1));
this.texts[1].transform.position = ZBH_Utils.GetBetweenPoint(ys[1].GetPosition(0), ys[1].GetPosition(1));
this.texts[2].transform.position = ZBH_Utils.GetBetweenPoint(zs[0].GetPosition(0), zs[0].GetPosition(1));
}
void ShowText(DimensionUnit du, float x, float y, float z)
{
switch (du)
{
case DimensionUnit.m:
break;
case DimensionUnit.cm:
x *= 100f;
y *= 100f;
z *= 100f;
break;
case DimensionUnit.mm:
x *= 1000f;
y *= 1000f;
z *= 1000f;
break;
}
ShowText(ZBH_Utils.TowDot(x).ToString(), ZBH_Utils.TowDot(y).ToString(), ZBH_Utils.TowDot(z).ToString(), du.ToString());
}
void ShowText(string x, string y, string z, string unit)
{
this.texts[0].text = x + unit;
this.texts[1].text = y + unit;
this.texts[2].text = z + unit;
}
}
using UnityEngine;
public class ZBH_Utils
{
#region 得到物体的尺寸
public static Vector3 Get_GameObject_Size(GameObject go)
{
BoxCollider boxCollider = go.GetComponent<BoxCollider>();
if (boxCollider)
{
return Get_BoxCollider_size(go);
}
else
{
return Get_GameObject_size(go);
}
}
/// <summary>
/// 得到物体BOX碰撞的最小值
/// </summary>
/// <param name="go"></param>
public static Vector3 Get_BoxCollider_min(GameObject go)
{
BoxCollider bc = go.GetComponent<BoxCollider>();
return bc.bounds.min;
}
/// <summary>
/// 得到物体BOX碰撞的尺寸
/// </summary>
/// <param name="go"></param>
public static Vector3 Get_BoxCollider_size(GameObject go)
{
BoxCollider bc = go.GetComponent<BoxCollider>();
return bc.bounds.size;
}
/// <summary>
/// 得到物体的最小值(无碰撞)
/// </summary>
/// <param name="go"></param>
/// <returns></returns>
public static Vector3 Get_GameObject_min(GameObject go)
{
Vector3 min_vector3 = Vector3.zero;
Renderer[] mr = go.transform.GetComponentsInChildren<Renderer>();
float x, y, z;
if (mr.Length > 0)
{
x = 0f;
y = 0f;
z = 0f;
for (int i = 0; i < mr.Length; i++)
{
if (i == 0)
{
x = mr[0].bounds.min.x;
y = mr[0].bounds.min.y;
z = mr[0].bounds.min.z;
}
else
{
if (min_vector3.x > mr[i].bounds.min.x)
{
x = mr[i].bounds.min.x;
}
if (min_vector3.y > mr[i].bounds.min.y)
{
y = mr[i].bounds.min.y;
}
if (min_vector3.z > mr[i].bounds.min.z)
{
z = mr[i].bounds.min.z;
}
}
min_vector3 = new Vector3(x, y, z);
}
}
return min_vector3;
}
/// <summary>
/// 得到物体的最大值(无碰撞)
/// </summary>
/// <param name="go"></param>
/// <returns></returns>
public static Vector3 Get_GameObject_max(GameObject go)
{
Vector3 max_vector3 = Vector3.zero;
Renderer[] mr = go.transform.GetComponentsInChildren<Renderer>();
float x, y, z;
if (mr.Length > 0)
{
x = 0f;
y = 0f;
z = 0f;
for (int i = 0; i < mr.Length; i++)
{
if (i == 0)
{
x = mr[0].bounds.max.x;
y = mr[0].bounds.max.y;
z = mr[0].bounds.max.z;
}
else
{
if (max_vector3.x < mr[i].bounds.max.x)
{
x = mr[i].bounds.max.x;
}
if (max_vector3.y < mr[i].bounds.max.y)
{
y = mr[i].bounds.max.y;
}
if (max_vector3.z < mr[i].bounds.max.z)
{
z = mr[i].bounds.max.z;
}
}
max_vector3 = new Vector3(x, y, z);
}
}
return max_vector3;
}
/// <summary>
/// 得到物体的尺寸(无碰撞)
/// </summary>
/// <param name="go"></param>
/// <returns></returns>
public static Vector3 Get_GameObject_size(GameObject go)
{
Vector3 obj_min = Get_GameObject_min(go);
Vector3 obj_max = Get_GameObject_max(go);
Vector3 size_vector3 = obj_max - obj_min;
return size_vector3;
}
/// <summary>
/// 得到物体的碰撞中心点
/// </summary>
/// <param name="go"></param>
/// <returns></returns>
public static Vector3 Get_GameObject_center(GameObject go)
{
Vector3 obj_min = Get_GameObject_min(go);
Vector3 obj_max = Get_GameObject_max(go);
Vector3 center_vector3 = (obj_max + obj_min) / 2f;
return center_vector3;
}
#endregion
/// <summary>
/// 得到两点间的距离,并保留小数点后面多少位
/// </summary>
/// <param name="point1"></param>
/// <param name="point2"></param>
/// <param name="r">小数位</param>
/// <returns></returns>
public static float GetTwoDis(Vector3 point1, Vector3 point2, float r = 2f)
{
float dis = Vector3.Distance(point1, point2);
return TowDot(dis, r);
}
/// <summary>
/// 保留几位小数
/// </summary>
/// <param name="val"></param>
/// <param name="r">位数,默认2</param>
/// <returns></returns>
public static float TowDot(float val, float r = 2f)
{
float __r = Mathf.Pow(10f, r);
return Mathf.Round(val * __r) / __r;
}
/// <summary>
/// 两点间,距离起始点的百分比的位置
/// </summary>
/// <param name="start">起始点</param>
/// <param name="end"></param>
/// <param name="percent">百分比,默认50%</param>
/// <returns></returns>
public static Vector3 GetBetweenPoint(Vector3 start, Vector3 end, float percent = 0.5f)
{
Vector3 normal = (end - start).normalized;
float distance = Vector3.Distance(start, end);
return normal * (distance * percent) + start;
}
/// <summary>
/// 设置鼠标指针
/// </summary>
/// <param name="tt2d"></param>
public static void SetMouseCursor(Texture2D tt2d = null)
{
Cursor.SetCursor(tt2d, Vector2.zero, CursorMode.Auto);
}
/// <summary>
/// 随机字符串组重新排序
/// </summary>
/// <param name="strs"></param>
/// <returns></returns>
public static string[] Get_Random_SORT(string[] strs)
{
System.Random randomNum = new System.Random();
int index = 0;
string temp;
for (int i = 0; i < strs.Length; i++)
{
index = randomNum.Next(0, strs.Length - 1);
if (index != i)
{
temp = strs[i];
strs[i] = strs[index];
strs[index] = temp;
}
}
return strs;
}
}