Unity相机围绕物体的旋转与缩放

这个是需要用的DOTween的,将此脚本挂到相机上,然后再添加相机跟随的目标即可,具体代码如下

using DG.Tweening;
using UnityEngine;

public class FollowTrackingCamera : MonoBehaviour
{
    //相机跟随目标
    public Transform target;

    //从目标到摄像机位置的曝光变量
    public float height = 20f;
    public float distance = 20f;

    //相机移动范围
    public float min = 10f;
    public float max = 60;

    //相机旋转以及缩放功能开关
    public bool doZoom;
    public bool doRotate;

    //缩放时的移动量。
    public float zoomStep = 30f;
    public float zoomSpeed = 5f;
    private float _heightWanted;
    private float _distanceWanted;

    public float xSpeed = 3.0f;
    public float ySpeed = 3.0f;

    public float smoothTime = 2f;

    private float _rotationYAxis = 230.0f;
    private float _rotationXAxis = -8.0f;

    private float _velocityX;
    private float _velocityY;

    //两根手指
    private Touch _oldTouch1;
    private Touch _oldTouch2;

    private float _scaleFactor;

    // 结果向量
    private Quaternion _rotationResult;
    private Vector3 _targetAdjustedPosition;

    public float currAngle = 45;
    public float wantedScale = 20; //想要的缩进大小

    public bool isInit;

    private void Start()
    {
        Init();
    }

    private void Init()
    {
        //得到相机欧拉角
        Vector3 angles = transform.eulerAngles;
        //相机绕Y轴转动的角度值
        _rotationYAxis = angles.y;
        //相机绕X轴转动的角度值
        _rotationXAxis = angles.x;
        print("相机初始位置" + _rotationXAxis);

        //相机当前高度赋值于目标高度
        _heightWanted = height;
        _distanceWanted = distance;
    }

    private void LateUpdate()
    {
        if (isInit)
        {
            _distanceWanted = wantedScale;
            _rotationXAxis = 25;
            DOTween.To(() => _rotationXAxis, x => _rotationXAxis = x, currAngle, 0.5f);
            _rotationYAxis = 0;
            isInit = false;
        }

        //检测目标是否存在
        if (!target)
        {
            Debug.LogError("This camera has no target, you need to assign a target in the inspector.");
            return;
        }

        //相机视角缩放
        if (doZoom)
        {
            float mouseInput;
            if (Input.touchCount > 1)
            {
                Touch newTouch1 = Input.GetTouch(0);
                Touch newTouch2 = Input.GetTouch(1);
                //第2点刚开始接触屏幕, 只记录,不做处理
                if (newTouch2.phase == TouchPhase.Began)
                {
                    _oldTouch2 = newTouch2;
                    _oldTouch1 = newTouch1;
                }

                //计算老的两点距离和新的两点间距离,变大要放大模型,变小要缩放模型
                float oldDistance = Vector2.Distance(_oldTouch1.position, _oldTouch2.position);
                float newDistance = Vector2.Distance(newTouch1.position, newTouch2.position);
                //两个距离只差,为正表示放大,为负表示缩小
                float offset = newDistance - oldDistance;
                //缩放因子
                _scaleFactor = offset / 1000f;

                mouseInput = _scaleFactor;

                _heightWanted -= zoomStep * mouseInput;
                _distanceWanted -= zoomStep * mouseInput;
            }

            //记录鼠标滚轮滚动时的变量 并赋值记录
            //mouseInput特性:正常状态为0;滚轮前推一格变为+0.1一次,后拉则变为-0.1一次
            if (Input.touchCount <= 0)
            {
                mouseInput = Input.GetAxis("Mouse ScrollWheel");

                _heightWanted -= zoomStep * mouseInput;
                _distanceWanted -= zoomStep * mouseInput;
            }

            //限制相机高度范围
            _heightWanted = Mathf.Clamp(_heightWanted, min, max);
            _distanceWanted = Mathf.Clamp(_distanceWanted, min, max);
            //差值计算,动态修改相机高度值(平滑的变化)
            height = Mathf.Lerp(height, _heightWanted, Time.deltaTime * zoomSpeed);
            distance = Mathf.Lerp(distance, _distanceWanted, Time.deltaTime * zoomSpeed);
        }

        //相机视角旋转
        if (doRotate)
        {
            if (Input.touchCount == 1)
            {
                Touch newTouch1 = Input.GetTouch(0);
                if (Input.touches[0].phase == TouchPhase.Began)
                {
                    _oldTouch1 = newTouch1;
                }

                if (Input.touches[0].phase == TouchPhase.Moved)
                {
                    float cx = newTouch1.position.x - _oldTouch1.position.x;
                    float cy = newTouch1.position.y - _oldTouch1.position.y;

                    _velocityX += xSpeed * cx * 0.02f * Time.deltaTime;
                    _velocityY += ySpeed * cy * 0.02f * Time.deltaTime;
                }
            }

            if (Input.GetMouseButton(2) || Input.GetMouseButton(0) || Input.GetMouseButton(1))
            {
                _velocityX += xSpeed * Input.GetAxis("Mouse X") * 0.02f;
                _velocityY += ySpeed * Input.GetAxis("Mouse Y") * 0.02f;
            }

            _rotationYAxis += _velocityX;
            _rotationXAxis -= _velocityY;
            if (_rotationXAxis >= 90)
            {
                _rotationXAxis = 90;
            }
            else if (_rotationXAxis <= -90)
            {
                _rotationXAxis = -90;
            }
        }

        Quaternion toRotation = Quaternion.Euler(_rotationXAxis, _rotationYAxis, 0);
        Quaternion rotation = toRotation;
        Vector3 negDistance = new Vector3(0.0f, 0.0f, -distance);
        //相机跟随
        Vector3 position = rotation * negDistance + target.position;
        //改变相机Rotation,从而旋转相机
        transform.rotation = rotation;

        //将缩放后的坐标作为相机的当前坐标位置
        transform.position = position;
        _velocityX = Mathf.Lerp(_velocityX, 0, Time.deltaTime * smoothTime);
        _velocityY = Mathf.Lerp(_velocityY, 0, Time.deltaTime * smoothTime);
    }
}
评论 18
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值