Loading...
Loading...
Compare original and translation side by side
unity-clicom.unity.pipelineevalProjectSettings/ProjectSettings.assetunity command eval --code '<snippet>'unity commandunity-clicom.unity.pipelineevalProjectSettings/ProjectSettings.assetunity command eval --code '<snippet>'unity commandevalevalevalusingusing UnityEditor;CS0210PlayerSettingsCS0246ObjectobjectCS0104evalusingusing UnityEditor;CS0210PlayerSettingsCS0246ObjectobjectCS0104var target = UnityEditor.Build.NamedBuildTarget.WebGL;
var w = new System.Collections.Generic.List<string>();
w.Add($"activeBuildTarget={UnityEditor.EditorUserBuildSettings.activeBuildTarget}");
w.Add($"compressionFormat={UnityEditor.PlayerSettings.WebGL.compressionFormat}");
w.Add($"decompressionFallback={UnityEditor.PlayerSettings.WebGL.decompressionFallback}");
w.Add($"stripEngineCode={UnityEditor.PlayerSettings.stripEngineCode}");
w.Add($"managedStrippingLevel={UnityEditor.PlayerSettings.GetManagedStrippingLevel(target)}");
w.Add($"il2cppCodeGeneration={UnityEditor.PlayerSettings.GetIl2CppCodeGeneration(target)}");
w.Add($"apiCompatibilityLevel={UnityEditor.PlayerSettings.GetApiCompatibilityLevel(target)}");
w.Add($"exceptionSupport={UnityEditor.PlayerSettings.WebGL.exceptionSupport}");
w.Add($"debugSymbolMode={UnityEditor.PlayerSettings.WebGL.debugSymbolMode}");
w.Add($"dataCaching={UnityEditor.PlayerSettings.WebGL.dataCaching}");
w.Add($"wasm2023={UnityEditor.PlayerSettings.WebGL.wasm2023}");
w.Add($"initialMemorySize={UnityEditor.PlayerSettings.WebGL.initialMemorySize}");
w.Add($"maximumMemorySize={UnityEditor.PlayerSettings.WebGL.maximumMemorySize}");
w.Add($"memoryGrowthMode={UnityEditor.PlayerSettings.WebGL.memoryGrowthMode}");
w.Add($"targetFrameRate={UnityEngine.Application.targetFrameRate}");
w.Add($"vSyncCount={UnityEngine.QualitySettings.vSyncCount}");
return string.Join("\n", w);| Setting | Correct form | Does NOT exist |
|---|---|---|
| Managed stripping level | | |
| Wasm code optimization | | |
| IL2CPP code generation | | a bare property |
UserBuildSettingsvar target = UnityEditor.Build.NamedBuildTarget.WebGL;
var w = new System.Collections.Generic.List<string>();
w.Add($"activeBuildTarget={UnityEditor.EditorUserBuildSettings.activeBuildTarget}");
w.Add($"compressionFormat={UnityEditor.PlayerSettings.WebGL.compressionFormat}");
w.Add($"decompressionFallback={UnityEditor.PlayerSettings.WebGL.decompressionFallback}");
w.Add($"stripEngineCode={UnityEditor.PlayerSettings.stripEngineCode}");
w.Add($"managedStrippingLevel={UnityEditor.PlayerSettings.GetManagedStrippingLevel(target)}");
w.Add($"il2cppCodeGeneration={UnityEditor.PlayerSettings.GetIl2CppCodeGeneration(target)}");
w.Add($"apiCompatibilityLevel={UnityEditor.PlayerSettings.GetApiCompatibilityLevel(target)}");
w.Add($"exceptionSupport={UnityEditor.PlayerSettings.WebGL.exceptionSupport}");
w.Add($"debugSymbolMode={UnityEditor.PlayerSettings.WebGL.debugSymbolMode}");
w.Add($"dataCaching={UnityEditor.PlayerSettings.WebGL.dataCaching}");
w.Add($"wasm2023={UnityEditor.PlayerSettings.WebGL.wasm2023}");
w.Add($"initialMemorySize={UnityEditor.PlayerSettings.WebGL.initialMemorySize}");
w.Add($"maximumMemorySize={UnityEditor.PlayerSettings.WebGL.maximumMemorySize}");
w.Add($"memoryGrowthMode={UnityEditor.PlayerSettings.WebGL.memoryGrowthMode}");
w.Add($"targetFrameRate={UnityEngine.Application.targetFrameRate}");
w.Add($"vSyncCount={UnityEngine.QualitySettings.vSyncCount}");
return string.Join("\n", w);| 设置项 | 正确写法 | 不存在的写法 |
|---|---|---|
| 托管代码剥离级别 | | |
| Wasm代码优化 | | |
| IL2CPP代码生成 | | 直接使用属性 |
UserBuildSettings[MenuItem]evalAssets/Editor/UnityEditor.EditorApplication.ExecuteMenuItem("Tools/Apply Web Release Settings");usingeval[MenuItem]evalAssets/Editor/UnityEditor.EditorApplication.ExecuteMenuItem("Tools/Apply Web Release Settings");usingevalEditorUserBuildSettings.activeBuildTargetWebGLcompressionFormatdecompressionFallbackstripEngineCodePlayerSettings.GetManagedStrippingLevel(NamedBuildTarget.WebGL)PlayerSettings.managedStrippingLevelPlayerSettings.WebGL.exceptionSupportUnityEditor.WebGL.UserBuildSettings.codeOptimizationPlayerSettings.WebGL.codeOptimizationoptimizationLevelApplication.targetFrameRateQualitySettings.vSyncCountPlayerSettings.WebGL.dataCachingPlayerSettings.WebGL.debugSymbolModePlayerSettings.WebGL.maximumMemorySizePlayerSettings.GetApiCompatibilityLevelEditorUserBuildSettings.activeBuildTargetWebGLcompressionFormatdecompressionFallbackstripEngineCodePlayerSettings.GetManagedStrippingLevel(NamedBuildTarget.WebGL)PlayerSettings.managedStrippingLevelPlayerSettings.WebGL.exceptionSupportUnityEditor.WebGL.UserBuildSettings.codeOptimizationPlayerSettings.WebGL.codeOptimizationoptimizationLevelApplication.targetFrameRateQualitySettings.vSyncCountPlayerSettings.WebGL.dataCachingPlayerSettings.WebGL.debugSymbolModePlayerSettings.WebGL.maximumMemorySizePlayerSettings.GetApiCompatibilityLevelWindow > General > Build ReportContent-Encoding: brContent-Encoding: gzipContent-Type: application/wasm.wasmApplication.targetFrameRate-1PlayerSettings.WebGL.initialMemorySizePlayerSettings.WebGL.memoryGrowthModeWindow > General > Build ReportContent-Encoding: brContent-Encoding: gzip.wasmContent-Type: application/wasmApplication.targetFrameRate-1PlayerSettings.WebGL.initialMemorySizePlayerSettings.WebGL.memoryGrowthMode| User Says | Default Interpretation |
|---|---|
| "build too large" / "download too slow" | Strip Engine Code on; Managed Stripping High; Disk Size + LTO; Brotli |
| "Decompression Fallback" / "slow startup" | Decompression Fallback off; fix server to send Content-Encoding |
| "stutter in Chrome" / "stutter in Safari" | Profile in browser DevTools; Safari caps at 60 fps |
| "excessive battery in browser" | |
| "exceptions too large" | None for release; Wasm 2023 exceptions if browser baseline allows |
| "set up CDN" | Addressables remote groups + Brotli/Gzip on CDN |
| "WebAssembly 2023" | Enable when browser baseline supports it — smaller and faster |
| "memory growth slow" | Tune Initial Memory Size to peak estimate; use Geometric growth mode |
| "KTX" / "Basis Universal" / "texture formats unknown GPU" | KTX2 with Basis Universal; ETC1S for size, UASTC for quality |
| "strip unused code" / "remove unused packages" | Web Stripping Tool + remove unused packages + shader stripping |
| "quality settings for web" | Quality Level to Very Low or Low; lower quality = faster load |
| "shader variants too many" | Graphics settings: auto lightmap/fog modes; strip instancing + BRG variants; audit Always Included Shaders |
| "video not playing" / "audio issues" | Video: URL-only or StreamingAssets; Audio: no AudioEffects on Web, use Mono, compress |
| "profiler symbols" / "can't read Wasm stacks" | Embed profiling symbols via build processor or emscriptenArgs |
| "iOS crashes" / "Safari memory" | iOS memory limits; set Initial Memory Size high rather than growing; Gigacage 2GB limit pre-iOS 18 |
| 用户表述 | 默认解读 |
|---|---|
| "构建体积过大" / "下载太慢" | 启用剥离引擎代码;设置托管代码剥离级别为高;开启磁盘大小优化+LTO;使用Brotli压缩 |
| "需要解压回退" / "启动缓慢" | 关闭解压回退;修复服务器使其发送Content-Encoding头 |
| "Chrome中卡顿" / "Safari中卡顿" | 使用浏览器DevTools分析性能;Safari帧率上限为60fps |
| "浏览器中电池消耗过高" | 静态画面启用 |
| "异常处理体积过大" | 发布版本禁用异常处理;若浏览器基线支持则使用Wasm 2023异常模型 |
| "配置CDN" | 使用Addressables远程组+CDN上的Brotli/Gzip压缩 |
| "WebAssembly 2023" | 当浏览器基线支持时启用——体积更小、速度更快 |
| "内存增长缓慢" | 根据峰值估算调整初始内存大小;使用几何增长模式 |
| "KTX" / "Basis Universal" / "未知GPU纹理格式" | 使用带Basis Universal的KTX2;ETC1S优先考虑体积,UASTC优先考虑质量 |
| "剥离未使用代码" / "移除未使用包" | 使用Web剥离工具+移除未使用包+着色器剥离 |
| "Web端质量设置" | 质量级别设为极低或低;质量越低,加载速度越快 |
| "着色器变体过多" | 图形设置:自动光照贴图/雾效模式;剥离实例化+BRG变体;审核始终包含的着色器 |
| "视频无法播放" / "音频问题" | 视频:仅使用URL或StreamingAssets;音频:WebGL不支持AudioEffects,使用单声道并压缩 |
| "性能分析符号" / "无法读取Wasm堆栈" | 通过构建处理器或emscriptenArgs嵌入性能分析符号 |
| "iOS崩溃" / "Safari内存问题" | iOS内存限制;设置较高的初始内存大小而非依赖增长;iOS 18之前Gigacage上限为2GB |
Assets/Editor/WebOptimizer.cstry/catchAssets/Editor/WebOptimizer.cstry/catcheval| Setting | Release recommendation |
|---|---|
| Compression Format | Brotli (HTTPS hosting); Gzip for HTTP |
| Decompression Fallback | Off when server is correctly configured |
| Strip Engine Code | On |
| Managed Stripping Level | High (release) / Medium (dev) |
| Code Optimization | Disk Size with LTO (release) / Build Times (dev) |
| WebAssembly Language Features | 2023 if browser baseline allows |
| Enable Exceptions | None (smallest); Explicitly Thrown Only if |
| Initial Memory Size | Tune to peak estimate; too small causes expensive growth |
| Memory Growth Mode | Geometric |
| API Compatibility Level | .NET Standard 2.1 — smaller than .NET Framework |
| IL2CPP Code Generation | Optimize Size — smaller Wasm at slight runtime cost |
| Debug Symbols | Off for release; on for development builds only |
| Data Caching | On — caches asset data in browser IndexedDB for faster repeat loads |
| Strip Unused Mesh Components | On — removes unused vertex attributes |
| Maximum Memory Size | 2048 MB default; up to 4096 for complex 3D (Firefox and Chrome < 119 have issues above 2048) |
| vSyncCount | 0 (browser handles pacing) |
| targetFrameRate | -1 (use |
eval| 设置项 | 发布版本建议 |
|---|---|
| 压缩格式 | Brotli(HTTPS托管);HTTP托管使用Gzip |
| 解压回退 | 服务器配置正确时关闭 |
| 剥离引擎代码 | 开启 |
| 托管代码剥离级别 | 高(发布版本)/ 中(开发版本) |
| 代码优化 | 磁盘大小优化+LTO(发布版本)/ 构建速度优先(开发版本) |
| WebAssembly语言特性 | 浏览器基线支持时启用2023 |
| 启用异常处理 | 无(体积最小);若需要 |
| 初始内存大小 | 根据峰值估算调整;过小会导致昂贵的内存增长操作 |
| 内存增长模式 | 几何增长 |
| API兼容性级别 | .NET Standard 2.1 —— 比.NET Framework体积更小 |
| IL2CPP代码生成 | 优化体积 —— 牺牲少量运行时性能以减小Wasm体积 |
| 调试符号 | 发布版本关闭;仅在开发构建中开启 |
| 数据缓存 | 开启 —— 在浏览器IndexedDB中缓存资源数据,加快重复加载速度 |
| 剥离未使用网格组件 | 开启 —— 移除未使用的顶点属性 |
| 最大内存大小 | 默认2048 MB;复杂3D项目可设为4096 MB(Firefox和Chrome 119以下版本超过2048 MB会有问题) |
| vSyncCount | 0(由浏览器控制 pacing) |
| targetFrameRate | -1(使用 |
| Compression | Use when | Notes |
|---|---|---|
| Brotli | HTTPS or localhost | Best ratio; browsers accept only over secure contexts |
| Gzip | HTTP delivery, legacy CDNs | Universal |
| None | Local dev / file:// | Largest payload; do not ship |
.brContent-Encoding: br.gzContent-Encoding: gzipContent-Type: application/wasm.wasmapplication/javascript.jsContent-Encoding| 压缩方式 | 使用场景 | 说明 |
|---|---|---|
| Brotli | HTTPS或本地主机 | 压缩率最佳;仅在安全上下文下被浏览器接受 |
| Gzip | HTTP交付、传统CDN | 通用兼容 |
| 无压缩 | 本地开发 / file://协议 | 体积最大;请勿用于发布 |
.brContent-Encoding: br.gzContent-Encoding: gzip.wasmContent-Type: application/wasm.jsapplication/javascriptContent-Encoding| Setting | Build size | Use |
|---|---|---|
| None | Smallest | Release builds where uncaught exceptions are acceptable |
| Explicitly Thrown Only | Modest | Default for projects that catch exceptions |
| Full | Largest, slowest | Rarely needed; avoid for release |
| 设置项 | 构建体积 | 使用场景 |
|---|---|---|
| 无 | 最小 | 可接受未捕获异常的发布版本 |
| 仅显式抛出 | 中等 | 使用异常捕获的项目默认设置 |
| 完整 | 最大、最慢 | 极少需要;发布版本避免使用 |
Packages/manifest.jsonEdit > Project Settings > Graphics| Setting | Recommendation |
|---|---|
| Lightmap Modes | Automatic (strips unused lightmap shader variants) |
| Fog Modes | Automatic (strips unused fog shader variants) |
| Instancing Variants | Strip Unused |
| Batch Renderer Group Variants | Strip All (if BRGs are not used) |
| Always Included Shaders | Audit and remove any shaders the project does not reference |
com.unity.web.stripping-toolPackages/manifest.jsonEdit > Project Settings > Graphics| 设置项 | 建议 |
|---|---|
| 光照贴图模式 | 自动(剥离未使用的光照贴图着色器变体) |
| 雾效模式 | 自动(剥离未使用的雾效着色器变体) |
| 实例化变体 | 剥离未使用的变体 |
| 批处理渲染组变体 | 全部剥离(若未使用BRG) |
| 始终包含的着色器 | 审核并移除项目未引用的着色器 |
com.unity.web.stripping-toolEdit > Project Settings > QualityevalUnityEngine.QualitySettings.SetQualityLevel(0, true);Edit > Project Settings > QualityevalUnityEngine.QualitySettings.SetQualityLevel(0, true);evalUnityEngine.Application.targetFrameRate = -1;requestAnimationFrameOnDemandRendering.renderFrameIntervalevalUnityEngine.Application.targetFrameRate = -1;requestAnimationFrameOnDemandRendering.renderFrameInterval| Topic | Guidance |
|---|---|
| Package | Install |
| When to use | Runtime-loaded textures via Addressables or asset bundles served to unknown GPU targets |
| When NOT to use | Textures baked into the player build — Unity already selects the correct format at build time |
| Supercompression | Use ETC1S for smallest size (lossy, good for diffuse/albedo); UASTC for higher quality (near-lossless, better for normals/UI) |
| Encoding | Encode offline with |
| Linear data | Set |
| Mip maps | Generate mips at encode time ( |
| Loading | Use |
| Memory | Transcoded textures are standard GPU textures; memory cost equals the target format, not the KTX2 file size |
| Orientation | Always include |
toktx| 主题 | 指导 |
|---|---|
| 包 | 通过Package Manager安装 |
| 使用场景 | 通过Addressables或资源包加载的运行时纹理,目标为未知GPU设备 |
| 不适用场景 | 烘焙到播放器构建中的纹理——Unity会在构建时自动选择正确格式 |
| 超压缩 | 使用ETC1S追求最小体积(有损压缩,适用于漫反射/基础色);使用UASTC追求更高质量(接近无损,适用于法线/UI) |
| 编码 | 使用 |
| 线性数据 | 编码法线贴图、遮罩或数据纹理时设置 |
| Mip贴图 | 编码时生成mip贴图( |
| 加载 | 使用 |
| 内存 | 转码后的纹理为标准GPU纹理;内存开销等于目标格式大小,而非KTX2文件大小 |
| 方向 | 始终添加 |
toktx| Tool | Use | Notes |
|---|---|---|
| Chrome DevTools > Performance | CPU flamegraph; main-thread analysis | Default first stop for WebGL hitches; inspect Wasm call stacks |
| Chrome DevTools > Memory | Heap snapshot; allocation timeline | Find JS/Wasm memory leaks; compare snapshots before/after scene load |
| Firefox Profiler | Cross-platform; shareable URLs; native + Wasm view | Better Wasm symbolication than Chrome in some cases; shareable profile URLs for team review |
| Safari Web Inspector | iOS Safari and macOS Safari debugging | Required for Safari-specific issues; WebGL/Wasm runtime differs from Chromium |
| Unity Profiler over WebSocket | Connect to a development build; standard markers | Use for Unity-side markers (GC, rendering, scripts); does not capture browser-side overhead |
| Symptom | First-line tool | Second-line tool |
|---|---|---|
| WebGL hitch / stutter | Chrome DevTools > Performance | Firefox Profiler |
| Memory climbing over time | Chrome DevTools > Memory | Unity Memory Profiler (WebSocket) |
| Slow initial load | Chrome DevTools > Network | Build Report Inspector |
| Safari-only rendering issue | Safari Web Inspector | Compare with Chrome DevTools |
Player Settings > Publishing > Debug Symbolsusing UnityEditor;
using UnityEditor.Build;
using UnityEditor.Build.Reporting;
public class WebProfilingBuildProcessor : IPreprocessBuildWithReport
{
public int callbackOrder => 0;
public void OnPreprocessBuild(BuildReport report)
{
PlayerSettings.SetAdditionalIl2CppArgs("--compiler-flags=--profiling-funcs");
}
}PlayerSettings.WebGL.emscriptenArgs| Flag | What it shows |
|---|---|
| CPU profiler overlay in browser |
| Visual memory map (white=allocated unused, pink=stack, blue=dynamic, green=fragmented) |
| Thread activity profiler |
about:memoryabout:memory| 工具 | 使用场景 | 说明 |
|---|---|---|
| Chrome DevTools > Performance | CPU火焰图;主线程分析 | WebGL卡顿问题的默认首选工具;检查Wasm调用栈 |
| Chrome DevTools > Memory | 堆快照;分配时间线 | 查找JS/Wasm内存泄漏;对比场景加载前后的快照 |
| Firefox Profiler | 跨平台;可分享URL;原生+Wasm视图 | 在某些情况下比Chrome的Wasm符号化效果更好;可生成分享链接供团队评审 |
| Safari Web Inspector | iOS Safari和macOS Safari调试 | 排查Safari专属问题的必备工具;WebGL/Wasm运行时与Chromium不同 |
| 通过WebSocket连接的Unity Profiler | 连接到开发构建;标准标记 | 用于分析Unity侧标记(GC、渲染、脚本);无法捕获浏览器端开销 |
| 症状 | 首选工具 | 次选工具 |
|---|---|---|
| WebGL卡顿/停顿 | Chrome DevTools > Performance | Firefox Profiler |
| 内存持续增长 | Chrome DevTools > Memory | Unity内存分析器(WebSocket) |
| 初始加载缓慢 | Chrome DevTools > Network | Build Report Inspector |
| Safari专属渲染问题 | Safari Web Inspector | 与Chrome DevTools对比 |
Player Settings > Publishing > Debug Symbolsusing UnityEditor;
using UnityEditor.Build;
using UnityEditor.Build.Reporting;
public class WebProfilingBuildProcessor : IPreprocessBuildWithReport
{
public int callbackOrder => 0;
public void OnPreprocessBuild(BuildReport report)
{
PlayerSettings.SetAdditionalIl2CppArgs("--compiler-flags=--profiling-funcs");
}
}PlayerSettings.WebGL.emscriptenArgs| 标志 | 显示内容 |
|---|---|
| 浏览器中的CPU分析器浮层 |
| 可视化内存地图(白色=已分配未使用,粉色=栈,蓝色=动态分配,绿色=碎片) |
| 线程活动分析器 |
about:memoryabout:memory.dataabout:memoryabout:memorydevicePixelRatiodevicePixelRatiolink.xmllink.xmlContent-Encoding: brContent-Encoding: brApplication.targetFrameRate = 60-1Application.targetFrameRate = 60-1Application.targetFrameRate = 60requestAnimationFrame-1vSyncCountApplication.targetFrameRate = 60requestAnimationFrame-1vSyncCountbrowser.cache.disk.max_entry_sizeabout:configbrowser.cache.disk.max_entry_sizeabout:configundefinedundefined
For Brotli testing, use HTTPS — Brotli requires a secure context. Generate a self-signed cert with OpenSSL for local testing.
测试Brotli需使用HTTPS——Brotli需要安全上下文。使用OpenSSL生成自签名证书用于本地测试。ShaderVariantCollectionShaderVariantCollection