Files
Fishing2NetTest/Assets/Scripts/UI/Common/ModelViewer/ModelViewerUtils.cs
2026-03-05 18:07:55 +08:00

99 lines
3.6 KiB
C#

using UnityEngine;
namespace NBF
{
public class ModelViewerUtils
{
public static ModelViewerSettings InitSetting(GameObject go, ModelViewerSettings settings)
{
if (settings.objectPosition.magnitude < 0.0001f)
settings.objectPosition = Vector3.zero;
//---Zero the GameObject euler angles if they're very small in magnitude---//
settings.objectRotation = go.transform.eulerAngles;
if (settings.objectRotation.magnitude < 0.0001f)
settings.objectRotation = Vector3.zero;
//---Set the object scale variable---//
settings.objectScale = go.transform.localScale;
//将默认对象位置设为使其位于图标中心的位置
Bounds bounds = GetObjectBounds(go);
settings.objectPosition = GetObjectAutoOffset(bounds);
// 将默认的相机设置调整为适合图标渲染中对象的呈现效果
float camAuto = GetCameraAuto(bounds);
settings.cameraSize = camAuto;
settings.cameraPosition = Vector3.one * camAuto;
return settings;
}
public static Bounds GetObjectBounds(GameObject go)
{
// 在将其位置归零之前先保存其位置信息
Vector3 prefabPos = go.transform.position;
go.transform.position = Vector3.zero;
// 创建一个边界对象,并将对象网格的边界进行封装。
MeshRenderer mr = go.GetComponent<MeshRenderer>();
Bounds bounds = new Bounds(Vector3.zero, 0.000001f * Vector3.one);
if (mr != null)
bounds.Encapsulate(mr.bounds);
else
{
SkinnedMeshRenderer smr = go.GetComponent<SkinnedMeshRenderer>();
if (smr != null)
bounds.Encapsulate(smr.bounds);
}
//同时将对象的子对象的范围也进行封装起来
EncapsulateChildBounds(go.transform, ref bounds);
//将预制物的位置重置为存储的值
go.transform.position = prefabPos;
return bounds;
}
public static Vector3 GetObjectAutoOffset(Bounds bounds)
{
//将偏移量应用到图标对象的位置上
return -bounds.center;
}
public static float GetCameraAuto(Bounds bounds)
{
//---Scale camera size and position so that the object fits in the render---//
Matrix4x4 trs = Matrix4x4.TRS(Vector3.zero, Quaternion.Euler(0, 45, 0), 1.05f * Vector3.one);
Vector3 corner = new Vector3(bounds.extents.x, bounds.extents.y, bounds.extents.z);
corner = trs * corner;
Vector2 refB2 = new Vector2(0.74f, 0.53f);
Vector2 b2 = refB2 * corner.magnitude;
return b2.magnitude;
}
public static void EncapsulateChildBounds(Transform t, ref Bounds bounds)
{
// 遍历所有子对象,封装边界
MeshRenderer mr;
for (int i = 0; i < t.childCount; i++)
{
mr = t.GetChild(i).GetComponent<MeshRenderer>();
if (mr != null)
bounds.Encapsulate(mr.bounds);
else
{
SkinnedMeshRenderer smr = t.GetChild(i).GetComponent<SkinnedMeshRenderer>();
if (smr != null)
bounds.Encapsulate(smr.bounds);
}
EncapsulateChildBounds(t.GetChild(i), ref bounds);
}
}
}
}