2025-01-06 Unity 使用 Tip2 —— Windows、Android、WebGL 打包记录

news2025/2/28 15:22:11

文章目录

  • 1 Windows
  • 2 Android
    • 2.1 横版 / 竖版游戏
    • 2.2 API 最低版本
    • 2.3 目标帧率
      • 2.3.1 targetFrameRate
      • 2.3.2 vSyncCount
      • 2.3.3 Unity 默认设置以及推荐设置
      • 2.3.4 Unity 帧率托管
  • 3 WebGL
    • 3.1 平台限制
    • 3.2 打包报错记录 1
    • 3.3 打包报错记录 2

​ 最近尝试将写的小游戏打包,主要平台包括 Windows、Android 和 WebGL,以下是一些打包过程记录。

  • Unity 版本:6000.0.26f1c1

1 Windows

​ 不得不说,Windows 平台是真好,打包一切顺利,没有任何卡壳,太感动了〒▽〒。

​ 点击 Build And Run,直接无脑生成 exe。

image-20250106033655380

​ 小游戏的话不需要全屏,所以我设置了 Windowed。

image-20250106033350591

2 Android

​ 需要做一些处理,没有那么顺利。

2.1 横版 / 竖版游戏

​ 需要设置游戏是横版还是竖版,我将 Default Orientation 设置了 Auto Rotation,即自动翻转,并将 Allowed Orientations for Auto Rotation 仅设置 Landscape Right/Landscape Left,即可以横版左右翻转。

image-20250106034030506

​ 以下是相关设置说明:

  • Default Orientation:指定应用程序窗口在设备屏幕内的方向。

    可选项包括:

    1. Portrait:竖屏显示。
    2. Portrait Upside Down:竖屏倒立显示。
    3. Landscape Right:横屏显示(手机右侧朝下)。
    4. Landscape Left:横屏显示(手机左侧向下)。
    5. Auto Rotation:自动旋转。
  • Auto Rotation Behavior:自动旋转方式。

    可选项包括:

    1. User:用户可以锁定设备的自动旋转方向设置以关闭自动旋转。
    2. Sensor:依据设备传感器数据进行旋转,用户无法进行干预。

2.2 API 最低版本

​ Minimum API Level 必须手动设置,一般设置为 API Level 33,或者依据 Build 提示设为其指定值。我这里依据 Build 提示,设置为 API Level 34。

image-20250106035322270

​ 有意思的是,Unity 默认会选很古老的 API,例如 Android 8.0(API Level 26)。

​ 但奇怪的是,在 Unity Hub 下载 Android 模块时,往往只下载了 API Level 33 ~ 35,这就非常搞鬼了,不手动设置的话,基本第一次 Build 都会报错,因为压根没装那么低版本的 API。

image-20250106035718633

2.3 目标帧率

​ 通过 targetFrameRate(软件计时、手动设置)和 vSyncCount(硬件支持、自动设置)两种方式进行控制,只会同时生效其中一种(不考虑 VR 设备):

  • vSyncCount = 0 时,targetFrameRate 生效。
  • vSyncCount != 0 时,vSyncCount 生效。

2.3.1 targetFrameRate

targetFrameRate 是指定 Unity 尝试渲染游戏的目标帧速率,需要在程序运行之初使用代码进行设置。参考官方文档:https://docs.unity3d.com/6000.0/Documentation/ScriptReference/Application-targetFrameRate.html。

​ 不做任何手动设置时,Android 固定 30 fps 渲染(即 targetFrameRate = 30),以节省电池电量,与显示器的本机刷新率无关。

说明:

  1. targetFrameRate 只是帧率上限,实际帧率只会比这个值低或等于。

    不是说设置为 120 fps 后,老年机也能跑 120 帧。

  2. targetFrameRate = -1,表示帧率不封顶,帧数能跑多高就会跑多高。

  3. 受到显示器最大刷新率的限制,实际帧率不会超过显示器的本机刷新率。

    如果 targetFrameRate = 120,但是手机屏幕最高仅支持 90 帧,那么实际帧率最大也只能是 90。

  4. 在 Android 和 iOS 上,targetFrameRate 将向下舍入到能够整除显示器当前刷新率的最大值。

    例如,在 60Hz Android 显示器上运行时,且设置 targetFrameRate = 25 ,则设备帧率最高为 20fps,因为 20 是小于 25 且可以整除 60 的最高数字。

  5. 在 Windows 和 Web 上,不建议使用 targetFrameRate ,因为 targetFrameRate 基于软件计时,容易出现轻微卡顿现象。

​ 最初不知道如何设置的时候,导出 APK 在手机上运行时只有 30 帧超级卡,我还以为是自己性能优化没做好 hh。

2.3.2 vSyncCount

vSyncCount 表示每帧之间应传递的垂直同步数,即游戏允许在帧之间传递的屏幕刷新次数。范围是 0~ 4 内的整数,默认为 1。参考官方文档:https://docs.unity3d.com/6000.0/Documentation/ScriptReference/QualitySettings-vSyncCount.html。

​ 假设目标设备显示器的刷新率为 90 fps,当 vSyncCount > 0 时,游戏目标帧为 90 / vSyncCount

vSyncCount 能够在 “Project Settings” -> “Quality”-> “VSync Count” 中进行设置:

  • Don’t Sync:即 vSyncCount = 0
  • Every V Blank:即 vSyncCount = 1
  • Every Second V Blank:即 vSyncCount = 2
image-20250106043532111

说明:

  1. 在 Android 和 iOS 上,vSyncCount 始终被忽略,因为移动设备不允许不同步渲染(使用 targetFrameRate 控制帧速率)。
  2. 在 Windows 和 Web 上,建议使用 vSyncCount,因为其基于硬件同步机制,能够产生完全无卡顿的输出。

2.3.3 Unity 默认设置以及推荐设置

平台Unity 默认设置推荐设置
WindowsvSyncCount = 0, targetFrameRate = -1
(帧率不封顶,不同步渲染)
默认即可
Android / IOStargetFrameRate = 30
(固定 30 帧渲染)
targetFrameRate = 60
WebGLvSyncCount = 1
(垂直同步,以本机显示刷新率渲染)
默认即可

​ 实现代码:

public class GameStart : MonoBehaviour
{
    private void Awake()
    {
#if PLATFORM_ANDROID
        QualitySettings.vSyncCount  = 0;
        Application.targetFrameRate = 60;
#endif
    }
}

2.3.4 Unity 帧率托管

​ 在 “Project Settings” -> “Player”-> “Resolution and Presentation” -> “Resolution” 中,可勾选 “Optimized Frame Pacing”,从而让 Unity 均匀分布帧,以减少帧速率的差异并创造更流畅的体验,提供更平滑的帧率表现。

image-20250106045000717

​ 但参考该文:https://blog.csdn.net/m0_63261863/article/details/143192236,勾选可能导致游戏降频,建议结合自己情况勾选。

3 WebGL

​ WebGL 平台限制是真多,导出过程真的快吐了。

​ 但优点是链接点开即玩,所以没有办法。

3.1 平台限制

  1. 不支持访问本地文件。

    对资产数据和 AssetBundle 的网络请求会缓存在浏览器缓存中。

  2. 不支持多线程。

    不支持 C# System.Threading 命名空间中的任何内容。

  3. 不支持System.Net命名空间内的 .NET 网络类。

  4. 不支持 Unity 内部 AudioSource 与 AudioClip 的部分 API。

    这将导致,在 Unity 编辑器中使用 Addressables 模拟真机 AB 包加载音频时,无法正确播放。只能使用 Use Asset Database,或者将音频文件放在 Resources 文件夹下(不建议这样做)。

image-20250106050823395
  1. 不允许使用 System.Reflection.Emit 动态生成代码。

  2. 不支持同步加载资源,只能异步加载。

3.2 打包报错记录 1

​ 一次偶然的机会,看到 Low 选项,不自觉设置为了 Medium。

image-20250106051828069

​ 于是 WebGL 下打包报错,获取不到单例的非公共构造函数。

​ 报错代码:FrameworkException: Non-Public Constructor() not found! in Framework.Toolkits.PoolKit.SingletonObjectPool`1[Framework.Toolkits.AudioKit.AudioPlayer] at Framework.Toolkits.SingletonKit.SingletonCreator.CreateNonPublicConstructorObject[T] () [0x00000] in <00000000000000000000000000000000>:0

image-20250106052012118

​ 查原因后,发现 Strip Engine Code 等级为 Medium 及以上时,会对反射的代码产生影响。而恰好,我的单例是通过反射获取私有无参构造函数创建的(官方链接:https://docs.unity3d.com/6000.0/Documentation/Manual/class-PlayerSettingsWebGL.html)。解决方案就是将 Strip Engine Code 等级调回 Low 即可。

image-20250106052249345
  • Strip Engine Code:仅适用于 IL2CPP 脚本后端。

    勾选会剔除应用程序不使用的 DLL,以减少内置播放器的大小,建议勾选。

  • Managed Stripping Level:控制剔除程度。

    1. Minimal

      使用此选项以剥离类库、UnityEngine、Windows 运行时程序集,并复制所有其他程序集。

    2. Low

      删除无法访问的托管代码,减少构建大小和 Mono/IL2CPP 构建时间。

    3. Medium

      运行 UnityLinker 以减少代码大小,剔除范围大于 Low 选项,且某些反射代码路径的行为可能不同(支持自定义 link.xml 文件)。

    4. High

      运行 UnityLinker 进一步减少代码大小,剔除范围大于 Mediumm 选项,某些反射代码路径的行为可能不同,同时某些方法的托管代码调试可能不再起作用(支持自定义 link.xml 文件)。

3.3 打包报错记录 2

​ 有次无意间不满意新写的代码,直接将老版本代码(unitypackage)覆盖导入 Unity,之后再进行 WebGL 打包时发生如下报错:

Build completed with a result of 'Failed' in 129 seconds (129224 ms)
Building Library\Bee\artifacts\WebGL\build\debug_WebGL_wasm\build.js failed with output:

P:\Unity Project\Mine\Survivor Game 2.0>set MYDIR=S:\Unity Editor\6000.0.26f1c1\Editor\Data\PlaybackEngines\WebGLSupport\BuildTools\Emscripten\emscripten\ 

P:\Unity Project\Mine\Survivor Game 2.0>goto FOUND_MYDIR 
wasm-ld: warning: function signature mismatch: UxmlFactory__ctor_m87E7DA1E842A9B4B4A45132392EDA2868D62B8A2
>>> defined as () -> void in P:/Unity Project/Mine/Survivor Game 2.0/Library/Bee/artifacts/WebGL/il2cppOutput/build/GameAssembly.a(3yoe1qmioyer.o)
>>> defined as (i32, i32) -> void in lto.tmp

wasm-ld: warning: function signature mismatch: VisualChangesProcessor_get_elementBuilder_m759F6B67F45FB60E9B1E4C646F26689258317B1E
>>> defined as () -> void in P:/Unity Project/Mine/Survivor Game 2.0/Library/Bee/artifacts/WebGL/il2cppOutput/build/GameAssembly.a(lsyvkdbleliz.o)
>>> defined as (i32, i32) -> i32 in lto.tmp

wasm-ld: warning: function signature mismatch: Area__ctor_m6128DC659857264FD4FBF06C01E0C2F04EAA4105
>>> defined as () -> void in P:/Unity Project/Mine/Survivor Game 2.0/Library/Bee/artifacts/WebGL/il2cppOutput/build/GameAssembly.a(kkef0xumaj1j.o)
>>> defined as (i32, i32, i32) -> void in lto.tmp

wasm-ld: warning: function signature mismatch: SingleQueryMatcher_IsInUse_mF17B2C22806E732E50055D4F6AC8A0E3ABEB4B99
>>> defined as () -> void in P:/Unity Project/Mine/Survivor Game 2.0/Library/Bee/artifacts/WebGL/il2cppOutput/build/GameAssembly.a(z4arkogp7up0.o)
>>> defined as (i32, i32) -> i32 in lto.tmp

...

​ 最初认为是项目中部分插件不支持 WebGL 平台,倒腾一番后,又重装了 WebGL 打包模块,依然是同样的报错。

​ 解决方案:删除该项目下的 Library 文件夹,Unity 重新打开项目,没有报错。

image-20250106053758010

​ 分析原因:Library 中缓存的以前打包的结果,导致代码链接失败。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2273676.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

湘潭大学人机交互复习

老师没给题型也没划重点&#xff0c;随便看看复习了 什么是人机交互 人机交互&#xff08;Human-Computer Interaction&#xff0c;HCI&#xff09;是关于设计、评价和实现供人们使用的交互式计算机系统&#xff0c;并围绕相关的主要现象进行研究的学科。 人机交互研究内容 …

基于FPGA的出租车里程时间计费器

基于FPGA的出租车里程时间计费器 功能描述一、系统框图二、verilog代码里程增加模块时间增加模块计算价格模块上板视频演示 总结 功能描述 &#xff08;1&#xff09;&#xff1b;里程计费功能&#xff1a;3公里以内起步价8元&#xff0c;超过3公里后每公里2元&#xff0c;其中…

基于FPGA的洗衣机控制器电子定时器

文章目录 功能描述 一、框架 二、verilog代码 控制模块实现 三、视频上板效果展示 功能描述 &#xff08;1&#xff09;定时启动正转20秒暂停10秒反转20秒暂 停10秒&#xff0c;定时未到回到“正转20秒暂停10秒……”&#xff0c;定时到则停止; 若定时到&#xff0c;则停…

【Linux系列】Vim 编辑器中的高效文本编辑技巧:删除操作

&#x1f49d;&#x1f49d;&#x1f49d;欢迎来到我的博客&#xff0c;很高兴能够在这里和您见面&#xff01;希望您在这里可以感受到一份轻松愉快的氛围&#xff0c;不仅可以获得有趣的内容和知识&#xff0c;也可以畅所欲言、分享您的想法和见解。 推荐:kwan 的首页,持续学…

大纲笔记幕布的替换

文章目录 前言类似的大纲软件探索 DynalistLogseq通过国内代码仓库建立 Git 仓库Logseq 的使用PC 端安卓端Git 操作Termux git 步骤Termux 的桌面组件&#xff1a;Termux widget 报错参考 前言 之前我一直用幕布&#xff0c;买了三年&#xff0c;奈何要过期了&#xff0c;又三…

STM32-笔记35-DMA(直接存储器访问)

一、什么叫DMA&#xff1f; DMA&#xff08;Direct Memory Access&#xff0c;直接存储器访问&#xff09;提供在外设与内存、存储器和存储器之间的高速数据传输使用。它允许不同速度的硬件装置来沟通&#xff0c;而不需要依赖于CPU&#xff0c;在这个时间中&#xff0c;CPU对于…

【踩坑】SparkSQL union/unionAll 函数的去重问题

【踩坑】SparkSQL union/unionAll 函数的去重问题 测试数据 case class Employee(first_name:String)val employeeDF1 spark.createDataset(Seq( Employee("Mary"), Employee("Mandy"),Employee("Kurt") )) val employeeDF2 spark.createDat…

allure报告修改默认语言为中文

1、项目根目录创建.py文件&#xff0c;把代码复制进去 import os from pathlib import Pathdef create_settings_js_file(directory"../pytest_mytt/reports/allures/", filenamesettings.js):# 创建或确认目录存在Path(directory).mkdir(parentsTrue, exist_okTrue…

使用frp实现本地内网穿透

环境&#xff1a;linux &#xff08;具有公网ip的线上服务器&#xff09;、windows&#xff08;本地&#xff09;、frp Releases fatedier/frphttps://github.com/fatedier/frp/releases 首先下载下来下面两个文件 概览 | frp一些概述&#xff0c;便于您快速的了解 frp。http…

Cursor无限续杯——解决Too many free trials.

前情提要 我们都知道Cursor对新用户是有14天且500条免费限制的。 一般情况下&#xff0c;当14天过期&#xff0c;是可以注销账户再重新注册&#xff0c;这样就可以继续拥有14天的体验时长。 但是&#xff01;&#xff01;如果使用超过500次&#xff0c;Cusor就会把你的电脑I…

cursor试用出现:Too many free trial accounts used on this machine 的解决方法

文章精选推荐 1 JetBrains Ai assistant 编程工具让你的工作效率翻倍 2 Extra Icons&#xff1a;JetBrains IDE的图标增强神器 3 IDEA插件推荐-SequenceDiagram&#xff0c;自动生成时序图 4 BashSupport Pro 这个ides插件主要是用来干嘛的 &#xff1f; 5 IDEA必装的插件&…

攻防世界 Web_php_wrong_nginx_config

​ 打开题目地址&#xff0c;显示为登录页面。尝试用御剑扫描一下&#xff0c;发现了admin页面&#xff0c;点进去显示如下 点开控制台&#xff0c;发现如下 isLogin参数为0。尝试抓包并该islogin参数为1&#xff0c;返回依旧不变。 再扫描&#xff0c;发现robots.txt&#xff…

WordPress静态缓存插件WP Super Cache与 WP Fastest Cache

引言 WordPress是一款开源的内容管理系统&#xff08;CMS&#xff09;&#xff0c;最初作为博客平台开发&#xff0c;现已发展成为一个功能强大的建站工具&#xff0c;支持创建各种类型的网站&#xff0c;包括企业网站、在线商店、个人博客等。它具有用户友好的界面、丰富的插…

多模态大模型初探索:通过ollama部署多模态大模型

文章目录 前言模型下载 前言 今天和同事聊天&#xff0c;聊到多模态大模型&#xff0c;感觉可以作为2025年的一个新的探索方向。希望和大家一起学习&#xff0c;一起进步。 今天也是尝试了我能想到的最基本最快速地本地部署多模态大模型的方式&#xff0c;那便是使用ollama。…

【深度学习】布匹寻边【附完整链接】

布匹寻边 项目简介 布匹寻边是指布料裁剪过程中&#xff0c;通过AI寻边技术自动识别布匹的边缘&#xff0c;将检测到的边缘信息输出&#xff0c;确保裁剪的准确性&#xff0c;减少浪费&#xff0c;并提高生产效率。 项目需求 将打满针眼的布匹边缘裁剪掉&#xff0c;且误差小…

scanf:数据之舟的摆渡人,静卧输入港湾的诗意守候

大家好啊&#xff0c;我是小象٩(๑ω๑)۶ 我的博客&#xff1a;Xiao Xiangζั͡ޓއއ 很高兴见到大家&#xff0c;希望能够和大家一起交流学习&#xff0c;共同进步。* 这一节我们主要来学习scanf的基本用法&#xff0c;了解scanf返回值&#xff0c;懂得scanf占位符和赋值…

vue数据请求通用方案:axios的options都有哪些值

Axios 是一个基于 promise 的 HTTP 库&#xff0c;可以用在浏览器和 Node.js 中。 在使用 Axios 发送请求时&#xff0c;可以通过传递一个配置对象来指定请求的各种选项。 以下是一些常用的 Axios 配置选项及其说明&#xff1a; 1.url: &#xff08;必需&#xff09;请求的 …

阿里mod_asr3.0集成webrtc静音算法

alibabacloud-nls-cpp-sdk-master 先到阿里官网下载nls库的源代码&#xff0c;编译生成对应的库文件和头文件。 我编译的放到了以下目录。 /home/jp/2025/alibabacloud-nls-cpp-sdk-master/build/install/NlsSdk3.X_LINUX/include/ /home/jp/2025/alibabacloud-nls-cpp-sdk-…

【大模型】百度千帆大模型对接LangChain使用详解

目录 一、前言 二、LangChain架构与核心组件 2.1 LangChain 核心架构 2.2 LangChain 核心组件 三、环境准备 3.1 前置准备 3.1.1 创建应用并获取apikey 3.1.2 开通付费功能 3.2 获取LangChain文档 3.3 安装LangChain依赖包 四、百度千帆大模型对接 LangChain 4.1 LL…

【51单片机零基础-chapter6:LCD1602调试工具】

实验0-用显示屏LCD验证自己的猜想 如同c的cout,前端的console.log() #include <REGX52.H> #include <INTRINS.H> #include "LCD1602.h" int var0; void main() {LCD_Init();LCD_ShowNum(1,1,var211,5);while(1){;} }实验1-编写LCD1602液晶显示屏驱动函…