index.html 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500
  1. <!DOCTYPE html>
  2. <html lang="en-us">
  3. <head>
  4. <meta charset="utf-8">
  5. <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
  6. <title>Unity WebGL Player | 万世镜</title>
  7. <link rel="shortcut icon" href="TemplateData/favicon.ico">
  8. <link rel="stylesheet" href="TemplateData/style.css">
  9. <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">
  10. <meta name="screen-orientation" content="portrait">
  11. <script src="https://cdn.jihuigame.com/sdk/h5sdk-1.0.2.js" onerror="console.error('SDK加载失败!')">
  12. </script>
  13. <!-- 保持原有head内容不变 -->
  14. <style>
  15. /* 视口规则建议放在CSS最前面 */
  16. @viewport {
  17. width: device-width;
  18. zoom: 1.0;
  19. }
  20. body,
  21. html {
  22. margin: 0;
  23. padding: 0;
  24. width: 100%;
  25. height: 100%;
  26. overflow: hidden;
  27. background: #000;
  28. touch-action: none;
  29. }
  30. #unity-container {
  31. position: absolute;
  32. width: 100%;
  33. height: 100%;
  34. display: flex;
  35. justify-content: center;
  36. align-items: center;
  37. background: #000;
  38. /* 确保初始状态就居中 */
  39. left: 0;
  40. right: 0;
  41. margin: 0 auto;
  42. /* 添加过渡效果避免闪动 */
  43. transition: opacity 0.3s ease;
  44. opacity: 0;
  45. /* 初始不可见 */
  46. }
  47. /* 基础竖屏尺寸(9:16比例) */
  48. #unity-canvas {
  49. width: 360px;
  50. /* 基准宽度 */
  51. height: 640px;
  52. /* 基准高度 */
  53. background: url('Build/webgl.jpg') center / cover;
  54. /* 确保canvas初始位置正确 */
  55. position: relative;
  56. left: 0;
  57. margin: 0 auto;
  58. }
  59. /* 高质量渲染 */
  60. #unity-canvas {
  61. image-rendering: -webkit-optimize-contrast;
  62. image-rendering: crisp-edges;
  63. -webkit-font-smoothing: subpixel-antialiased;
  64. }
  65. /* 移动端适配 */
  66. @media (max-width: 768px) {
  67. #unity-canvas {
  68. width: 100vw !important;
  69. /* 精确匹配视口宽度 */
  70. height: calc(100vw * 16/9) !important;
  71. /* 强制按比例计算高度 */
  72. max-height: 100vh !important;
  73. /* 确保不超过屏幕高度 */
  74. position: absolute;
  75. left: 0 !important;
  76. right: 0 !important;
  77. }
  78. #unity-container {
  79. width: 100vw !important;
  80. /* 使用视口单位确保精确 */
  81. overflow: hidden;
  82. /* 隐藏任何可能的溢出 */
  83. }
  84. /* 修复iOS Safari的视口问题 */
  85. @supports (-webkit-touch-callout: none) {
  86. #unity-canvas {
  87. height: -webkit-fill-available !important;
  88. }
  89. }
  90. }
  91. /* PC端特殊适配 */
  92. @media (min-width: 769px) {
  93. #unity-canvas {
  94. height: 100vh !important;
  95. /* 独占高度 */
  96. width: calc(100vh * 9/16) !important;
  97. /* 按比例计算宽度 */
  98. }
  99. }
  100. </style>
  101. </head>
  102. <body>
  103. <div id="unity-container" class="unity-desktop">
  104. <canvas id="unity-canvas" width=960 height=600></canvas>
  105. <div id="unity-loading-bar">
  106. <div id="unity-logo"></div>
  107. <div id="unity-progress-bar-empty">
  108. <div id="unity-progress-bar-full"></div>
  109. </div>
  110. </div>
  111. <div id="unity-warning"> </div>
  112. <div id="unity-footer">
  113. <div id="unity-webgl-logo"></div>
  114. <div id="unity-fullscreen-button"></div>
  115. <div id="unity-build-title">万世镜</div>
  116. </div>
  117. </div>
  118. <!-- 添加SDK交互的div -->
  119. <div id="sdk-container" style="display:none;"></div>
  120. <script>
  121. // 全局缩放控制
  122. var currentScale = 1;
  123. var baseWidth = 360; // 基准设计宽度
  124. var baseHeight = 640; // 基准设计高度
  125. window.onload = function () {
  126. var container = document.getElementById("unity-container");
  127. var canvas = document.getElementById("unity-canvas");
  128. function updateCanvasSize() {
  129. var windowWidth = window.innerWidth;
  130. var windowHeight = window.innerHeight;
  131. var gameRatio = baseWidth / baseHeight;
  132. // 立即显示容器(避免闪动)
  133. container.style.opacity = '1';
  134. // 初始强制居中
  135. container.style.left = '0';
  136. container.style.right = '0';
  137. canvas.style.left = '0';
  138. canvas.style.margin = '0 auto';
  139. // PC端特殊处理(高度优先)
  140. if (windowWidth > 768) {
  141. // 按高度计算显示宽度
  142. var displayWidth = windowHeight * gameRatio;
  143. currentScale = windowHeight / baseHeight;
  144. // 更新Canvas物理尺寸(解决模糊)
  145. canvas.style.width = displayWidth + 'px';
  146. canvas.style.height = windowHeight + 'px';
  147. canvas.width = displayWidth * window.devicePixelRatio;
  148. canvas.height = windowHeight * window.devicePixelRatio;
  149. }
  150. // 移动端处理
  151. else {
  152. // 保持原比例缩放
  153. var scale = Math.min(
  154. windowWidth / baseWidth,
  155. windowHeight / baseHeight
  156. );
  157. currentScale = scale;
  158. // 更新Canvas物理尺寸
  159. var displayWidth = baseWidth * scale;
  160. var displayHeight = baseHeight * scale;
  161. canvas.style.width = displayWidth + 'px';
  162. canvas.style.height = displayHeight + 'px';
  163. canvas.width = displayWidth * window.devicePixelRatio;
  164. canvas.height = displayHeight * window.devicePixelRatio;
  165. }
  166. // 强制重绘(解决某些浏览器渲染问题)
  167. if (window.unityInstance) {
  168. window.unityInstance.Module.requestAnimationFrame(() => { });
  169. }
  170. }
  171. // 初始化调整
  172. updateCanvasSize();
  173. window.addEventListener('resize', updateCanvasSize);
  174. window.addEventListener('fullscreenchange', updateCanvasSize);
  175. };
  176. </script>
  177. <script>
  178. var container = document.querySelector("#unity-container");
  179. var canvas = document.querySelector("#unity-canvas");
  180. var loadingBar = document.querySelector("#unity-loading-bar");
  181. var progressBarFull = document.querySelector("#unity-progress-bar-full");
  182. var fullscreenButton = document.querySelector("#unity-fullscreen-button");
  183. var warningBanner = document.querySelector("#unity-warning");
  184. // SDK相关的全局变量
  185. var sdkParams = null;
  186. // 修复鼠标/触摸事件坐标
  187. function fixEventCoordinates(event) {
  188. if (!window.unityInstance) return;
  189. var rect = canvas.getBoundingClientRect();
  190. var scaleX = canvas.width / rect.width;
  191. var scaleY = canvas.height / rect.height;
  192. // 修正坐标
  193. if (event.clientX !== undefined) {
  194. event.unityX = (event.clientX - rect.left) * scaleX;
  195. event.unityY = (event.clientY - rect.top) * scaleY;
  196. }
  197. // 传递修正后的事件给Unity
  198. // if (window.unityInstance.Module) {
  199. // window.unityInstance.Module.handleEvent(event);
  200. // }
  201. }
  202. // 从URL获取SDK参数
  203. function getSDKParamsFromUrl() {
  204. var urlParams = new URLSearchParams(window.location.search);
  205. return {
  206. user_id: urlParams.get('user_id'),
  207. user_name: urlParams.get('user_name'),
  208. uuid: urlParams.get('uuid'),
  209. sign: urlParams.get('sign'),
  210. timestamp: urlParams.get('timestamp'),
  211. cp_ext: urlParams.get('cp_ext')
  212. };
  213. }
  214. // 初始化SDK参数
  215. function initSDKParams() {
  216. sdkParams = getSDKParamsFromUrl();
  217. console.log("SDK Params:", sdkParams);
  218. // 这里可以添加将参数传递给Unity的逻辑
  219. // 例如通过UnityInstance.SendMessage
  220. //if (unityInstance) {
  221. // unityInstance.SendMessage('JHGameSDKGameObject', 'OnInitSDKParams', JSON.stringify(sdkParams));
  222. //}
  223. }
  224. // 显示临时消息横幅
  225. function unityShowBanner(msg, type) {
  226. function updateBannerVisibility() {
  227. warningBanner.style.display = warningBanner.children.length ? 'block' : 'none';
  228. }
  229. var div = document.createElement('div');
  230. div.innerHTML = msg;
  231. warningBanner.appendChild(div);
  232. if (type == 'error') div.style = 'background: red; padding: 10px;';
  233. else {
  234. if (type == 'warning') div.style = 'background: yellow; padding: 10px;';
  235. setTimeout(function () {
  236. warningBanner.removeChild(div);
  237. updateBannerVisibility();
  238. }, 5000);
  239. }
  240. updateBannerVisibility();
  241. }
  242. var buildUrl = "Build";
  243. var loaderUrl = buildUrl + "/webgl.loader.js";
  244. // 监听所有输入事件
  245. ['mousedown', 'mouseup', 'mousemove', 'touchstart', 'touchend', 'touchmove'].forEach(function (eventName) {
  246. canvas.addEventListener(eventName, fixEventCoordinates, { passive: false });
  247. });
  248. var config = {
  249. dataUrl: "Build/webgl.data.gz",
  250. frameworkUrl: "Build/webgl.framework.js.gz",
  251. codeUrl: "Build/webgl.wasm.gz",
  252. streamingAssetsUrl: "StreamingAssets",
  253. companyName: "gfg",
  254. productName: "万世镜",
  255. productVersion: "1.0",
  256. showBanner: unityShowBanner,
  257. devicePixelRatio: window.devicePixelRatio || 1,
  258. preserveDrawingBuffer: true
  259. };
  260. if (/iPhone|iPad|iPod|Android/i.test(navigator.userAgent)) {
  261. // 强制重新计算(解决iOS Safari的1px问题)
  262. canvas.style.width = '100vw';
  263. canvas.style.height = 'calc(100vw * 16/9)';
  264. // 修复Android Chrome的视口问题
  265. setTimeout(() => {
  266. canvas.style.width = '100%';
  267. canvas.style.height = '100%';
  268. }, 100);
  269. } else {
  270. // PC端设置
  271. config.devicePixelRatio = 1;
  272. }
  273. canvas.style.background = "url('" + buildUrl + "/webgl.jpg') center / cover";
  274. loadingBar.style.display = "block";
  275. var script = document.createElement("script");
  276. script.src = loaderUrl;
  277. script.onload = () => {
  278. createUnityInstance(canvas, config, (progress) => {
  279. progressBarFull.style.width = 100 * progress + "%";
  280. }).then((unityInstance) => {
  281. loadingBar.style.display = "none";
  282. window.unityInstance = unityInstance;
  283. fullscreenButton.onclick = () => {
  284. unityInstance.SetFullscreen(1).then(() => {
  285. setTimeout(() => {
  286. // 全屏后重新计算尺寸
  287. canvas.width = canvas.clientWidth * window.devicePixelRatio;
  288. canvas.height = canvas.clientHeight * window.devicePixelRatio;
  289. unityInstance.SendMessage('JSBridge', 'OnFullscreenChanged', '1');
  290. updateCanvasSize();
  291. if (/iPhone|iPad|iPod|Android/i.test(navigator.userAgent)) {
  292. document.getElementById("unity-canvas").style.marginLeft = '0';
  293. }
  294. }, 300);
  295. });
  296. };
  297. // Unity实例加载完成后初始化SDK
  298. initSDKParams();
  299. // 这里可以添加将unityInstance保存为全局变量的代码
  300. window.unityInstance = unityInstance;
  301. setupSDKCallbacks(unityInstance);
  302. }).catch((message) => {
  303. alert(message);
  304. });
  305. };
  306. document.body.appendChild(script);
  307. </script>
  308. <!-- 添加SDK交互的JavaScript代码 -->
  309. <script>
  310. function onSDKLoaded() {
  311. setupSDKCallbacks(window.unityInstance);
  312. }
  313. // 这部分代码将在Unity加载完成后执行
  314. function setupSDKCallbacks(unityInstance) {
  315. // 支付回调示例
  316. window.JHRecharge = function (params) {
  317. console.log("调用支付:", params);
  318. const sdkParams = {
  319. amount: Number(params.amount), // 确保是 Number 类型
  320. cpProductId: params.cpProductId, // cpProductId → cp_product_id
  321. productName: params.productName, // productName → product_name
  322. notifyUrl: "https://webgltest.goufuguiwxw.com/gfg/recharge/jhganmeh5", // notifyUrl → notify_url
  323. serverId: params.serverId, // serverId → server_id
  324. serverName: params.serverName, // serverName → server_name
  325. roleName: params.roleName, // roleName → role_name
  326. roleId: params.roleId, // roleId → role_id
  327. roleLevel: params.roleLevel, // roleLevel → role_level
  328. vipLevel: params.vipLevel, // vipLevel → vip_level
  329. cpOrderId: params.cpOrderId, // cpOrderId → cp_order_id(关键字段)
  330. balance: params.balance, // 确保是 String 类型(文档要求)
  331. extra: params.extra,
  332. fighting: params.fighting
  333. };
  334. // 这里可以添加支付前的Unity交互逻辑
  335. // 例如通知Unity准备支付
  336. if (unityInstance) {
  337. unityInstance.SendMessage('JHGameSDKGameObject', 'OnRechargeStart', JSON.stringify(params));
  338. }
  339. // 调用SDK支付
  340. JHGameSDK.recharge(sdkParams).then(function (res) {
  341. console.log('支付结果:', res);
  342. // 支付完成后通知Unity
  343. if (unityInstance) {
  344. unityInstance.SendMessage('JHGameSDKGameObject', 'OnRechargeComplete', JSON.stringify(res));
  345. }
  346. }).catch(function (error) {
  347. console.error('支付错误:', error);
  348. if (unityInstance) {
  349. unityInstance.SendMessage('JHGameSDKGameObject', 'OnRechargeError', JSON.stringify(error));
  350. }
  351. });
  352. };
  353. // 创建角色回调
  354. window.JHCreateRole = function (params) {
  355. console.log("创建角色:", params);
  356. if (unityInstance) {
  357. unityInstance.SendMessage('JHGameSDKGameObject', 'OnCreateRoleStart', JSON.stringify(params));
  358. }
  359. JHGameSDK.createRole(params).then(function (res) {
  360. console.log('创建角色结果:', res);
  361. if (unityInstance) {
  362. unityInstance.SendMessage('JHGameSDKGameObject', 'OnCreateRoleComplete', JSON.stringify(res));
  363. }
  364. }).catch(function (error) {
  365. console.error('创建角色错误:', error);
  366. if (unityInstance) {
  367. unityInstance.SendMessage('JHGameSDKGameObject', 'OnCreateRoleError', JSON.stringify(error));
  368. }
  369. });
  370. };
  371. // 角色登录回调
  372. window.JHLoginRole = function (params) {
  373. console.log("角色登录:", params);
  374. if (unityInstance) {
  375. unityInstance.SendMessage('JHGameSDKGameObject', 'OnLoginRoleStart', JSON.stringify(params));
  376. }
  377. JHGameSDK.loginRole(params).then(function (res) {
  378. console.log('角色登录结果:', res);
  379. if (unityInstance) {
  380. unityInstance.SendMessage('JHGameSDKGameObject', 'OnLoginRoleComplete', JSON.stringify(res));
  381. }
  382. }).catch(function (error) {
  383. console.error('角色登录错误:', error);
  384. if (unityInstance) {
  385. unityInstance.SendMessage('JHGameSDKGameObject', 'OnLoginRoleError', JSON.stringify(error));
  386. }
  387. });
  388. };
  389. // 角色升级回调
  390. window.JHUpgradeRole = function (params) {
  391. console.log("角色升级:", params);
  392. if (unityInstance) {
  393. unityInstance.SendMessage('JHGameSDKGameObject', 'OnUpgradeRoleStart', JSON.stringify(params));
  394. }
  395. JHGameSDK.upgradeRole(params).then(function (res) {
  396. console.log('角色升级结果:', res);
  397. if (unityInstance) {
  398. unityInstance.SendMessage('JHGameSDKGameObject', 'OnUpgradeRoleComplete', JSON.stringify(res));
  399. }
  400. }).catch(function (error) {
  401. console.error('角色升级错误:', error);
  402. if (unityInstance) {
  403. unityInstance.SendMessage('JHGameSDKGameObject', 'OnUpgradeRoleError', JSON.stringify(error));
  404. }
  405. });
  406. };
  407. // 顶号回调
  408. window.JHRepeatLogin = function () {
  409. console.log("顶号处理");
  410. if (unityInstance) {
  411. unityInstance.SendMessage('JHGameSDKGameObject', 'OnRepeatLoginStart', '');
  412. }
  413. JHGameSDK.repeatLogin().then(function (res) {
  414. console.log('顶号结果:', res);
  415. if (unityInstance) {
  416. unityInstance.SendMessage('JHGameSDKGameObject', 'OnRepeatLoginComplete', JSON.stringify(res));
  417. }
  418. }).catch(function (error) {
  419. console.error('顶号错误:', error);
  420. if (unityInstance) {
  421. unityInstance.SendMessage('JHGameSDKGameObject', 'OnRepeatLoginError', JSON.stringify(error));
  422. }
  423. });
  424. };
  425. // 备案跳转回调
  426. window.JHCallIcpBeian = function () {
  427. console.log("备案跳转");
  428. if (unityInstance) {
  429. unityInstance.SendMessage('JHGameSDKGameObject', 'OnCallIcpBeianStart', '');
  430. }
  431. JHGameSDK.call({ target: "icpbeian" }).then((res) => {
  432. console.log('备案跳转结果:', res);
  433. if (unityInstance) {
  434. unityInstance.SendMessage('JHGameSDKGameObject', 'OnCallIcpBeianComplete', JSON.stringify(res));
  435. }
  436. }).catch(function (error) {
  437. console.error('备案跳转错误:', error);
  438. if (unityInstance) {
  439. unityInstance.SendMessage('JHGameSDKGameObject', 'OnCallIcpBeianError', JSON.stringify(error));
  440. }
  441. });
  442. };
  443. }
  444. </script>
  445. </body>
  446. </html>