Unity构建WebGL知识点
基础知识:
跨域问题:
- 跨域问题是指在 Web 开发中,浏览器出于安全考虑,限制一个域上的网页访问另一个域上的资源。这种限制是为了防止恶意网站窃取用户数据或进行其他不安全的操作。
- 原因:
- 同源策略:浏览器的安全机制,限制不同源(协议、域名、端口不同)的网页之间的交互。
- 安全性:防止跨站请求伪造(CSRF)和跨站脚本攻击(XSS)。
- 常见的跨域解决方案:
- CORS(跨源资源共享):服务器通过设置 HTTP 头部(如 `Access-Control-Allow-Origin`)来允许特定源访问资源。
- JSONP:通过 `<script>` 标签加载数据,绕过同源策略,但只支持 GET 请求。
- 代理服务器:通过同源的服务器转发请求,避免直接跨域。
- WebSocket:WebSocket 协议不受同源策略限制,可以跨域通信。
CORS 原理:
- 工作原理:
- 预检请求:对于某些类型的请求(如使用 `PUT`、`DELETE` 或自定义头部),浏览器会先发送一个 `OPTIONS` 请求,询问服务器是否允许实际请求。
- 服务器响应:服务器根据请求的来源和请求类型,返回相应的 CORS 头部,指示浏览器是否允许跨域请求。
- 常见的 CORS 头部:
- `Access-Control-Allow-Origin`: 指定允许访问的源(如 `*` 表示所有源,或指定具体的域名)。
- `Access-Control-Allow-Methods`: 指定允许的 HTTP 方法(如 `GET, POST`)
- `Access-Control-Allow-Headers`: 指定允许的自定义头部。
### 示例:
假设有一个前端应用在 `https://example.com`,需要访问一个 API 在 `https://api.example.com`。
1. **前端请求**:
```javascript
fetch('https://api.example.com/data', {
method: 'GET',
headers: {
'Content-Type': 'application/json'
}
})
.then(response => response.json())
.then(data => console.log(data))
.catch(error => console.error('Error:', error));
```
2. **服务器响应**(在 `https://api.example.com`):
```http
HTTP/1.1 200 OK
Access-Control-Allow-Origin: https://example.com
Access-Control-Allow-Methods: GET, POST
Content-Type: application/json
{ "data": "Hello, World!" }
```
- 在这个例子中,服务器通过 `Access-Control-Allow-Origin` 头部允许来自 `https://example.com` 的请求,从而解决了跨域问题。浏览器在收到这个响应后,会允许前端应用访问返回的数据。
音频压缩:
CompressedInMemory | 使用此选项压缩磁盘上的音频,并使其在加载到应用程序内存后保持压缩状态。 | 压缩音频可能会导致延迟,并且在音频播放时不太精确。但是,压缩音频在应用程序中使用的内存比解压音频少。对于不受精度影响的音频(例如背景音乐),最好使用CompressedInMemory。 |
DecompressOnLoad | 使用它来压缩磁盘上的音频,类似于CompressedInMemory,并在加载到应用程序内存时进行解压缩。 | 与压缩音频相比,解压音频使用大量内存,但具有更低的延迟和更大的音频灵活性。使用DecompressedOnLoad处理受精确度影响的音频(例如,角色对话或音效) |
Unity 支持WebGl原理:
- Unity使用emscripten 编译器,把运行时代码(c 或者c++)编译成WebAssembly(Wasm). emscripten的主要优点是它的设计尺寸小,加载时间和内存效率高,并旨在提供接近本地的执行速度. 详细信息( blog post)
- 把 .NET游戏代码,也就是C#脚本转换成WebAssembly,Unity先用IL2CPP转换成 C++ 代码,然后再用emscripten转换成Wasm.
平台支持:
- 不支持多线程,因为js不支持,因此FMOD不支持
- 不支持动态代码生成,需要在编译时添加类型,让类型在编译后已知。
- 不支持socket
资源加载:
WebGL 中的内存 - Unity 手册
AssetBundle打包:
目的是因为assetbundle,可以随时卸载
代码剔除问题:assetbundle中用的类,在主包中剔除了
Unity 自带WebGL工具:
在 Unity 安装文件夹中有几个插件可供参考(位于PlaybackEngines/WebGLSupport/BuildTools/lib
和PlaybackEngines/WebGLSupport/BuildTools/Emscripten/src/library*
中)。
WebGL性能问题:
- 一般来说,WebGL的GPU性能,接近Native App,因为WebGL图形API使用GPU进行硬件加速渲染。唯一有开销的地方是将WebGL API 命令调用和shader,转换为操作系统图形API(通常是Windows上的DirectX, Mac上的OpenGL和Linux)
- 在CPU上,Emscripten将您的代码转换为WebAssembly,其性能取决于您使用的web浏览器。
- 以下是必须注意的其他事项:
- * JavaScript语言不支持多线程或SIMD。
- *任何受益于这些特性的代码都可能比其他代码慢。
- *不能在WebGL脚本中编写线程或SIMD代码,但由于某些引擎部件是多线程或SIMD优化的,它们在WebGL上的性能很低。例如,WebGL Skin既是多线程的,也是simd优化的。
- 提示:要查看Unity如何在非webgl平台上将工作分配给不同线程,请参阅Unity中的新时间线分析器。
- 为了获得最佳性能,在playersetting中将optimization level -> Faster ,设置Exception support -> None
- 在某些情况下,如果希望以较低的帧率运行WebGL内容以减少CPU使用。可以使用Application.targetFrameRate API来执行此操作。当不想限制性能时,将此API设置为默认值-1,而不是设置为较高的值。这允许浏览器在render loop中调整帧率以获得最流畅的动画,并且可能比Unity尝试在main time looping来匹配目标帧率产生更好的结果。
减少构建包的大小:
Classes ordered by ID number - Unity 手册