Unity implements the mouse to control the rotation and scaling of the camera around the center point

illustrate

  Implemented a functional script, which is convenient for the camera to rotate and zoom around an object, and the way to use it is also very simple, mount the script to the main camera. [ Unity Android side gestures to control the rotation and zoom of the camera ]

DoTweenThe plug-ins and plug-ins   used here also UniRxneed to be imported. If you don’t want to use the plug-ins, you can simply modify the following code.

using UnityEngine;
using DG.Tweening;
using UnityEngine.EventSystems;
using QFramework;
using UniRx;
using UniRx.Triggers;

/// <summary>
/// 摄像机控制管理
/// </summary>
public class CameraController : MonoBehaviour
{
    
    
    static CameraController _instance;
    public static CameraController Ins
    {
    
    
        get {
    
     return _instance; }
    }

    Transform cam_TF;

    // 是否可以控制摄像机
    public bool isCanControlCam = true;

    [Header("旋转的目标点:")]
    public Transform rotTarget;

    [Header("相机点击UI前进和返回的速度")]
    public float cameraMoveSpeed = 400f;

    [Header("旋转速度和缩放速度:")]
    public float rotateSpeed = 1.25f;
    public float wheelSpeed = 100f;

    [Header("摄像机的最远距离和最近距离:")]
    public float minDist = 3;
    public float maxDist = 60;

    [Header("最大俯仰角:")]
    public float maxAngle;
    [Header("最小俯仰角:")]
    public float minAngle;

    // 当前摄像机俯仰角
    public float nowCamEulerX;

    Vector3 initPos;

    void Awake()
    {
    
    
        _instance = this;
        cam_TF = Camera.main.transform;
    }

    void Start()
    {
    
    
        cam_TF.LookAt(rotTarget);
        initPos = cam_TF.localPosition;
        nowCamEulerX = cam_TF.localEulerAngles.x;
		this.LateUpdateAsObservable().Subscribe(_ => {
    
    
            if (!isCanControlCam)
                return;

            CameraRotate();
            CameraFOV();
        });
    }
    /// <summary>
    /// 摄像机的初始位置
    ///可供外部调用 使摄像机位置初始化
    /// </summary>
    public void CamMoveInitPos()
    {
    
    
        if (!isCanControlCam)
            return;

        this.Sequence()
            .Event(() =>
            {
    
    
                isCanControlCam = false;
                mouseLerpPos = Vector2.zero;
                cam_TF.DORotate(new Vector3(25, -44, 0), 1f);
                cam_TF.DOMove(initPos, 1f);
            })
            .Delay(1.05f)
            .Event(() =>
            {
    
    
                isCanControlCam = true;
                nowCamEulerX = cam_TF.localEulerAngles.x;
            })
            .Begin();
    }

    #region 鼠标操作
    Vector2 mousePos;
    Vector2 mouseLerpPos;

    /// <summary>
    /// 摄像机旋转
    /// </summary>
    void CameraRotate()
    {
    
    
        mousePos.x = Input.GetAxis("Mouse X");
        mousePos.y = Input.GetAxis("Mouse Y");

        if (Input.GetMouseButton(0) && !EventSystem.current.IsPointerOverGameObject())
        {
    
    
            mouseLerpPos.x = Mathf.Lerp(mouseLerpPos.x, mousePos.x, 5 * Time.deltaTime);
            mouseLerpPos.y = Mathf.Lerp(mouseLerpPos.y, mousePos.y, 5 * Time.deltaTime);
        }
        else
        {
    
    
            mouseLerpPos.x = Mathf.Lerp(mouseLerpPos.x, 0, 5 * Time.deltaTime);
            mouseLerpPos.y = Mathf.Lerp(mouseLerpPos.y, 0, 5 * Time.deltaTime);
        }
        cam_TF.RotateAround(rotTarget.position, Vector3.up, mouseLerpPos.x * rotateSpeed);

        nowCamEulerX -= mouseLerpPos.y * rotateSpeed;

        if (nowCamEulerX > maxAngle || nowCamEulerX < minAngle)
        {
    
    
            nowCamEulerX += mouseLerpPos.y * rotateSpeed;

            mouseLerpPos.y = 0;
            return;
        }

        if (Mathf.Abs(-mouseLerpPos.y * rotateSpeed) < 0.02f)
            return;

        cam_TF.RotateAround(rotTarget.position, cam_TF.right, -mouseLerpPos.y * rotateSpeed * 0.5f);
    }

    float wheelValue;
    float wheelTargetValue;
    /// <summary>
    /// 摄像机缩放
    /// </summary>
    void CameraFOV()
    {
    
    
        wheelValue = Input.GetAxis("Mouse ScrollWheel");

        if (Vector3.Distance(cam_TF.position, rotTarget.position) < minDist && wheelValue > 0)
        {
    
    
            return;
        }

        if (Vector3.Distance(cam_TF.position, rotTarget.position) > maxDist && wheelValue < 0)
        {
    
    
            return;
        }

        if (wheelValue > 0)
            wheelValue = 0.15f;

        if (wheelValue < 0)
            wheelValue = -0.15f;

        wheelTargetValue = Mathf.Lerp(wheelTargetValue, wheelValue, 5 * Time.deltaTime);

        cam_TF.Translate(Vector3.forward * wheelTargetValue * wheelSpeed);
    }

    #endregion
}

Guess you like

Origin blog.csdn.net/weixin_44446603/article/details/119146088