1. 程式人生 > >Unity中實現Camera縮放旋轉

Unity中實現Camera縮放旋轉

先上效果圖:


把縮放和旋轉分開說吧

縮放:

原理很簡單:

1.先儲存相機與玩家的的位置偏移offset

2.獲取使用者輸入(滾輪)

3.將滾輪輸入乘一個合理的係數,也可以稱為縮放速度啦

4.將offset數值更新

ps:第四步用到了vector3.normalized,首先獲取到offset的單位向量,再將它放大

pps:可以使用vector3.magnitude獲取偏移向量offset的模(向量長度),通過模來限制最大縮放和最小縮放

    void ScrollView()
    {
        //限制最大縮放
        if (Input.GetAxis("Mouse ScrollWheel") < 0 && offsetPlayerPos.magnitude < maxScroll)
        {
            //獲取偏移量的模
            distance = offsetPlayerPos.magnitude;
            distance += System.Math.Abs(Input.GetAxis("Mouse ScrollWheel")) * scrollSpeed;
            //通過獲得單位向量*新的偏移模更新偏移資訊
            offsetPlayerPos = offsetPlayerPos.normalized * distance;
        }
        //限制最小縮放
        if (Input.GetAxis("Mouse ScrollWheel") > 0 && offsetPlayerPos.magnitude > minScroll)
        {
            //獲取偏移量的模
            distance = offsetPlayerPos.magnitude;
            distance += -System.Math.Abs(Input.GetAxis("Mouse ScrollWheel")) * scrollSpeed;
            //通過獲得單位向量*新的偏移模更新偏移資訊
            offsetPlayerPos = offsetPlayerPos.normalized * distance;
        }
    }

旋轉:

原理很簡單:

先講左右旋轉(Mouse X)

1.獲取使用者輸入Input.GetAxis("Mouse X")

2.將攝像機繞著玩家,以玩家的y軸進行旋轉

3.旋轉完成,更新偏移資訊offset

ps:這裡左右旋轉我認為不需要限制

            transform.RotateAround(playerTransform.position, playerTransform.up, Input.GetAxis("Mouse X") * rotateSpeed);
            //更新玩家與攝像機的偏移資訊
            offsetPlayerPos = transform.position - playerTransform.position;
            transform.position = playerTransform.position + offsetPlayerPos;

再來上下旋轉(Mouse Y)

1.獲取使用者輸入Input.GetAxis("Mouse Y")

2.將攝像機繞著玩家,以攝像機的X軸進行旋轉(這是個坑,一開始繞著玩家的X軸發現很奇怪,因為玩家的位置時刻變化,導致一些詭異效果,因為我攝像機使用了LookAt所以保證攝像機的做圓周運動)

3.旋轉完成,更新偏移資訊offset

ps:這個上下旋轉的角度我使用vector3.localEulerAngles.x獲取角度大小從而限制最大值與最小值

        if (Input.GetMouseButton(1))
        {
            //限制最大角度
            if (transform.localEulerAngles.x < maxYRotateAngles && Input.GetAxis("Mouse Y") < 0)
            {
                transform.RotateAround(playerTransform.position, transform.right, -Input.GetAxis("Mouse Y") * rotateSpeed);
                //更新玩家與攝像機的偏移資訊
                offsetPlayerPos = transform.position - playerTransform.position;
                transform.position = playerTransform.position + offsetPlayerPos;
            }
            //限制最小角度
            if (transform.localEulerAngles.x > minYRotateAngles && Input.GetAxis("Mouse Y") > 0)
            {
                transform.RotateAround(playerTransform.position, transform.right, -Input.GetAxis("Mouse Y") * rotateSpeed);
                //更新玩家與攝像機的偏移資訊
                offsetPlayerPos = transform.position - playerTransform.position;
                transform.position = playerTransform.position + offsetPlayerPos;
            }

        }

完整程式碼如下:掛到Camera上即可,可通過inspector面板調節各引數

public class CameraController : MonoBehaviour {

    public float maxScroll;
    public float minScroll;
    public float maxYRotateAngles = 70;
    public float minYRotateAngles = 5;
    public float rotateSpeed = 5;
    public float scrollSpeed = 10;

    private Transform playerTransform;
    private Vector3 offsetPlayerPos;
    private float distance;
    private Quaternion currentRotation;

    void Start()
    {
        playerTransform = GameObject.FindGameObjectWithTag("Player").transform;
        transform.LookAt(playerTransform);
        offsetPlayerPos = transform.position - playerTransform.position;
    }


    void Update()
    {
        transform.position = playerTransform.position + offsetPlayerPos;
        RotateCamera();
        ScrollView();
    }
    void RotateCamera()
    {
        if (Input.GetMouseButton(1))
        {

            transform.RotateAround(playerTransform.position, playerTransform.up, Input.GetAxis("Mouse X") * rotateSpeed);
            //更新玩家與攝像機的偏移資訊
            offsetPlayerPos = transform.position - playerTransform.position;
            transform.position = playerTransform.position + offsetPlayerPos;
            //限制最大角度
            if (transform.localEulerAngles.x < maxYRotateAngles && Input.GetAxis("Mouse Y") < 0)
            {
                transform.RotateAround(playerTransform.position, transform.right, -Input.GetAxis("Mouse Y") * rotateSpeed);
                //更新玩家與攝像機的偏移資訊
                offsetPlayerPos = transform.position - playerTransform.position;
                transform.position = playerTransform.position + offsetPlayerPos;
            }
            //限制最小角度
            if (transform.localEulerAngles.x > minYRotateAngles && Input.GetAxis("Mouse Y") > 0)
            {
                transform.RotateAround(playerTransform.position, transform.right, -Input.GetAxis("Mouse Y") * rotateSpeed);
                //更新玩家與攝像機的偏移資訊
                offsetPlayerPos = transform.position - playerTransform.position;
                transform.position = playerTransform.position + offsetPlayerPos;
            }

        }
    }
    void ScrollView()
    {
        //限制最大縮放
        if (Input.GetAxis("Mouse ScrollWheel") < 0 && offsetPlayerPos.magnitude < maxScroll)
        {
            //獲取偏移量的模
            distance = offsetPlayerPos.magnitude;
            distance += System.Math.Abs(Input.GetAxis("Mouse ScrollWheel")) * scrollSpeed;
            //通過獲得單位向量*新的偏移模更新偏移資訊
            offsetPlayerPos = offsetPlayerPos.normalized * distance;
        }
        //限制最小縮放
        if (Input.GetAxis("Mouse ScrollWheel") > 0 && offsetPlayerPos.magnitude > minScroll)
        {
            //獲取偏移量的模
            distance = offsetPlayerPos.magnitude;
            distance += -System.Math.Abs(Input.GetAxis("Mouse ScrollWheel")) * scrollSpeed;
            //通過獲得單位向量*新的偏移模更新偏移資訊
            offsetPlayerPos = offsetPlayerPos.normalized * distance;
        }
    }
}