unity摄像机围绕屏幕中心旋转,平移,缩放

很好用所以保存下来使用

直接附代码了

3D摄像机的

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

public class Camera3DMove : MonoBehaviour
{
    //摄像机绕屏幕中心旋转缩放平移脚本
    public float thetaSpeed = 150.0f; //x旋转速度
    public float phiSpeed = 150.0f; //垂直旋转速度
    public float moveSpeed = 10.0f; //平移速度
    public float zoomSpeed = 10.0f; //缩放速度

    public float phiBoundMin = -89f;  //最低垂直旋转角度
    public float phiBoundMax = 89f; //最高垂直旋转角度

    //缩放距离限制 最小,最大
    public Vector2 distanceLimit = new Vector2(2f, 30f);

    //旋转平滑
    public float rotateSmoothing = 0.5f;
    //移动平滑
    public float moveSmoothing = 0.7f;

    //当前距离
    public float distance = 15.0f;

    //摄像机的初始角度
    private Vector2 euler;

    //目标旋转角度
    public Quaternion targetRot;
    //当前朝向的目标
    private Vector3 targetLookAt;
    //当前摄像机到目标的距离
    public float targetDist;

    //临时变量
    private Vector3 distanceVec = new Vector3(0, 0, 0);

    //目标对象的变换
    public Transform target;

    //中心点
    public Vector3 pivotPoint = new Vector3(0, 0, 0);

  

    //限制鼠标范围 避免点击抖动
    private Vector2 limitMouseX = new Vector2(-5, 5);
    private Vector2 limitMouseY = new Vector2(-5, 5);

    //目标位置
    public Vector3 targetPos;

    public void Start()
    {
        //获取当前摄像机的角度
        Vector3 angles = transform.eulerAngles;
        euler.x = angles.y;
        euler.y = angles.x;
        //unity only returns positive euler angles but we need them in -90 to 90
        euler.y = Mathf.Repeat(euler.y + 180f, 360f) - 180f;

        //创建目标物体
        GameObject go = new GameObject("_CameraTarget");
        //设置隐藏并不保存
        go.hideFlags = HideFlags.HideAndDontSave | HideFlags.HideInInspector;

        //设置初始参数
        target = go.transform; //设置目标

        target.position = pivotPoint; //设置中心点为其实目标位置
        targetDist = (transform.position - target.position).magnitude; //获取相机到中心点的距离

        targetRot = transform.rotation; //设置目标旋转角度
        targetLookAt = target.position; //设置朝向的目标所在位置

    
    }
    public void Update()
    {                        
            //获取鼠标在屏幕的x.y值
            float dx = Input.GetAxis("Mouse X");
            float dy = Input.GetAxis("Mouse Y");

            //鼠标偏移量限制,防止抖动
            if (dx < limitMouseX.x || dx > limitMouseX.y)
            {              
                return;
            }

            if (dy < limitMouseY.x || dy > limitMouseY.y)
            {               
                return;
            }

            if (Input.GetMouseButton(2))
            {
                //计算移动量
                dx = dx * moveSpeed * 0.005f * targetDist;
                dy = dy * moveSpeed * 0.005f * targetDist;
                targetLookAt -= transform.up * dy + transform.right * dx;            
            }

            else if (Input.GetMouseButton(1))
            {
                //计算旋转角度
                dx = dx * thetaSpeed * 0.02f;
                dy = dy * phiSpeed * 0.02f;
                euler.x += dx;
                euler.y -= dy;
                //限制垂直旋转角度
                euler.y = ClampAngle(euler.y, phiBoundMin, phiBoundMax);
                targetRot = Quaternion.Euler(euler.y, euler.x, 0);
            }

            //当前摄像机到目标的距离 减鼠标滑动距离
            targetDist -= Input.GetAxis("Mouse ScrollWheel") * zoomSpeed;
            //限制缩放
            targetDist = Mathf.Clamp(targetDist, distanceLimit.x, distanceLimit.y);

        
    }

    public void FixedUpdate()
    {   
        //计算距离
        distance = moveSmoothing * targetDist + (1 - moveSmoothing) * distance;
        //计算旋转角度插值
        transform.rotation = Quaternion.Slerp(transform.rotation, targetRot, rotateSmoothing);

        //计算距离插值
        target.position = Vector3.Lerp(target.position, targetLookAt, moveSmoothing);

        //设置距离 Z轴
        distanceVec.z = distance;
        //设置相机最终的位置  目标位置 - 相机当前旋转角度 * 距离Z轴
        transform.position = target.position - transform.rotation * distanceVec;
    }

    /// <summary>
    /// 限制角度
    /// </summary>
    /// <param name="angle"></param>
    /// <param name="min"></param>
    /// <param name="max"></param>
    /// <returns></returns>
    static float ClampAngle(float angle, float min, float max)
    {
        if (angle < -360f) angle += 360f;
        if (angle > 360f) angle -= 360f;
        return Mathf.Clamp(angle, min, max);
    }

}
摄像机脚本

在加一个2D摄像机的项目需要就一起记录下喽,不喜勿怪哦,

using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class Camera2DMove : MonoBehaviour
{
    private Camera camera2D;

    public float rotation_H_speed =10 ;    //水平速度
    public float rotation_V_speed =10 ;    //垂直速度
    public float sizeMin = 5f, sizeMax = 20f;  //2D摄像机的最小最大距离
    private float floatDistance;  //临时的距离
    // Start is called before the first frame update
    void Start()
    {
        camera2D = this.GetComponent<Camera>();
        floatDistance = camera2D.orthographicSize;
    }
    // Update is called once per frame
    void Update()
    {
        if (camera2D.enabled)
        {
            if (Input.GetMouseButton (2))
            {
             
              this.transform.Translate(new Vector3(-Input.GetAxis("Mouse X") * rotation_H_speed*Time.deltaTime, -Input.GetAxis("Mouse Y") * rotation_V_speed*Time.deltaTime, 0f));

            }
            else if (Input.GetAxis("Mouse ScrollWheel")!=0)
            {
                floatDistance -= Input.GetAxis("Mouse ScrollWheel") * 5f;
                floatDistance = Mathf.Clamp(floatDistance, sizeMin, sizeMax);
                camera2D.orthographicSize = floatDistance; 
            }
        }
    }
}
2D摄像机平移

再加一个好用的相机移动,包含(中键移动,左键自身旋转,右键绕点旋转)

using UnityEngine;
using System.Collections;
using UnityEngine.EventSystems;
using System;

[AddComponentMenu("Camera-Control/专用摄像机脚本")]
public class MaxCamera : MonoBehaviour
{
    [Header("上下移动的开关")]
    public bool QEBOL;
    [HideInInspector]
    public Transform target;
    public Vector3 targetOffset;
    [Header("旋转点距离相机的距离")]
    public float distance = 20.0f;   
    [Header("摄像机上下旋转速度")]
    public float xSpeed = 200.0f;
    [Header("摄像机左右旋转速度")]
    public float ySpeed = 200.0f;
    [Header("摄像机俯视角度")]
    public int yMinLimit = -80;
    [Header("摄像机仰视角度")]
    public int yMaxLimit = 80;
    [Header("摄像机镜头拉近速度")]
    public int zoomRate = 200;
    [Header("摄像机旋转速度")]
    public float zoomDampening = 50.0f;
    [Header("摄像机鼠标中键移动速度")]
    public float transpeed = 0.005f;
    [Header("摄像机键盘移动速度")]
    public float jpSpeed = 50f;

    [Header("摄像机上升和下降移动速度")]
    public float ssxjSpeed = 4f;
  
    public LayerMask layerMask = -1;
 
    private float xDeg = 0.0f;
    private float yDeg = 0.0f;
    private float currentDistance;
    [HideInInspector]
    public float desiredDistance;
    private Quaternion currentRotation;
    private Quaternion desiredRotation;
    private Quaternion rotation;
    private Vector3 position;
    private float pinchdistance = 0;
    private bool zhjbool = false;

    private EventSystem eventsystem;
    public Camera mainCamera;

    void Start() 
    {
        eventsystem = FindObjectOfType<EventSystem>() as EventSystem;
        Init(); 
    }
    void OnEnable()
    {
        Init();
    }
    /// <summary>
    /// 模型定位移动旋转 用Dotween需要自己修改
    /// </summary>
    public void ModelMove(Vector3 pos_,Quaternion quater_)
    {
        TagetingDistace(0);
        target.position = pos_;
        mainCamera.transform.rotation = quater_;
        ChongZhiRotation(quater_);
    }
    //设置位置
    public void TagetingDistace(float distance_)
    {
        if (target != null)
        {
            target.position = transform.position + (transform.forward * distance_);
            distance = Vector3.Distance(transform.position, target.position);
            currentDistance = distance;
            desiredDistance = distance;
        }

    }
    //重置旋转角度
    public void ChongZhiRotation(Quaternion quaternion)
    {
        position = transform.position;
        rotation = quaternion;
        currentRotation = quaternion;
        desiredRotation = quaternion;
        Vector3 cross = Vector3.Cross(Vector3.right, transform.right);
        xDeg = Vector3.Angle(Vector3.right, transform.right);
        if (cross.y < 0) xDeg = 360 - xDeg;
        yDeg = Vector3.Angle(Vector3.up, transform.up);

        transform.rotation = rotation;
        target.rotation = transform.rotation;
    }
    public void Init()
    {     
        if (!target)
        {
            GameObject go = new GameObject("CamTarget");
            go.transform.position = transform.position + (transform.forward * distance);
            target = go.transform;         
        }
        distance = Vector3.Distance(transform.position, target.position);
        currentDistance = distance;
        desiredDistance = distance;
              
        position = transform.position;
        rotation = transform.rotation;
        currentRotation = transform.rotation;
        desiredRotation = transform.rotation;
        Vector3 cross = Vector3.Cross(Vector3.right, transform.right);
        xDeg = Vector3.Angle(Vector3.right, transform.right );
        if (cross.y < 0) xDeg = 360 - xDeg;
        yDeg = Vector3.Angle(Vector3.up, transform.up );
    }
    void LateUpdate()
    {
        bool outsideNewGUI = true;
        if (eventsystem) outsideNewGUI = !eventsystem.IsPointerOverGameObject();
        // 获取左右方向的移动信息
        float horspeed = Input.GetAxis("Horizontal");
        // 获取前后方向的移动信息
        float verspeed = Input.GetAxis("Vertical");
        if (Input.GetMouseButton(1)&& !zhjbool)
        {
            
            if (!Input.GetMouseButtonDown(1))
            {                          
                xDeg += Input.GetAxis("Mouse X") * xSpeed * 0.02f;
                yDeg -= Input.GetAxis("Mouse Y") * ySpeed * 0.02f;              
                yDeg = ClampAngle(yDeg, yMinLimit, yMaxLimit);           
                desiredRotation = Quaternion.Euler(yDeg, xDeg, 0);

                currentRotation = transform.rotation;              
                rotation = Quaternion.Lerp(currentRotation, desiredRotation, Time.deltaTime * zoomDampening);         
                transform.rotation = rotation;
                target.rotation = transform.rotation;
            }
          
            else
            {
                RaycastHit hit;
                if (Physics.Raycast(mainCamera.transform.position, mainCamera.transform.forward, out hit))
                {
                    float dist = Vector3.Distance(mainCamera.transform.position, hit.point);
                    TagetingDistace(dist);
                }
                else
                {
                    TagetingDistace(20);
                }
                if (Input.touchCount > 1) pinchdistance = Vector2.Distance(Input.touches[0].position, Input.touches[1].position);
            }

        }
        else if (Input.GetMouseButton(0) && !zhjbool)
        {
            if (!Input.GetMouseButtonDown(0))
            {               
                xDeg += Input.GetAxis("Mouse X") * xSpeed * 0.02f;
                yDeg -= Input.GetAxis("Mouse Y") * ySpeed * 0.02f;                           
                yDeg = ClampAngle(yDeg, yMinLimit, yMaxLimit);            
                desiredRotation = Quaternion.Euler(yDeg, xDeg, 0);

                currentRotation = transform.rotation;
                rotation = Quaternion.Lerp(currentRotation, desiredRotation, Time.deltaTime * zoomDampening);
                transform.rotation = rotation;
                target.rotation = transform.rotation;
            }
            else
            {
                TagetingDistace(0);
                if (Input.touchCount > 1) pinchdistance = Vector2.Distance(Input.touches[0].position, Input.touches[1].position);
            }
        }
        else if (Input.GetMouseButtonDown(2))
        {      
            StartCoroutine(DragTarget(Input.mousePosition));          
        }

        if (Input.GetKey(KeyCode.Q)&&QEBOL)
        {
            target.Translate(Vector3.up * Time.deltaTime * ssxjSpeed, Space.World);
            //target.transform.position = new Vector3(target.transform.position.x, Mathf.Clamp(target.transform.position.y, 0.1f, 10),
            //    target.transform.position.z);
        }
        else if (Input.GetKey(KeyCode.E)&& QEBOL)
        {
            target.Translate(Vector3.down * Time.deltaTime * ssxjSpeed, Space.World);
            //target.transform.position = new Vector3(target.transform.position.x, Mathf.Clamp(target.transform.position.y, 0.1f, 10),
            //   target.transform.position.z);
        }

        if (Input.GetAxis("Mouse ScrollWheel") < 0)
        {
            target.Translate(Vector3.back * zoomRate * Time.deltaTime);
            position = target.position - (rotation * Vector3.forward * currentDistance + targetOffset);
            transform.position = position;           
        }
        else if (Input.GetAxis("Mouse ScrollWheel") > 0)
        {
            target.Translate(Vector3.forward * zoomRate * Time.deltaTime);
            position = target.position - (rotation * Vector3.forward * currentDistance + targetOffset);
            transform.position = position;
        }
      


        //键盘移动
        KeyTranslation();

    }
    //摄像机移动功能
    IEnumerator DragTarget(Vector3 startingHit)
    {
        Vector3 startTargetPos = target.position;     
        while (Input.GetMouseButton(2))
        {
            Vector3 mouseMove = 1f*transpeed * transform.position.y * (Input.mousePosition - startingHit);          
            Vector3 zDir = transform.forward;
            zDir.y = 0;
            target.position = startTargetPos - transform.right * mouseMove.x - zDir.normalized * mouseMove.y;
            position = target.position - (rotation * Vector3.forward * currentDistance + targetOffset);
            transform.position = position;
            yield return null;
        }      
    }

    //键盘控制移动
    void KeyTranslation()
    //平移控制
    {
        float moveX = Input.GetAxis("Horizontal") * Time.deltaTime * 2;
        float moveY = Input.GetAxis("Vertical") * Time.deltaTime * 2;
        //if (moveX == 0 && moveY == 0)
        //{
        //    return;
        //}
        //自身坐标的z轴投影到世界坐标的z轴,用自身坐标的y轴和z轴的值乘 自身的相对欧拉角的x的三角函数。
        float tranY = moveY * (float)Math.Sin(Math.Round(target.localRotation.eulerAngles.x, 2) * Math.PI / 180.0);
        float tranZ = moveY * (float)Math.Cos(Math.Round(target.localRotation.eulerAngles.x, 2) * Math.PI / 180.0);
        target.Translate(new Vector3(moveX, tranY, tranZ) * jpSpeed * 0.1f, Space.Self);
        position = target.position - (rotation * Vector3.forward * currentDistance + targetOffset);
        transform.position = position;
    }
    //角度限制
    private 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);
    }
}
3D摄像机使用脚本

 

有需要可以用哦,喜欢点个赞呗

posted @ 2023-03-20 15:48  剑起苍穹  阅读(388)  评论(0编辑  收藏  举报
/*鼠标点击特效*/