【Unity3D】摄像机适配场景以及Canvas适配
目录
宽度不变策略
高度不变策略
宽度不变策略
开发分辨率 750*1334 (宽高比:0.56)
真机分辨率 1170*2532 (宽高比:0.46)
真机宽高比<开发宽高比,采用宽度不变策略
理由:小于代表真机高度比开发高度更大,因此不需要担心高度上的遮挡,而应担心宽度的遮挡,为了避免宽度上有遮挡问题,因此保证宽度不变策略;


左图是开发分辨率下的情况(宽度和高度均正常 设计上就是如此)
右图是真机分辨率下适配后的情况,保证宽度不变(可见宽度上的绿色边缘处是紧贴着屏幕边缘),但是高度绿色边缘没有紧贴白色的UI(问题1)(下面的一行白色是UGUI UGUI紧贴着屏幕底下边缘)

不启用适配状况:若不启用摄像机适配会呈现如下图:
宽度会被遮挡一部分!因此我们要保证宽度不变
问题1(高度绿色边缘没有紧贴白色的UI)解决思路:
将整个3D场景所有元素放于一个根节点下,往下移动一定距离来紧贴白色UI
移动的相对距离是 (适配后的摄像机size - 开发时摄像机size),移动后得到如下图
注意相对的是指摄像机空间下的相对距离(Y轴,即上下位移)

如下脚本挂载摄像机下

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;public class CameraAdapt : MonoBehaviour
{//开发宽度private int width = 750;//开发高度private int height = 1334;//摄像机原始sizeprivate float cameraSize;//场景物体根节点public Transform levelTrans;//CanvasScaler组件public CanvasScaler canvasScaler;//场景物体根节点世界位置Vector3 levelWorldPos;void Start(){//记录原始大小cameraSize = GetComponent<Camera>().orthographicSize;//场景世界位置levelWorldPos = levelTrans.position;AdaptCamera();}private void AdaptCamera(){Camera camera = Camera.main;float devRate = (750f / 1334f);float nowRate = (Screen.width * 1.0f / Screen.height);Debug.Log("开发宽高比:" + devRate);Debug.Log("真机宽高比:" + nowRate);//真机宽高比 > 开发宽高比时 , 例如 0.75 > 0.56 (目前是0.56) 说明真机更倾向高度不变策略 少于时更倾向宽度不变bool useHeight = false;if (nowRate > devRate){useHeight = true; //你可尝试注释这一行来查看ipad之类的适配情况,如果依旧保持宽度不变 会发生某些场景物体可能会因高度变小而无法看到。}Debug.Log("Screen.width :" + Screen.width);Debug.Log("Screen.height :" + Screen.height);float changeRate = (width * 1.0f / height) * (Screen.height * 1.0f / Screen.width);Debug.Log(changeRate);//保证高度不变if (useHeight){//原Unity策略就是高度不变,所以不需要任何算法,直接保持原样即可(这里cameraSize就是原始size)float targetHeight = cameraSize;camera.orthographicSize = targetHeight;//修改Canvas的适配为高度不变策略canvasScaler.matchWidthOrHeight = 1;}else{//保证宽度不变float targetWidth = cameraSize * (width * 1.0f / height);camera.orthographicSize = targetWidth * (Screen.height * 1.0f / Screen.width);//修改Canvas的适配为宽度不变策略canvasScaler.matchWidthOrHeight = 0;//在宽度不变情况下,拉长高度而导致场景空白区域变多后,将场景元素向下对齐的方案//即真机摄像机单位高度值 - 开发单位高度值 = 单位高度差值float deltaHeight = camera.orthographicSize - cameraSize;Debug.Log("camera.orthographicSize:" + camera.orthographicSize + ",cameraSize:" + cameraSize + ",deltaHeight:" + deltaHeight);//重置场景根节点世界坐标levelTrans.position = levelWorldPos;//延迟3秒后再偏移,目的是为了看到这个过程是如何变化让场景向下对齐StartCoroutine(DelayToSetPos(deltaHeight));}}IEnumerator DelayToSetPos(float deltaHeight){yield return new WaitForSeconds(1f);//场景根节点世界坐标 转 位于摄像机下的局部坐标Vector3 levelLocalPos = this.transform.InverseTransformPoint(levelWorldPos);//进行高度偏移 (高度单位差) 即向下对齐levelLocalPos = new Vector3(levelLocalPos.x, levelLocalPos.y - deltaHeight, levelLocalPos.z);// 位于摄像机下的局部坐标 转 世界坐标 赋予场景根节点levelTrans.position = this.transform.TransformPoint(levelLocalPos);}// Update is called once per framevoid Update(){//按下空格即可再次适配 (可以动态改Game 分辨率 测试不同分辨率下的情况)if (Input.GetKeyDown(KeyCode.Space)){AdaptCamera();}}
}
其他场景信息:


![]()


高度不变策略
当真机宽高比 > 开发宽高比时,采用高度不变策略

主要变化就是Canvas Scaler,摄像机size是保持不变的,Unity原本就是高度不变策略。

如果不采用高度不变策略会得到如下图,高度上会有场景元素被遮挡!
注释一行即可测试

相关文章:
【Unity3D】摄像机适配场景以及Canvas适配
目录 宽度不变策略 高度不变策略 宽度不变策略 开发分辨率 750*1334 (宽高比:0.56) 真机分辨率 1170*2532 (宽高比:0.46) 真机宽高比<开发宽高比,采用宽度不变策略 理由:小于代表真机高度比开发高度更大,因此不需要担心高度上…...
盛铂科技国产SLMF315超低相位噪声频率综合器介绍
SLMF315频率综合器简介: 盛铂科技SLMF315超低相位噪声频率综合器的频率范围覆盖200MHz至15GHz。频率的最小步进仅为0.1Hz,在不考虑频率精度的情况下频率步进可达0.04Hz。SLMF315内部采用多环路设计从而获得极优秀的相位噪声特性,频率输出为1…...
一个简单的人脸识别demo
使用face_recognition和OpenCV库完成人脸检测和识别任务: # 导入必要的库 import cv2 # OpenCV库,用于图像处理 import face_recognition # 人脸识别库 import numpy as np # 数值计算库# 步骤1:加载已知人脸的图片并编码 # 加载乔布斯的…...
SpringDoc和Swagger使用
目录 一、SpringDoc 1.添加依赖 2.配置代码 配置解释 (1)springdoc.api-docs.path (2)springdoc.swagger-ui.path (3)springdoc.swagger-ui.operationsSorter (4)springdoc.…...
RestTemplate和RPC区别
RestTemplate是Spring框架中用于进行RESTful风格的HTTP请求的模板类,通常用于与外部服务进行通信。它基于HTTP协议,使用GET、POST、PUT、DELETE等HTTP方法来进行通信,传输的数据通常使用JSON或XML格式。它是一种基于资源的通信方式࿰…...
asp.net core mvc模块化开发
razor类库 新建PluginController using Microsoft.AspNetCore.Mvc;namespace RazorClassLibrary1.Controllers {public class PluginController : Controller{public IActionResult Index(){return View();}} }Views下Plugin下新建Index.cshtml {ViewBag.Title "插件页…...
第2.2节 Android Jacoco插件覆盖率采集
JaCoCo(Java Code Coverage)是一款开源的代码覆盖率分析工具,适用于Java和Android项目。它通过插桩技术统计测试过程中代码的执行情况,生成可视化报告,帮助开发者评估测试用例的有效性。在github上开源的项目ÿ…...
Vue3中router最佳封装落地
文章目录 前言一、拆分路由文件夹?二、main.ts中注册路由总结 前言 router在使用过程中如果我们直接在一个文件的一个数组中配置,最后路由越来越多会导致不易管理,我们可以将一个页面的路由配置在一个数组中最后统一导入,这样就会…...
MySQL Router被HTTP流量击穿
## MySQL Router被HTTP流量击穿 #莫名奇妙的问题,谁让客户把Router放公网呢?除了被挖矿,还能被HTTP流量攻击。 1、日志信息 rootubuntu:/mysql# terminate called after throwing an instance of ‘mysqlrouter: :URIErrorwhat(): inval…...
网络爬虫【爬虫库request】
我叫不三不四,很高兴见到大家,欢迎一起学习交流和进步 今天来讲一讲爬虫 Requests是Python的一个很实用的HTTP客户端库,完全满足如今网络爬虫的需求。与Urllib对比,Requests不仅具备Urllib的全部功能;在开发使用上&…...
如何使用jenv工具管理多个JDK版本
一、jenv到底是干啥的? 简单来说,jenv就是专门用来管理多个Java版本的工具。不管是开发、测试,还是生产环境,只要你需要在同一台机器上用不同的Java版本,它都能帮上大忙。比如说,项目A要求JDK 8࿰…...
如何彻底解决Docker Desktop中Kubernetes无法启动问题
我们时常会遇到Kubernetes启动提示如下报错信息: {"message":"starting kubernetes: pulling images: pulling from host: pulling tag \"registry.k8s.io/etcd:3.5.16-0\": Error response from daemon: .Log in with your Docker ID or…...
aws(学习笔记第三十四课) dockerized-app with asg-alb
aws(学习笔记第三十四课) dockerized-app with asg-alb 使用cdk生成dockerized-app并使用AutoScalingGroup和ApplicationLoaderBalancer 学习内容: 使用cdk生成dockerized-app并使用AutoScalingGroup和ApplicationLoaderBalancer在AutoScalingGroup中使用efs以及R…...
嵌入式c学习七
c语言指针:程序需要载入内存中运行,在32bit系统中内存地址的范围是:0x0000 0000-0xFFFF FFFF,内存大小为4GB,内存地址指的是内存单元的编号是固定的,本身就是一个整数,对于32bit系统,…...
Selenium Web UI自动化测试:从入门到实战
引言 在当今快速迭代的软件开发周期中,自动化测试已成为保障产品质量、提升测试效率的核心手段之一。而针对Web应用的UI自动化测试,Selenium作为最流行的开源工具之一,凭借其跨浏览器、多语言支持(Python、Java、C#等)…...
【实战指南】用MongoDB存储文档和图片等大文件(Java实现)
一、前言 在现代应用开发中,经常需要处理和存储大量的文档、图片等大文件。传统的关系型数据库在处理这类大文件时,往往会面临性能瓶颈、存储成本高等问题。而 MongoDB 作为一款流行的 NoSQL 数据库,提供了 GridFS 规范,能够很好地解决大文件存储的问题。GridFS 可以将大文…...
Jetpack Compose 显示时间
Jetpack Compose 显示时间 介绍主体代码使用 介绍 在软件中实时显示时间 主体代码 import androidx.compose.runtime.Composable import androidx.compose.runtime.DisposableEffect import androidx.compose.runtime.getValue import androidx.compose.runtime.mutableStat…...
vue3中,通过获取路由上的token直接进入首页,跳过登录页面
1.需求 A系统想快速进入到B系统,但又不想输入账号密码,A系统的token与B系统共用token,因此在访问B系统就会在路径上携带token(https://magictool-box.com/login?token《token》),通过token直接进入B系统首…...
软考通关利器:中级软件设计师结构化开发核心考点
简介: 作为国家软考中级认证的核心科目,“软件设计师” 结构化开发能力是职业进阶的黄金敲门砖。本模块聚焦考试大纲高频考点,深度解析需求建模、结构化分析方法(SA/SD)、模块设计原则、数据流图(DFD&#…...
[思考记录]两则:宏观视角、理想化
#宏观视角# 昨天听金老师讲解了他初步整理的大模型宏观概念关系图,受益不少。图上不仅是涵盖了诸多概念,更厉害的应该在于把概念之间的关系进行了描述,更直观展现了概念是如何与其他概念相互作用的。帮助从整体的角度去理解,以及透…...
MySQL 性能优化方向
MySQL 性能优化是一个系统性的工作,涉及数据库设计、查询优化、索引优化、硬件配置等多个方面。以下是 MySQL 性能优化的主要方向和具体优化方案: 一、数据库设计优化 1. 合理设计表结构 规范化设计:避免数据冗余,确保数据一致性。适度反规范化:在查询频繁的场景下,适当…...
3-22 vector的使用详解---STL C++
C中的vector容器展开系统讲解,具体内容如下: 1. vector的定义和特性(基础概念) 讲解vector作为动态数组的核心特性:自动内存管理、动态扩容机制(倍增策略)对比普通数组:支持随机访…...
Collectors.toList / list 转 list
前言 略 Collectors.toList List<User> userList ...; List<Long> userIdList userList.stream().map(User::getUserId).collect(Collectors.toList());...
uniapp 和 webview 之间的通信
1.背景 应用使用了uniapp开发跨端应用,在uniapp中内嵌webview页面实现页面热更新效果,不需要用户单独重新安装软件即可实现页面的版本更新。 2.webview通知uniapp 在开发过程中我们难会遇到需要uniapp和webview来实现数据通信的场景,接下来…...
【Linux】Hadoop-3.4.1的伪分布式集群的初步配置
配置步骤 一、检查环境 JDK # 目前还是 JDK8 最适合 Hadoop java -version echo $JAVA_HOME Hadoop hadoop version echo $HADOOP_HOME 二、配置SSH免密登录 Hadoop需要通过SSH管理节点(即使在伪分布式模式下) sudo apt install openssh-server …...
【Java】深入了解下Java Bitset
【Java】深入了解下Java Bitset 推荐超级课程: 本地离线DeepSeek AI方案部署实战教程【完全版】Docker快速入门到精通Kubernetes入门到大师通关课AWS云服务快速入门实战 目录 【Java】深入了解下Java Bitset引言如果Java Bitset不是布尔数组,那它是什么…...
Linux CentOS7 安装 ffmpeg教程
官网:FFmpeg 操作 先用uname -a 查看内核版本,如果是 3.2.0或者以上就可以按照此办法来安装 cd /tmp wget https://johnvansickle.com/ffmpeg/releases/ffmpeg-release-amd64-static.tar.xz# 2. 解压 tar xvf ffmpeg-release-amd64-static.tar.xz# 3. 将…...
楼宇自控系统的结构密码:总线与分布式结构方式的差异与应用
在现代建筑中,为了实现高效、智能的管理,楼宇自控系统变得越来越重要。它就像建筑的 智能管家,可自动控制照明、空调、通风等各种机电设备,让建筑运行更顺畅,还能节省能源成本。而在楼宇自控系统里,有两种关…...
Fourier-Lerobot——把斯坦福人形动作策略iDP3封装进了Lerobot(含我司七月人形研发落地实践)
前言 近期在抠lerobot源码时,看到其封装了ALOHA ACT、diffusion policy、π0时,我就在想,lerobot其实可以再封装下idp3 我甚至考虑是否从我联合带的那十几个具身研究生中选几个同学做下这事,对他们也是很好的历练然当25年3.18日…...
系统架构设计知识体系总结
1.技术选型 1.什么是技术选型? 技术选型是指评估和选择在项目或系统开发中使用的最合适的技术和工具的过程。这涉及考虑基于其能力、特性、与项目需求的兼容性、可扩展性、性能、维护和其他因素的各种可用选项。技术选型的目标是确定与项目目标相符合、能够有效解…...

