Commit 6e67854c authored by Mahmoud Mostafa's avatar Mahmoud Mostafa

Fixed WebGL Template

parent e40ba054
<!DOCTYPE html> <!DOCTYPE html>
<html lang="en"> <html lang="en">
<head> <head>
<meta charset="utf-8"> <meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no"> <meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no">
<meta name="mobile-web-app-capable" content="yes">
<meta name="apple-mobile-web-app-capable" content="yes">
<title>{{{ PRODUCT_NAME }}}</title> <title>{{{ PRODUCT_NAME }}}</title>
<!-- ═══ ANTI-CACHE ═══ -->
<meta http-equiv="Cache-Control" content="no-cache, no-store, must-revalidate"> <meta http-equiv="Cache-Control" content="no-cache, no-store, must-revalidate">
<meta http-equiv="Pragma" content="no-cache"> <meta http-equiv="Pragma" content="no-cache">
<meta http-equiv="Expires" content="0"> <meta http-equiv="Expires" content="0">
<!-- ═══ PRECONNECT TO CDN — speeds up HLS chunk fetching ═══ -->
<!-- Replace with your actual PeerTube domain -->
<link rel="preconnect" href="https://your-peertube-instance.com" crossorigin> <link rel="preconnect" href="https://your-peertube-instance.com" crossorigin>
<link rel="dns-prefetch" href="https://your-peertube-instance.com"> <link rel="dns-prefetch" href="https://your-peertube-instance.com">
<!-- ═══ PRELOAD HLS.js — starts downloading before Unity even loads ═══ -->
<link rel="preload" href="https://cdn.jsdelivr.net/npm/hls.js@1.5.17/dist/hls.min.js" as="script" crossorigin> <link rel="preload" href="https://cdn.jsdelivr.net/npm/hls.js@1.5.17/dist/hls.min.js" as="script" crossorigin>
<style> <style>
...@@ -25,18 +23,21 @@ ...@@ -25,18 +23,21 @@
box-sizing: border-box; box-sizing: border-box;
} }
html, body { html,
body {
width: 100%; width: 100%;
height: 100%; height: 100%;
overflow: hidden; overflow: hidden;
background: #000; background: #000;
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif; font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
/* Prevent pull-to-refresh on mobile */
overscroll-behavior: none; overscroll-behavior: none;
touch-action: none; touch-action: none;
} }
#unity-container { #unity-container {
position: fixed;
top: 0;
left: 0;
width: 100%; width: 100%;
height: 100%; height: 100%;
display: flex; display: flex;
...@@ -47,16 +48,23 @@ ...@@ -47,16 +48,23 @@
#unity-canvas { #unity-canvas {
background: #000; background: #000;
/* Prevent blurry scaling */
image-rendering: -webkit-optimize-contrast; image-rendering: -webkit-optimize-contrast;
image-rendering: crisp-edges; image-rendering: crisp-edges;
width: 1920px;
height: 1080px;
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
} }
/* ═══ LOADING SCREEN ═══ */ /* ═══ LOADING SCREEN ═══ */
#loading-screen { #loading-screen {
position: fixed; position: fixed;
top: 0; left: 0; top: 0;
width: 100%; height: 100%; left: 0;
width: 100%;
height: 100%;
background: #000; background: #000;
display: flex; display: flex;
flex-direction: column; flex-direction: column;
...@@ -65,20 +73,33 @@ ...@@ -65,20 +73,33 @@
z-index: 1000; z-index: 1000;
transition: opacity 0.5s ease; transition: opacity 0.5s ease;
} }
#loading-screen.fade-out { #loading-screen.fade-out {
opacity: 0; opacity: 0;
pointer-events: none; pointer-events: none;
} }
#loading-logo { #loading-logo {
max-width: 200px; max-width: 200px;
max-height: 200px; max-height: 200px;
margin-bottom: 40px; margin-bottom: 40px;
animation: logoPulse 2s ease-in-out infinite; animation: logoPulse 2s ease-in-out infinite;
} }
@keyframes logoPulse { @keyframes logoPulse {
0%, 100% { transform: scale(1); opacity: 0.9; }
50% { transform: scale(1.05); opacity: 1; } 0%,
100% {
transform: scale(1);
opacity: 0.9;
}
50% {
transform: scale(1.05);
opacity: 1;
}
} }
#loading-bar-container { #loading-bar-container {
width: 280px; width: 280px;
height: 6px; height: 6px;
...@@ -87,6 +108,7 @@ ...@@ -87,6 +108,7 @@
overflow: hidden; overflow: hidden;
margin-bottom: 16px; margin-bottom: 16px;
} }
#loading-bar { #loading-bar {
width: 0%; width: 0%;
height: 100%; height: 100%;
...@@ -95,6 +117,7 @@ ...@@ -95,6 +117,7 @@
transition: width 0.3s ease; transition: width 0.3s ease;
box-shadow: 0 0 10px rgba(254, 215, 0, 0.4); box-shadow: 0 0 10px rgba(254, 215, 0, 0.4);
} }
#loading-text { #loading-text {
color: rgba(255, 255, 255, 0.5); color: rgba(255, 255, 255, 0.5);
font-size: 13px; font-size: 13px;
...@@ -102,132 +125,172 @@ ...@@ -102,132 +125,172 @@
} }
</style> </style>
</head> </head>
<body> <body>
<div id="unity-container"> <div id="unity-container">
<canvas id="unity-canvas" tabindex="-1"></canvas> <canvas id="unity-canvas" tabindex="-1"></canvas>
</div> </div>
<div id="loading-screen"> <div id="loading-screen">
<img id="loading-logo" src="logo.png" alt="Loading"> <img id="loading-logo" src="logo.png" alt="Loading">
<div id="loading-bar-container"> <div id="loading-bar-container">
<div id="loading-bar"></div> <div id="loading-bar"></div>
</div>
<div id="loading-text">Loading...</div>
</div> </div>
<div id="loading-text">Loading...</div>
</div>
<script> <script>
// ═══ 16:9 ASPECT RATIO LOCK ═══ var GAME_W = 1920;
function resizeCanvas() { var GAME_H = 1080;
var container = document.getElementById('unity-container');
var canvas = document.getElementById('unity-canvas'); var canvas = document.getElementById('unity-canvas');
var windowW = window.innerWidth;
var windowH = window.innerHeight; canvas.width = GAME_W;
var targetAspect = 16 / 9; canvas.height = GAME_H;
var windowAspect = windowW / windowH;
var canvasW, canvasH; function applyLayout() {
var winW = window.innerWidth;
if (windowAspect > targetAspect) { var winH = window.innerHeight;
canvasH = windowH; var isPortrait = winH > winW;
canvasW = Math.floor(windowH * targetAspect);
} else { var availW, availH, rotate;
canvasW = windowW;
canvasH = Math.floor(windowW / targetAspect); // If we're on a mobile device and in portrait, we rotate.
// On desktop, we just scale to fit.
if (isPortrait && /iPhone|iPad|iPod|Android/i.test(navigator.userAgent)) {
availW = winH;
availH = winW;
rotate = 'rotate(90deg) ';
} else {
availW = winW;
availH = winH;
rotate = '';
}
var scale = Math.min(availW / GAME_W, availH / GAME_H);
canvas.style.width = GAME_W + 'px';
canvas.style.height = GAME_H + 'px';
canvas.style.transform = 'translate(-50%, -50%) ' + rotate + 'scale(' + scale + ')';
canvas.style.left = '50%';
canvas.style.top = '50%';
canvas.style.position = 'absolute';
} }
canvas.style.width = canvasW + 'px'; window.addEventListener('resize', applyLayout);
canvas.style.height = canvasH + 'px'; window.addEventListener('orientationchange', function () {
canvas.width = canvasW; setTimeout(applyLayout, 200);
canvas.height = canvasH; });
} applyLayout();
window.addEventListener('resize', resizeCanvas); // ═══ FULLSCREEN & ORIENTATION ═══
resizeCanvas(); function tryFullscreen() {
var container = document.documentElement;
// ═══ PRELOAD HLS.js INTO CACHE BEFORE UNITY BOOTS ═══ try {
// This way when the jslib calls ensureHls(), it's already loaded if (container.requestFullscreen) {
(function() { container.requestFullscreen().catch(function (e) { /* silent fail */ });
var hlsScript = document.createElement('script'); } else if (container.webkitRequestFullscreen) {
hlsScript.src = 'https://cdn.jsdelivr.net/npm/hls.js@1.5.17/dist/hls.min.js'; container.webkitRequestFullscreen();
hlsScript.async = true; } else if (container.msRequestFullscreen) {
document.head.appendChild(hlsScript); container.msRequestFullscreen();
})(); }
} catch (err) {
// ═══ UNITY LOADER ═══ console.log("Fullscreen request failed silently.");
var loadingBar = document.getElementById('loading-bar'); }
var loadingText = document.getElementById('loading-text');
var loadingScreen = document.getElementById('loading-screen'); if (screen.orientation && screen.orientation.lock) {
screen.orientation.lock('landscape').catch(function (e) {
// Cache-bust the loader URL in development console.log("Orientation lock failed silently.");
// Remove the timestamp parameter for production });
var buildUrl = "Build"; }
var cacheBust = ""; // Set to "?t=" + Date.now() during development }
var loaderUrl = buildUrl + "/{{{ LOADER_FILENAME }}}" + cacheBust;
// Try immediately (some mobile browsers/environments might allow it)
var config = { tryFullscreen();
dataUrl: buildUrl + "/{{{ DATA_FILENAME }}}",
frameworkUrl: buildUrl + "/{{{ FRAMEWORK_FILENAME }}}", // Fallback: Modern browsers require a user gesture to enter fullscreen or lock orientation
#if USE_WASM document.addEventListener('click', function () {
tryFullscreen();
}, { once: true });
document.addEventListener('touchstart', function () {
tryFullscreen();
}, { once: true });
// ═══ PRELOAD HLS.js ═══
(function () {
var s = document.createElement('script');
s.src = 'https://cdn.jsdelivr.net/npm/hls.js@1.5.17/dist/hls.min.js';
s.async = true;
document.head.appendChild(s);
})();
// ═══ UNITY LOADER ═══
var loadingBar = document.getElementById('loading-bar');
var loadingText = document.getElementById('loading-text');
var loadingScreen = document.getElementById('loading-screen');
var buildUrl = "Build";
var cacheBust = "";
var loaderUrl = buildUrl + "/{{{ LOADER_FILENAME }}}" + cacheBust;
var config = {
dataUrl: buildUrl + "/{{{ DATA_FILENAME }}}",
frameworkUrl: buildUrl + "/{{{ FRAMEWORK_FILENAME }}}",
#if USE_WASM
codeUrl: buildUrl + "/{{{ CODE_FILENAME }}}", codeUrl: buildUrl + "/{{{ CODE_FILENAME }}}",
#endif #endif
#if MEMORY_FILENAME #if MEMORY_FILENAME
memoryUrl: buildUrl + "/{{{ MEMORY_FILENAME }}}", memoryUrl: buildUrl + "/{{{ MEMORY_FILENAME }}}",
#endif #endif
#if SYMBOLS_FILENAME #if SYMBOLS_FILENAME
symbolsUrl: buildUrl + "/{{{ SYMBOLS_FILENAME }}}", symbolsUrl: buildUrl + "/{{{ SYMBOLS_FILENAME }}}",
#endif #endif
streamingAssetsUrl: "StreamingAssets", streamingAssetsUrl: "StreamingAssets",
companyName: "{{{ COMPANY_NAME }}}", companyName: "{{{ COMPANY_NAME }}}",
productName: "{{{ PRODUCT_NAME }}}", productName: "{{{ PRODUCT_NAME }}}",
productVersion: "{{{ PRODUCT_VERSION }}}", productVersion: "{{{ PRODUCT_VERSION }}}",
};
// ═══ MEMORY SETTINGS ═══
// Match what you set in Player Settings var script = document.createElement("script");
// These override if present script.src = loaderUrl;
}; script.onload = function () {
createUnityInstance(
var script = document.createElement("script"); document.getElementById("unity-canvas"),
script.src = loaderUrl; config,
script.onload = function () { function (progress) {
createUnityInstance( var pct = Math.round(progress * 100);
document.getElementById("unity-canvas"), loadingBar.style.width = pct + '%';
config, loadingText.textContent = pct < 100 ? 'Loading... ' + pct + '%' : 'Starting...';
function (progress) { }
var pct = Math.round(progress * 100); ).then(function (instance) {
loadingBar.style.width = pct + '%'; loadingScreen.classList.add('fade-out');
loadingText.textContent = pct < 100 ? 'Loading... ' + pct + '%' : 'Starting...'; setTimeout(function () { loadingScreen.style.display = 'none'; }, 600);
} applyLayout();
).then(function (instance) {
loadingScreen.classList.add('fade-out'); window.addEventListener('beforeunload', function (e) {
setTimeout(function () { e.preventDefault();
loadingScreen.style.display = 'none'; e.returnValue = '';
}, 600); });
resizeCanvas();
}).catch(function (message) {
// ═══ PREVENT ACCIDENTAL NAVIGATION ═══ loadingText.textContent = 'Error: ' + message;
window.addEventListener('beforeunload', function(e) { loadingBar.style.background = '#ff3333';
e.preventDefault(); console.error(message);
e.returnValue = '';
}); });
};
document.body.appendChild(script);
}).catch(function (message) { document.getElementById('unity-canvas').addEventListener('contextmenu', function (e) {
loadingText.textContent = 'Error: ' + message; e.preventDefault();
loadingBar.style.background = '#ff3333';
console.error(message);
}); });
};
document.body.appendChild(script);
// ═══ PREVENT CONTEXT MENU ON CANVAS ═══
document.getElementById('unity-canvas').addEventListener('contextmenu', function(e) {
e.preventDefault();
});
// ═══ FOCUS CANVAS ON CLICK (fixes keyboard input) ═══ document.addEventListener('click', function () {
document.addEventListener('click', function() { document.getElementById('unity-canvas').focus();
document.getElementById('unity-canvas').focus(); });
}); </script>
</script>
</body> </body>
</html> </html>
\ No newline at end of file
fileFormatVersion: 2 fileFormatVersion: 2
guid: 02fd7fb55a304c218c3e0c8fc27670d9 guid: 02fd7fb55a304c218c3e0c8fc27670d9
timeCreated: 1771209097 DefaultImporter:
\ No newline at end of file externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:
...@@ -6,7 +6,7 @@ EditorUserSettings: ...@@ -6,7 +6,7 @@ EditorUserSettings:
serializedVersion: 4 serializedVersion: 4
m_ConfigSettings: m_ConfigSettings:
GraphicsSettingsInspector_UserSettings: GraphicsSettingsInspector_UserSettings:
value: 18134705175a055722080a3115371d4a0d55006876786860616b0471b8b07a68ffab74f9ee2a3a30300cea1a11320d0beb1a0c25f7060f494b4cc80018eb09361fc211cb1f862d19c51d19dcc413d6ade0d8ddfcddf9f4d9d29195fcfde6ebeae6f0a9c9afa6f8c5b89ff7a1aacececac4eba4d7c9d28bda value: 18134705175a055722080a3115371d4a0d55006876786860616b0471b8b07a68ffab74f9ee2a3a30300cea1a11320d0beb1a0c25f7060f494b4cdf1b18f3045e38cb5ad8
flags: 0 flags: 0
RecentlyUsedSceneGuid-0: RecentlyUsedSceneGuid-0:
value: 5500005f0702580d085e5524117b5e444f1549297c2c276374794a65b1b4303a value: 5500005f0702580d085e5524117b5e444f1549297c2c276374794a65b1b4303a
...@@ -21,21 +21,18 @@ EditorUserSettings: ...@@ -21,21 +21,18 @@ EditorUserSettings:
value: 52530450570659030f0b0d751577064441154128742b23692f7d4a61e0b5623d value: 52530450570659030f0b0d751577064441154128742b23692f7d4a61e0b5623d
flags: 0 flags: 0
RecentlyUsedSceneGuid-4: RecentlyUsedSceneGuid-4:
value: 5a08575f5207595a0f5d59741173094444164f7d7d2a23317c7a4465bbe1646d value: 000305555d01595a5c5d082143700911134e1c737b2b7763782c1962b5b3666d
flags: 0 flags: 0
RecentlyUsedSceneGuid-5: RecentlyUsedSceneGuid-5:
value: 000305555d01595a5c5d082143700911134e1c737b2b7763782c1962b5b3666d value: 5a08575f5207595a0f5d59741173094444164f7d7d2a23317c7a4465bbe1646d
flags: 0 flags: 0
RecentlyUsedSceneGuid-6: RecentlyUsedSceneGuid-6:
value: 5305555052020c5a0f5758701670074444151b7c7e7b7164747e4a66bbb6603c
flags: 0
RecentlyUsedSceneGuid-7:
value: 5304575f5c0c51035d5a5e771271594417154e7c2d7b70647b7b4c35bbe1646d value: 5304575f5c0c51035d5a5e771271594417154e7c2d7b70647b7b4c35bbe1646d
flags: 0 flags: 0
RecentlyUsedSceneGuid-8: RecentlyUsedSceneGuid-7:
value: 5701055506000a030f5c542744260844404f4d73797975367c2c1e6ab7e2653d value: 5701055506000a030f5c542744260844404f4d73797975367c2c1e6ab7e2653d
flags: 0 flags: 0
RecentlyUsedSceneGuid-9: RecentlyUsedSceneGuid-8:
value: 0003525055055d020e0b0a7216755d444215417e787d27362e2f4866b2e1323e value: 0003525055055d020e0b0a7216755d444215417e787d27362e2f4866b2e1323e
flags: 0 flags: 0
UnityEditor.ShaderGraph.Blackboard: UnityEditor.ShaderGraph.Blackboard:
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment