Unity设备展示中使用鼠标对摄像机画面的控制及镜头复位

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档


前言

日常开发中,模型的展示需要使摄像机画面聚焦在模型上,分享下鼠标控制的方法。代码中用到了DoTween插件的功能,大家自行下载导入。


一、控制代码

using DG.Tweening;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class CameraControlObj : MonoBehaviour
{
    public bool isControl=false;
    private Vector3 v3init;
    public float xMinLimit = -360f;
    public float xMaxLimit = 360f;
    public float yMinLimit = 0f;
    public float yMaxLimit = 80f;
    public float xSpeed = 50.0f;
    public Transform target;
    public float distance = 10.0f;
    public float nearLimit = 1.0f;
    public float farLimit = 80.0f;
    public float movSpeedScroll = 5.0f;
    public float movSpeed = 0.005f;
    public float x;
    public float y;
    public float z;

    Vector3 v3Pos;
    float v3Distance;

    Quaternion rotation;
    Vector3 position;
    // Use this for initialization
    void Start()
    {
          ParamInit();

    }

    private bool bFstTouch;
    private Vector3 vCurPos;
    private Vector3 vOrgPos;
    private float yDis;
    private float xDis;
    private Touch touch1;
    private Touch touch2;
    private Touch touch3;
    private float touchDistance;
    private float lastTouchDistance;
    private float deltaDistance;
    public void ParamInit()
    {
        //v3init = target.position;
        //v3Pos = new Vector3(x, y, z);
        //v3Distance = distance;

    }
   

    // Update is called once per frame
    public void Update()
    {
       
        if (target==null|| !isControl)
        {
            return;
        }
        //if (Input.GetMouseButtonDown(0))
        //{
        //    target.position= v3init;
        //    distance = v3Distance;
        //    x = v3Pos.x;
        //    y = v3Pos.y;
        //    z = v3Pos.z;
        //}

        if (Application.platform == RuntimePlatform.WindowsEditor || Application.platform == RuntimePlatform.WebGLPlayer || Application.platform == RuntimePlatform.WindowsPlayer)
        {
            if (Input.GetMouseButton(1))
            {
                x += Input.GetAxis("Mouse X") * xSpeed * 0.02f;
                x = ClampAngle(x, xMinLimit, xMaxLimit);
                y -= Input.GetAxis("Mouse Y") * xSpeed * 0.02f;
                y = ClampAngle(y, yMinLimit, yMaxLimit);

            }
            else if (Input.GetMouseButton(0))
            {

            }
            else if (Input.GetMouseButton(2))
            {
                vCurPos = Input.mousePosition;
                if (!bFstTouch)
                {
                    vOrgPos = vCurPos;
                    bFstTouch = true;
                    return;
                }
                if (vOrgPos != vCurPos)
                {
                    yDis = (vCurPos.y - vOrgPos.y) * movSpeed;
                    xDis = (vCurPos.x - vOrgPos.x) * movSpeed;
                    vOrgPos = vCurPos;//Record last mouseposition
                    //Change target's position,acording' its rotation and the distance mouse moved
                    Quaternion rot = Quaternion.Euler(y, x, 0);
                    Vector3 pos = rot * new Vector3(-xDis, -yDis, 0) + target.position;
                    target.position = pos;
                }
            }
            if (Input.GetMouseButtonUp(2))
            {
                bFstTouch = false;
            }
            if (Input.GetAxis("Mouse ScrollWheel") != 0)
            {
                distance -= Input.GetAxis("Mouse ScrollWheel") * movSpeedScroll;
                distance = Mathf.Clamp(distance, nearLimit, farLimit);
            }

        }
        else
        {
            int iTouchCount = Input.touchCount;
            switch (iTouchCount)
            {
                case 1:
                    touch1 = Input.GetTouch(0);
                    if (touch1.phase == TouchPhase.Moved)
                    {
                        x += (Input.GetTouch(0).deltaPosition.x) * xSpeed * 0.02f;
                        x = ClampAngle(x, xMinLimit, xMaxLimit);
                        y -= (Input.GetTouch(0).deltaPosition.y) * xSpeed * 0.02f;
                        y = ClampAngle(y, yMinLimit, yMaxLimit);
                    }
                    break;
                case 2:
                    touch1 = Input.GetTouch(0);
                    touch2 = Input.GetTouch(1);
                    if (touch1.phase == TouchPhase.Moved || touch2.phase == TouchPhase.Moved)
                    {
                        touchDistance = (touch1.position - touch2.position).magnitude;
                        lastTouchDistance = ((touch1.position - touch1.deltaPosition) - (touch2.position - touch2.deltaPosition)).magnitude;
                        deltaDistance = lastTouchDistance - touchDistance;

                        distance += deltaDistance * movSpeedScroll;
                        distance = Mathf.Clamp(distance, nearLimit, farLimit);
                    }
                    break;
                case 3:
                    touch1 = Input.GetTouch(0);
                    touch2 = Input.GetTouch(1);
                    touch3 = Input.GetTouch(2);
                    if (touch1.phase == TouchPhase.Moved && touch1.phase == TouchPhase.Moved && touch3.phase == TouchPhase.Moved)
                    {
                        vCurPos = touch3.position;
                        if (!bFstTouch)
                        {
                            vOrgPos = vCurPos;
                            bFstTouch = true;
                            return;
                        }
                        if (vOrgPos != vCurPos)
                        {
                            yDis = (vCurPos.y - vOrgPos.y) * movSpeed;
                            xDis = (vCurPos.x - vOrgPos.x) * movSpeed;
                            vOrgPos = vCurPos;//Record last mouseposition
                            //Change target's position,acording' its rotation and the distance mouse moved
                            Quaternion rot = Quaternion.Euler(y, x, 0);
                            Vector3 pos = rot * new Vector3(-xDis, -yDis, 0) + target.position;
                            target.position = pos;

                        }
                    }
                    break;
                case 0:
                    bFstTouch = false;
                    break;
            }

        }
        rotation = Quaternion.Euler(y, x, z);
        position = rotation * new Vector3(0f, 0f, -distance) + target.position;
        transform.position = Vector3.Lerp(transform.position, position, Time.deltaTime * 10);
        transform.rotation = Quaternion.Lerp(transform.rotation, rotation, Time.deltaTime * 10);

    }


    static float ClampAngle(float angle, float min, float max)
    {
        if (angle < -360)
            angle += 360;
        if (angle > 360)
            angle -= 360;
        return Mathf.Clamp(angle, min, max);
    }

    /// <summary>
    /// 设定相机角度
    /// </summary>
    /// <param name="dis"></param>
    /// <param name="posx"></param>
    /// <param name="posy"></param>
    public void setPos(float dis, float posx, float posy)
    {

        distance = dis;
        x = posx;
        y = posy;
    }

    /// <summary>
    /// 目标点移动
    /// </summary>
    public void TargetMove(Transform t) 
    {
        target.DOMove(t.position,1f);
    }

    float DifferenceDistance;
    /// <summary>
    /// 相机复原位置
    /// </summary>
    public void CamMoveInitPos()
    {
        isControl = false;
        DifferenceDistance = distance;
        this.transform.DORotate(Vector3.zero, 1f).
            OnUpdate(() =>
            {
                x = this.transform.eulerAngles.y;
                y = this.transform.eulerAngles.x;
                rotation = Quaternion.Euler(y, x, z);
                position = rotation * new Vector3(0f, 0f, -distance) + target.position;
                transform.position = position;
                transform.rotation = rotation;
                distance += (nearLimit + 5f - DifferenceDistance)*Time.deltaTime;
            }).OnComplete
        (
            () =>
            {
                x = 0;
                y = 0;
                isControl = true;
            }
            );
    }
 [ContextMenu("相机视角复位")]
    public void CameraViewInit() 
    {
        CamMoveInitPos();
    }

}

二、使用方法

2.1 首先将脚本挂载到相机物体上

将脚本挂载在相机上

2.2 将观察物体拖到脚本定义物体中;

在这里插入图片描述

2.3 在镜头切换后,可以通过图中功能按钮进行视角的复位;

在这里插入图片描述

三、键盘移动相机方法

    public class CameraMoveAndRotate : MonoBehaviour
    {
        public GameObject target;
        public float sensitivity = 2f;
        public float speed = 0.1f;

        /// <summary>
        /// 相机可移动区域 (限制围绕中心点和相机的 x ,z)
        /// </summary>
        public Bounds aroundPosBounds = new Bounds();

        // Start is called before the first frame update
        void Start()
        {
            if (target==null)
            {
                target = Camera.main.gameObject;
            }
        }
        旋转速度
        //public float rotationSpeed = 5f;
        上下旋转角度限制
        //public float maxVerticalAngle = 90f;
        //public float minVerticalAngle = -90f;
        旋转缓冲速度
        //public float lerpSpeed = 10f;
        //private float targetRotationX = 0f;
        //private float targetRotationY = 0f;

        // Update is called once per frame
        void Update()
        {
            Move();

            if (Input.GetMouseButton(1))
            {
                Rotate();
                //if (Input.GetMouseButton(1))
                //{
                //    // 获取鼠标输入的旋转增量
                //    float rotationXInput = -Input.GetAxis("Mouse Y");
                //    float rotationYInput = Input.GetAxis("Mouse X");
                //    // 根据旋转速度进行摄像机的旋转
                //    targetRotationX += rotationXInput * rotationSpeed;
                //    targetRotationY += rotationYInput * rotationSpeed;
                //    // 对上下旋转角度进行限制
                //    targetRotationX = Mathf.Clamp(targetRotationX, minVerticalAngle, maxVerticalAngle);
                //    // 根据旋转角度更新摄像机的欧拉角,Quaternion.Lerp可以使摄像机旋转更加平滑
                //    Quaternion targetRotation = Quaternion.Euler(targetRotationX, targetRotationY, 0f);
                //    transform.rotation = Quaternion.Lerp(transform.rotation, targetRotation, lerpSpeed * Time.deltaTime);
                //}

            }

            moveInput = ClampVector3(target.transform.position, aroundPosBounds.min, aroundPosBounds.max);
            target.transform.position = moveInput;
        }

        public Vector3 ClampVector3(Vector3 v, Vector3 min, Vector3 max)
        {
            v.x = Mathf.Clamp(v.x, min.x, max.x);
            v.y = Mathf.Clamp(v.y, min.y, max.y);
            v.z = Mathf.Clamp(v.z, min.z, max.z);
            return v;
        }


        private Vector3 moveInput;
        private void Move()
        {
            if (Input.GetKey(KeyCode.UpArrow) || Input.GetKey(KeyCode.W))
            {
                transform.Translate(Vector3.forward * Time.deltaTime * speed);
            }

            if (Input.GetKey(KeyCode.DownArrow) || Input.GetKey(KeyCode.S))
            {
                transform.Translate(Vector3.back * Time.deltaTime * speed);
            }

            if (Input.GetKey(KeyCode.LeftArrow) || Input.GetKey(KeyCode.A))
            {
                transform.Translate(Vector3.left * Time.deltaTime * speed);
            }

            if (Input.GetKey(KeyCode.RightArrow) || Input.GetKey(KeyCode.D))
            {
                transform.Translate(Vector3.right * Time.deltaTime * speed);
            }

            if (Input.GetKey(KeyCode.E))
            {
                transform.Translate(Vector3.up * Time.deltaTime * speed);
            }

            if (Input.GetKey(KeyCode.Q))
            {
                transform.Translate(Vector3.down * Time.deltaTime * speed);
            }

            /*Vector3 vertMove = transform.forward * Input.GetAxis("Vertical");
            Vector3 horiMove = transform.right * Input.GetAxis("Horizontal");
            moveInput = vertMove + horiMove;
            moveInput.Normalize();
            transform.Translate(moveInput * Time.deltaTime * speed);*/
        }

        private void Rotate()
        {
            Vector2 mouseInput = new Vector2(Input.GetAxisRaw("Mouse X"), Input.GetAxisRaw("Mouse Y")) * sensitivity;
            transform.rotation = Quaternion.Euler(transform.rotation.eulerAngles.x, transform.rotation.eulerAngles.y + mouseInput.x, transform.rotation.eulerAngles.z); //水平方向旋转
            transform.rotation = Quaternion.Euler(transform.rotation.eulerAngles + new Vector3(-mouseInput.y, 0f, 0f));//摄像头垂直旋转
        }
    }

总结

以上就是今天要讲的内容,本文仅仅简单介绍了摄像机画面的控制及镜头复位,对于简单的功能制作比较有帮助。

  • 5
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值