Unity3d定位模型, 繞模型旋轉、拖動和縮放,獲得模型中心點

此腳本掛在 Camera(攝像機)上。

定位模型用作查找模型後定位到該模型的跟前,然後擁有下面的操作功能;

類似編輯器模式下的操作,用作瀏覽模型使用,旋轉、拖動和縮放均是操作的Camera(攝像機)位移;

高亮使用了HighlightingSystem插件;

中心點並非模型的transform.position,而是模型的正中心,因爲有些模型的position不是模型正中心,所以需要此方法。

using HighlightingSystem;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;

public class Test01 : MonoBehaviour {

    public Transform obj;
    float maxX, maxY, maxNum;
    //float minx, minY, minZ;
    private Vector3 centerPoint;

    #region 瀏覽模型操控屬性
    /// <summary>
    /// 縮放距離
    /// </summary>
    public float ZoomSpeed = 30;
    /// <summary>
    /// 拖動速度
    /// </summary>
	public float MovingSpeed = 0.5f;
    /// <summary>
    /// 視角擺動速度
    /// </summary>
	public float RotateSpeed = 1;
    /// <summary>
    /// 攝像機旋轉速度
    /// </summary>
    public float distance = 30;

    Quaternion rotation;
    Vector3 position;
    float delta_x, delta_y, delta_z;
    float delta_rotation_x, delta_rotation_y; 
    #endregion

   

    void Start () {
        //計算模型正前方位置點
        Mesh mesh = obj.GetComponent<MeshFilter>().mesh;
        Vector3[] vertices = mesh.vertices;
        //minZ = obj.position.z;
        //計算得到最值頂點,判斷模型的最長或最寬,用來計算定位點的離模型的距離
        foreach (Vector3 item in vertices)
        {
            if (item.x > maxX)
            {
                maxX = item.x;
            }
            if (item.y > maxY)
            {
                maxY = item.y;
            }
        }

        centerPoint = GetCenter(obj.gameObject);

        //得到模型最長端作爲計算視點距離
        if (maxX > maxY)
        {
            maxNum = maxX;
        }
        else
        {
            maxNum = maxY;
        }
        if (maxNum < 5) maxNum = 5;
        //獲得模型正前方視點
        Camera.main.transform.position = new Vector3(centerPoint.x, centerPoint.y, centerPoint.z - maxNum);
        
//================================================
//方法二:如果obj對象爲靜態對象,則用此方法
        //Renderer[] mrs = obj.GetComponentsInChildren<Renderer>();
        //Vector3 center = obj.transform.position;
        //if (mrs.Length != 0)
        //{
        //    Bounds bounds = new Bounds(center, Vector3.zero);
        //    foreach (Renderer item in mrs)
        //    {
        //        bounds.Encapsulate(item.bounds);
        //    }
        //    center = bounds.center;
        //    print("中心點:" + center + "最大點:" + bounds.max + "最小點:" + bounds.min);

        //    if ((bounds.max.x - bounds.min.x) > (bounds.max.y - bounds.min.y))
        //    {
        //        maxNum = bounds.max.x - bounds.min.x;
        //    }else if((bounds.max.x - bounds.min.x) < (bounds.max.y - bounds.min.y))
        //    {
        //        maxNum = bounds.max.y - bounds.min.y;
        //    }
        //    else
        //    {
        //        maxNum = bounds.max.x - bounds.min.x;
        //    }
        //    print(maxNum);
        //    //限制模型過小,導致定位過近
        //    if (maxNum < 8)
        //    {
        //        maxNum = 8;
        //    }
        //    print(maxNum);
        //}
        //centerPoint = center;
//================================================

        //高亮
        Highlighter highlighter = obj.gameObject.AddComponent<Highlighter>();//添加高亮腳本
        highlighter.ConstantOn();

      
    }

    // Update is called once per frame
    void Update()
    {
        //拖動
        if (Input.GetMouseButton(2))
        {
            //根據距離實時調節拖動靈敏度
            MovingSpeed = Vector3.Distance(transform.position, centerPoint) / 40;
            
            delta_x = Input.GetAxis("Mouse X") * MovingSpeed;
            delta_y = Input.GetAxis("Mouse Y") * MovingSpeed;
            //rotation = Quaternion.Euler(0, transform.rotation.eulerAngles.y, 0);
            //transform.position = rotation * new Vector3(-delta_x, 0, -delta_y) + transform.position;
            transform.Translate(-delta_x, -delta_y, 0);


        }

        //縮放
        if (Input.GetAxis("Mouse ScrollWheel") != 0)
        {
            //縮放距離限制
            if(Vector3.Distance(transform.position, centerPoint) < 5f)
            {
                delta_z = -Input.GetAxis("Mouse ScrollWheel") * ZoomSpeed;
                if (delta_z > 0)
                {
                    transform.Translate(0, 0, -delta_z);
                }
            }else if (Vector3.Distance(transform.position, centerPoint) > maxNum*2f)
            {
                delta_z = -Input.GetAxis("Mouse ScrollWheel") * ZoomSpeed;
                if (delta_z < 0)
                {
                    transform.Translate(0, 0, -delta_z);
                }
            }
            else
            {
                delta_z = -Input.GetAxis("Mouse ScrollWheel") * ZoomSpeed;
                transform.Translate(0, 0, -delta_z);
            }
            

        }

        //旋轉
        if (Input.GetMouseButton(1))
        {
            //根據距離調節旋轉靈敏度
            //RotateSpeed = Vector3.Distance(transform.position, centerPoint) / 80;

            delta_rotation_x = Input.GetAxis("Mouse X") * RotateSpeed;
            delta_rotation_y = -Input.GetAxis("Mouse Y") * RotateSpeed;
            position = transform.rotation * new Vector3(0, 0, distance) + transform.position;
            transform.Rotate(0, delta_rotation_x, 0, Space.World);
            transform.Rotate(delta_rotation_y, 0, 0);
            transform.position = transform.rotation * new Vector3(0, 0, -distance) + position;
            
            
        }
    }


    /// <summary>
    /// 獲得中心點
    /// </summary>
    /// <param name="target"></param>
    /// <returns></returns>
    private Vector3 GetCenter(GameObject target)
    {
        Renderer[] mrs = target.GetComponentsInChildren<Renderer>();
        Vector3 center = target.transform.position;
        if (mrs.Length != 0)
        {
            Bounds bounds = new Bounds(center, Vector3.zero);
            foreach (Renderer item in mrs)
            {
                bounds.Encapsulate(item.bounds);
            }
            center = bounds.center;
        }
        return center;
    }
}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章