【Unity】PC端:缩放、移动画面


前言

  本文章内容适用于PC端UCUI,通过鼠标移动与滑动滚轮,进行正交摄像机的移动与缩放。


一、前置修改

1.修改Canvas

请添加图片描述

1)分离Canvas
 将UI按照是否跟随摄像机移动分离到多个Canvas。

2)修改RenderMode
 不跟随摄像机移动的Canvas设置为WorldSpace。(仅此项,Canvas不会跟随摄像机移动)
 跟随摄像机移动的Canvas设置为其它选项。

3)修改Scale
 RenderMode设置为WorldSpace,需要修改Scale为0.01

4)修改order in Layer
 该数值越大,显示越靠上,按需调整即可。

2.修改Camera

请添加图片描述
  正交摄像机的视口大小Size 的含义:输出的游戏画面的高度对应 2* size 个 Unity 单位。(一个单位通常为100个像素)


二、代码实现

1.缩放

代码如下:

 private void ZoomCamera()
    {
        float zoomValue = Input.GetAxis("Mouse ScrollWheel");
        if (zoomValue != 0)
        {
            NowSize = Camera.main.orthographicSize + zoomValue * ZoomSpeed;
            NowSize = Mathf.Min(NowSize, MaxScale);
            NowSize = Mathf.Max(NowSize, MinScale);

            Camera.main.orthographicSize = NowSize;        
        }
    }

2.移动

代码如下:

private void MoveCamera()
    {
        float moveX = 0, moveY = 0;

        float x = Input.mousePosition.x;
        float y = Input.mousePosition.y;

        if (x < JudgeX)//判断鼠标水平方向 是否进入移动判定区域
        {
            moveX = -MoveX;
        }
        else if (x > ScreenSize.x - JudgeX)
        {
            moveX = MoveX;
        }
        else
        {
            moveX = 0;
        }

        if (y < JudgeY)//判断鼠标垂直方向 是否进入移动判定区域
        {
            moveY = -MoveY;
        }
        else if (y > ScreenSize.y - JudgeY)
        {
            moveY = MoveY;
        }
        else
        {
            moveY = 0;
        }

        Vector3 endPos = Return_EndPos(moveX, moveY);//摄像机应移动距离
   
        this.transform.position = Vector3.Lerp(this.transform.position, endPos, MoveSpeed * Time.deltaTime);//插值移动,避免显示卡顿       
    }

    private Vector3 Return_EndPos(float moveX, float moveY)
    {
        float endX = moveX + this.transform.position.x;
        float endY = moveY + this.transform.position.y;

        float zoomScale = (NowSize - MinScale) / (MaxScale - MinScale);//当前缩放比例 处于 最小缩放比例与最大缩放比例中的 位置

        endX = Mathf.Min(Mathf.Max(MinX + zoomScale * JudgePosX, endX), MaxX - zoomScale * JudgePosX);
        endY = Mathf.Min(Mathf.Max(MinY + zoomScale * JudgePosY, endY), MaxY - zoomScale * JudgePosY);//将摄像机最终位置,调整为极限位置内
        Vector3 endPos = new Vector3(endX, endY, 0);

        return endPos;
    }

3.总览

代码如下:

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

public class MoveAndZoomCamera : MonoBehaviour {
    [Header("缩放")]
    public float ZoomSpeed = 5;

    private float MinScale = 5.4f;
    private float MaxScale = 10.8f;
    private float NowSize = 5.4f;

    [Header("移动")]
    public float JudgeX = 5f;
    public float MoveX = 5f;

    public float JudgeY = 5f;
    public float MoveY = 5f;
    public float MoveSpeed = 1;

    private Vector3 StartPos = new Vector3(0, 0, 0);
    private Vector2 ScreenSize = new Vector2(1920, 1080);
    private Vector2 BgSize = new Vector2(3840, 2160);

    private float MinX, MinY, MaxX, MaxY;
    private bool IsZoom = false;

    private float JudgePosX, JudgePosY;

    private void Start()
    {
        this.transform.position = StartPos;


        MinX = -(BgSize.x - ScreenSize.x) / 2 / 100;
        MaxX = (BgSize.x - ScreenSize.x) / 2 / 100;
        MinY = -(BgSize.y - ScreenSize.y) / 2 / 100;
        MaxY = (BgSize.y - ScreenSize.y) / 2 / 100;//最小缩放比例下 摄像机紧贴背景上下左右边缘时 的坐标 

        JudgePosX = (MaxScale - MinScale) / ScreenSize.y * ScreenSize.x;
        JudgePosY = MaxScale - MinScale;//最小缩放比例 与 最大缩放比例 摄像机可移动距离 
    }

    private void Update()
    {
        ZoomCamera();
        MoveCamera();
    }

    private void ZoomCamera()
    {
        float zoomValue = Input.GetAxis("Mouse ScrollWheel");
        if (zoomValue != 0)//判断是否滑动 鼠标滑轮
        {
            NowSize = Camera.main.orthographicSize + zoomValue * ZoomSpeed;
            NowSize = Mathf.Min(NowSize, MaxScale);
            NowSize = Mathf.Max(NowSize, MinScale);

            Camera.main.orthographicSize = NowSize;
            IsZoom = true;//正在缩放
        }
        else
        {
            IsZoom = false;//当前未缩放
        }
    }

    private void MoveCamera()
    {
        float moveX = 0, moveY = 0;

        float x = Input.mousePosition.x;
        float y = Input.mousePosition.y;

        if (x < JudgeX)//判断鼠标水平方向上 是否进入移动判定区域
        {
            moveX = -MoveX;
        }
        else if (x > ScreenSize.x - JudgeX)
        {
            moveX = MoveX;
        }
        else
        {
            moveX = 0;
        }

        if (y < JudgeY)//判断鼠标垂直方向上 是否进入移动判定区域
        {
            moveY = -MoveY;
        }
        else if (y > ScreenSize.y - JudgeY)
        {
            moveY = MoveY;
        }
        else
        {
            moveY = 0;
        }

        Vector3 endPos = Return_EndPos(moveX, moveY);//摄像机应移动距离

        if (IsZoom)//当前处于缩放状态
        {
            this.transform.position = endPos;//直接调整位置,避免显示背景之外的区域
        }
        else
        {
            this.transform.position = Vector3.Lerp(this.transform.position, endPos, MoveSpeed * Time.deltaTime);//插值移动,避免显示卡顿
        }
    }

    private Vector3 Return_EndPos(float moveX, float moveY)
    {
        float endX = moveX + this.transform.position.x;
        float endY = moveY + this.transform.position.y;

        float zoomScale = (NowSize - MinScale) / (MaxScale - MinScale);//当前缩放比例 处于 最小缩放比例与最大缩放比例中的 位置

        endX = Mathf.Min(Mathf.Max(MinX + zoomScale * JudgePosX, endX), MaxX - zoomScale * JudgePosX);
        endY = Mathf.Min(Mathf.Max(MinY + zoomScale * JudgePosY, endY), MaxY - zoomScale * JudgePosY);//将摄像机最终位置,调整为极限位置内
        Vector3 endPos = new Vector3(endX, endY, 0);

        return endPos;
    }
}


参考

Unity Camera详述

Unity 单位和图片像素关系

Unity 鼠标滚轮放大缩小

Unity Vector3.Lerp()方法的理解

Unity 实现放大缩小以及相机位置平移实现拖拽效果

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值