jjzjj

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

凋零叶子 2024-07-29 原文

文章目录


前言

  本文章内容适用于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 实现放大缩小以及相机位置平移实现拖拽效果

有关【Unity】PC端:缩放、移动画面的更多相关文章

  1. ruby - 在 Ruby 程序执行时阻止 Windows 7 PC 进入休眠状态 - 2

    我需要在客户计算机上运行Ruby应用程序。通常需要几天才能完成(复制大备份文件)。问题是如果启用sleep,它会中断应用程序。否则,计算机将持续运行数周,直到我下次访问为止。有什么方法可以防止执行期间休眠并让Windows在执行后休眠吗?欢迎任何疯狂的想法;-) 最佳答案 Here建议使用SetThreadExecutionStateWinAPI函数,使应用程序能够通知系统它正在使用中,从而防止系统在应用程序运行时进入休眠状态或关闭显示。像这样的东西:require'Win32API'ES_AWAYMODE_REQUIRED=0x0

  2. ruby - 多次弹出/移动 ruby​​ 数组 - 2

    我的代码目前看起来像这样numbers=[1,2,3,4,5]defpop_threepop=[]3.times{pop有没有办法在一行中完成pop_three方法中的内容?我基本上想做类似numbers.slice(0,3)的事情,但要删除切片中的数组项。嗯...嗯,我想我刚刚意识到我可以试试slice! 最佳答案 是numbers.pop(3)或者numbers.shift(3)如果你想要另一边。 关于ruby-多次弹出/移动ruby​​数组,我们在StackOverflow上找到一

  3. ruby-on-rails - 如何重命名或移动 Rails 的 README_FOR_APP - 2

    当我在我的Rails应用程序根目录中运行rakedoc:app时,API文档是使用/doc/README_FOR_APP作为主页生成的。我想向该文件添加.rdoc扩展名,以便它在GitHub上正确呈现。更好的是,我想将它移动到应用程序根目录(/README.rdoc)。有没有办法通过修改包含的rake/rdoctask任务在我的Rakefile中执行此操作?是否有某个地方可以查找可以修改的主页文件的名称?还是我必须编写一个新的Rake任务?额外的问题:Rails应用程序的两个单独文件/README和/doc/README_FOR_APP背后的逻辑是什么?为什么不只有一个?

  4. Unity 热更新技术 | (三) Lua语言基本介绍及下载安装 - 2

    ?博客主页:https://xiaoy.blog.csdn.net?本文由呆呆敲代码的小Y原创,首发于CSDN??学习专栏推荐:Unity系统学习专栏?游戏制作专栏推荐:游戏制作?Unity实战100例专栏推荐:Unity实战100例教程?欢迎点赞?收藏⭐留言?如有错误敬请指正!?未来很长,值得我们全力奔赴更美好的生活✨------------------❤️分割线❤️-------------------------

  5. FOHEART H1数据手套驱动Optitrack光学动捕双手运动(Unity3D) - 2

    本教程将在Unity3D中混合Optitrack与数据手套的数据流,在人体运动的基础上,添加双手手指部分的运动。双手手背的角度仍由Optitrack提供,数据手套提供双手手指的角度。 01  客户端软件分别安装MotiveBody与MotionVenus并校准人体与数据手套。MotiveBodyMotionVenus数据手套使用、校准流程参照:https://gitee.com/foheart_1/foheart-h1-data-summary.git02  数据转发打开MotiveBody软件的Streaming,开始向Unity3D广播数据;MotionVenus中设置->选项选择Unit

  6. unity---接入Admob - 2

    目录1.AdmobSDK下载地址2.将下载好的unityPackagesdk导入到unity里​编辑 3.解析依赖到项目中

  7. Unity 3D 制作开关门动画,旋转门制作,推拉门制作,门把手动画制作 - 2

    Unity自动旋转动画1.开门需要门把手先动,门再动2.关门需要门先动,门把手再动3.中途播放过程中不可以再次进行操作觉得太复杂?查看我的文章开关门简易进阶版效果:如果这个门可以直接打开的话,就不需要放置"门把手"如果门把手还有钥匙需要旋转,那就可以把钥匙放在门把手的"门把手",理论上是可以无限套娃的可调整参数有:角度,反向,轴向,速度运行时点击Test进行测试自己写的代码比较垃圾,命名与结构比较拉,高手轻点喷,新手有类似的需求可以拿去做参考上代码usingSystem.Collections;usingSystem.Collections.Generic;usingUnityEngine;u

  8. ruby-on-rails - rbenv:从 RVM 移动到 rbenv 后,在 Jenkins 执行 shell 中找不到命令 - 2

    我从Ubuntu服务器上的RVM转移到rbenv。当我使用RVM时,使用bundle没有问题。转移到rbenv后,我在Jenkins的执行shell中收到“找不到命令”错误。我内爆并删除了RVM,并从~/.bashrc'中删除了所有与RVM相关的行。使用后我仍然收到此错误:rvmimploderm~/.rvm-rfrm~/.rvmrcgeminstallbundlerecho'exportPATH="$HOME/.rbenv/bin:$PATH"'>>~/.bashrcecho'eval"$(rbenvinit-)"'>>~/.bashrc.~/.bashrcrbenvversions

  9. Unity Shader 学习笔记(5)Shader变体、Shader属性定义技巧、自定义材质面板 - 2

    写在之前Shader变体、Shader属性定义技巧、自定义材质面板,这三个知识点任何一个单拿出来都是一套知识体系,不能一概而论,本文章目的在于将学习和实际工作中遇见的问题进行总结,类似于网络笔记之用,方便后续回顾查看,如有以偏概全、不祥不尽之处,还望海涵。1、Shader变体先看一段代码......Properties{ [KeywordEnum(on,off)]USL_USE_COL("IsUseColorMixTex?",int)=0 [Toggle(IS_RED_ON)]_IsRed("IsRed?",int)=0}......//中间省略,后续会有完整代码 #pragmamulti_c

  10. 三分钟集成 TapTap 防沉迷 SDK(Unity 版) - 2

    三分钟集成Tap防沉迷SDK(Unity版)一、SDK介绍基于国家对上线所有游戏必须增加防沉迷功能的政策下,TapTap推出防沉迷SDK,供游戏开发者进行接入;允许未成年用户在周五、六、日以及法定节假日晚上8:00-9:00进行游戏,防沉谜时间段进入游戏会弹窗进行提示!开发环境要求:Unity2019.4或更高版本iOS10或更高版本Android5.0(APIlevel21)或更高版本🔗Unity集成Demo参考链接🔗UnityTapSDK功能体验APK下载链接二、集成前准备1.创建应用进入开发者后台,按照提示开始创建应用;2.开通服务在使用TDS实名认证和防沉迷服务之前,需要在上面创建的应

随机推荐