Unity功能-将模型适配展示到UI界面
1、功能展示
1
2、参考博文
https://blog.51cto.com/u_15127573/2762967
3、按照参考博文设置
设置完成后发现有一些模型不能适配展示,最后发现是包围盒的中心点的计算出现了问题,然后重新计算一下包围盒的中心点,显示包围盒,最后比较满意的解决了此功能。
4、代码如下
/// <summary>
/// 设置特殊摄像机渲染
/// </summary>
/// <param name="go"></param>
public void SetSpecialCamera(GameObject go)
{
//获取模型包围盒
var bound = GetBoundPointsByObj(go);
//包围盒中心
var center = bound.center;
//设置专属摄像机旋转中心点
specialCamera.GetComponent<SpecialCameraScript>().specialCameraCenterPos = center;
var extents = bound.extents;
//获取包围盒xyz最大值
float[] floats = new float[3] { extents.x, extents.y, extents.z };
float max = floats.Max();
//设置专属渲染摄像机位置和旋转
specialCamera.transform.position = new Vector3(center.x, center.y, center.z - max - 6);
specialCamera.transform.rotation = Quaternion.identity;
SetSpecialCameraSize(center.x - extents.x, center.x + extents.x, center.y - extents.y, center.y + extents.y);
}
/// <summary>
/// 获取物体包围盒
/// 父物体///物体包围盒
/// </summary>
/// <param name="obj"></param>
/// <returns></returns>
private Bounds GetBoundPointsByObj(GameObject obj)
{
var bounds = new Bounds();
if (obj != null)
{
var renders = obj.GetComponentsInChildren<Renderer>();
if (renders != null)
{
CalculateModelCenterPos(obj.transform);
bounds = new Bounds(CalculateModelCenterPos(obj.transform), Vector3.zero);
foreach (var item in renders)
{
bounds.Encapsulate(item.bounds);
}
}
}
return bounds;
}
private void OnDrawGizmos()
{
var bounds = GetBoundPointsByObj(go);
Gizmos.color = Color.red;
Gizmos.DrawWireCube(center: bounds.center, size: bounds.size);
}
/// <summary>
/// 计算模型的中心点
/// </summary>
/// <param name="tran"></param>
/// <returns></returns>
public Vector3 CalculateModelCenterPos(Transform tran)
{
Vector3 position = tran.position;
Quaternion quaternion = tran.rotation;
Vector3 scale = tran.localScale;
tran.position = Vector3.zero;
tran.rotation = Quaternion.Euler(Vector3.zero);
tran.localScale = Vector3.one;
Vector3 center = Vector3.zero;
Renderer[] renders = tran.GetComponentsInChildren<Renderer>();
foreach (Renderer child in renders)
{
center += child.bounds.center;
}
center /= tran.GetComponentsInChildren<Renderer>().Length;
Bounds bounds = new Bounds(center, Vector3.zero);
foreach (Renderer item in renders)
{
bounds.Encapsulate(item.bounds);
}
tran.position = position;
tran.rotation = quaternion;
tran.localScale = scale;
foreach (Transform item in tran)
{
item.position = item.position - bounds.center;
}
return bounds.center + tran.position;
}
/// <summary>
/// 设置正交相机的Size
/// 包围盒x方向最小值///包围盒x方向最大值///包围盒y方向最小值///包围盒y方向最大值
/// </summary>
/// <param name="xmin"></param>
/// <param name="xmax"></param>
/// <param name="ymin"></param>
/// <param name="ymax"></param>
private void SetSpecialCameraSize(float xmin, float xmax, float ymin, float ymax)
{
float xDis = xmax - xmin;
float yDis = ymax - ymin;
float sizeX = xDis / ScreenScaleFactor / 2 / specialCamera.aspect;
float sizeY = yDis / ScreenScaleFactor / 2;
if (sizeX >= sizeY)
{
specialCamera.GetComponent<SpecialCameraScript>().specialCameraSize = specialCamera.orthographicSize = sizeX;
}
else
{
specialCamera.GetComponent<SpecialCameraScript>().specialCameraSize = specialCamera.orthographicSize = sizeY;
}
}
下面代码挂载到专属摄像机上即可
public class SpecialCameraScript : MonoBehaviour
{
public float zoomSpeed = 1f;
public float specialCameraSize;
private Camera specialCamera;
//正交摄像机绕着位置旋转
public Vector3 specialCameraCenterPos;
public float rotateSpeed = 5f;
// Start is called before the first frame update
void Start()
{
specialCamera = this.GetComponent<Camera>();
}
// Update is called once per frame
void Update()
{
//float scrollAmount = Input.GetAxis("Mouse ScrollWheel");
//specialCamera.orthographicSize += scrollAmount * zoomSpeed;
//specialCamera.orthographicSize = Mathf.Clamp(specialCamera.orthographicSize, specialCameraSize / 4, specialCameraSize * 2);
//旋转
if (Input.GetMouseButton(1))
{
float horizontal = Input.GetAxis("Mouse X");
float vertical = Input.GetAxis("Mouse Y");
transform.RotateAround(specialCameraCenterPos, Vector3.up, horizontal * rotateSpeed);
transform.RotateAround(specialCameraCenterPos, transform.right, -vertical * rotateSpeed);
}
}
}