mirror of
https://github.com/hanzo-templates/unity-webgl.git
synced 2026-10-30 20:51:58 +00:00
A real Unity WebGL build served with COOP/COEP, so crossOriginIsolated === true
and SharedArrayBuffer is available — the gate a multithreaded Unity build needs.
Declaring framework=unity on the project is what turns those headers on
(clients/projects.crossOriginIsolated), plus the application/wasm and
application/octet-stream MIME types the Unity loader requires.
Build payload is the example Unity WebGL build from Marinerer/unity-webgl
(Apache-2.0), renamed with a content hash; no Unity licence is needed to use or
swap it.
Why this exists: static-SPA builders cannot ship a game. Proving hanzo.app can
meant finding what actually stopped it, and three things did:
1. POST /v1/projects/:slug/deploy carries the entire build in ONE request body
and the public edge caps a body at 4 MiB (measured: 4194304 accepted,
4198400 gets the opaque fasthttp "Error when parsing request"). Godot emits
a 43 MB engine wasm; Unity 22 MB + 5.7 MB of data. The artifact lane cannot
express a game at all, so these ship through the release lane instead: stage
to the object store, then POST /v1/sites/:slug/publish promotes it
server-side with no body.
2. Engine loaders emit NON-fingerprinted filenames (index.js, <name>.loader.js)
and clients/sites.CacheControlFor only marks a content-hashed name
immutable. A redeploy therefore leaves the CDN and the browser running the
OLD loader against the NEW wasm. That is not a visible error: emscripten
prints "still waiting on run dependencies" forever and the canvas stays
300x150. Every template here fingerprints its own asset names so the case
cannot recur.
3. A cross-origin-isolated document (COEP: require-corp) BLOCKS a plain
cross-origin script, so the shared a.hanzo.ai runtime needs
crossorigin="anonymous" on exactly the pages that opt into isolation.
Co-authored-by: Hanzo Dev <[email protected]>
17 lines
1.4 KiB
CSS
17 lines
1.4 KiB
CSS
body { padding: 0; margin: 0 }
|
|
#unity-container { position: absolute }
|
|
#unity-container.unity-desktop { left: 50%; top: 50%; transform: translate(-50%, -50%) }
|
|
#unity-container.unity-mobile { position: fixed; width: 100%; height: 100% }
|
|
#unity-canvas { background: #231F20 }
|
|
.unity-mobile #unity-canvas { width: 100%; height: 100% }
|
|
#unity-loading-bar { position: absolute; left: 50%; top: 50%; transform: translate(-50%, -50%); display: none }
|
|
#unity-logo { width: 154px; height: 130px; background: url('unity-logo-dark.png') no-repeat center }
|
|
#unity-progress-bar-empty { width: 141px; height: 18px; margin-top: 10px; margin-left: 6.5px; background: url('progress-bar-empty-dark.png') no-repeat center }
|
|
#unity-progress-bar-full { width: 0%; height: 18px; margin-top: 10px; background: url('progress-bar-full-dark.png') no-repeat center }
|
|
#unity-footer { position: relative }
|
|
.unity-mobile #unity-footer { display: none }
|
|
#unity-webgl-logo { float:left; width: 204px; height: 38px; background: url('webgl-logo.png') no-repeat center }
|
|
#unity-build-title { float: right; margin-right: 10px; line-height: 38px; font-family: arial; font-size: 18px }
|
|
#unity-fullscreen-button { cursor:pointer; float: right; width: 38px; height: 38px; background: url('fullscreen-button.png') no-repeat center }
|
|
#unity-warning { position: absolute; left: 50%; top: 5%; transform: translate(-50%); background: white; padding: 10px; display: none }
|