作为游戏制作者,将个人游戏风格和创意融入游戏的每一个方面是非常重要的,特别是启动页面,它不仅是玩家的第一印象,也是展示游戏特色和故事的绝佳机会。通过定制启动页面,您可以:
- 展示游戏世界观:利用启动页面介绍游戏的背景故事或世界观,为玩家进入游戏做好铺垫。
- 强化视觉体验:通过精心设计的视觉元素,如艺术插图、动画和颜色方案,可以增强玩家的视觉体验,并与游戏的风格保持一致。
- 提前暗示游戏玩法:通过启动页面上的元素或小互动,可以暗示或简介游戏的核心玩法,激发玩家的好奇心和期待。
由于原生项目只能通过购买Unity的订阅服务
来自定义启动页面,而WebGL项目可以通过HTML的特性来自定义启动页面,因此本文只针对WebGL项目。好了,废话不多说,直接进入主题。
启动阶段
要想自定义启动页面,需要先了解进入游戏前,Unity WebGL
做了哪些工作。
这个阶段可以分为两个小阶段:启动加载和Logo展示
1. 启动加载阶段
在这个阶段,Unity会加载必要的系统和资源,准备运行游戏或应用程序。具体步骤包括:
- 初始化: Unity引擎启动并初始化内部系统,如内存管理、文件系统等。
- 配置加载: 读取项目的配置信息,包括屏幕分辨率、全屏设置、图形质量等。
- 资源预加载: 根据项目设置,加载必要的资源到内存中,这可能包括贴图、模型、声音文件等。
这个阶段的持续时间取决于项目的大小和复杂性,以及用户设备的性能。效果如图:
2. Logo展示阶段
这个阶段会显示Unity的Logo。这个阶段主要是出于品牌宣传的目的,但也给了Unity更多时间在背景加载游戏资源。
- 显示Unity Logo: 显示Unity的Logo,通常持续几秒钟。
- 继续加载资源: 在显示Logo的同时,Unity继续在后台加载游戏的其他资源。
- 过渡到游戏界面: 一旦资源加载足够,Unity会从Logo界面过渡到游戏的主界面或菜单。
这个阶段效果如图:
两个阶段的效果如图:
这两个阶段中:
- 第一个阶段的加载的功能是写在index.html,因此可以直接删除相应节点
- 第二个阶段的Logo展示已经
WebGL
渲染了,改不了,除非你是购买了Unity订阅服务
方案
- 方案一:购买
Unity订阅服务
- 方案二:可以在
Unity Canvas
节点上再盖一层,隐藏掉Unity Canvas
,等到第二阶段结束后再去删掉覆盖的那层,以展示游戏
笔者比较穷,选择方案二😄
要选择方案二,需要了解第二阶段什么时候开始,并且什么时候结束。
- 开始:即第一阶段结束的时候,在
createUnityInstance
方法成功返回的时候
- 结束:通过
Build Settings
->Player
->Splash Image
->Draw Mode(选择All Sequential)
-> Logos 的Logo Duration得知,第二阶段时长设置最小2秒,最长是10秒,默认是2秒。
因此只需要在createUnityInstance
成功返回后,设一个2秒的定时器来删除覆盖在Canvas
节点上的节点。
实现
这里以Unity2021版本为例
首先去掉unity的加载节点,及相应的js代码
html
<div id="unity-container" class="unity-desktop">
<canvas id="unity-canvas" width=960 height=600></canvas>
<!-- 去掉Unity加载节点 和 底部logo显示 -->
<!-- <div id="unity-loading-bar">
<div id="unity-logo"></div>
<div id="unity-progress-bar-empty">
<div id="unity-progress-bar-full"></div>
</div>
</div>
<div id="unity-warning"> </div>
<div id="unity-footer">
<div id="unity-webgl-logo"></div>
<div id="unity-fullscreen-button"></div>
<div id="unity-build-title">unity-minigamesdk-demo</div>
</div> -->
</div>
...
</div>
<script>
var container = document.querySelector("#unity-container");
var canvas = document.querySelector("#unity-canvas");
// 删掉加载画面的js代码
// var loadingBar = document.querySelector("#unity-loading-bar");
// var progressBarFull = document.querySelector("#unity-progress-bar-full");
// var fullscreenButton = document.querySelector("#unity-fullscreen-button");
// var warningBanner = document.querySelector("#unity-warning");
// function unityShowBanner(msg, type) {
// function updateBannerVisibility() {
// warningBanner.style.display = warningBanner.children.length ? 'block' : 'none';
// }
// var div = document.createElement('div');
// div.innerHTML = msg;
// warningBanner.appendChild(div);
// if (type == 'error') div.style = 'background: red; padding: 10px;';
// else {
// if (type == 'warning') div.style = 'background: yellow; padding: 10px;';
// setTimeout(function() {
// warningBanner.removeChild(div);
// updateBannerVisibility();
// }, 5000);
// }
// updateBannerVisibility();
// }
// ...
</script>
在Unity Canvas
节点上添加一个Loading层,以隐藏游戏内容,并添加删除节点的函数
html
<div id="loaderContainer">
<div id="loader">
<div class="dot"></div>
<div class="dot"></div>
<div class="dot"></div>
</div>
<div id="loadingText">Loading...</div>
</div>
<script>
function closeLoading() {
var _0x586046 = document['getElementById']('loaderContainer');
if (_0x586046)
_0x586046['remove']();
}
</script>
给Loading层设置好style和一个简单的css动画
css
@keyframes pulse {
0%, 100% {
opacity: 1;
transform: scale(1);
}
50% {
opacity: 0.3;
transform: scale(0.5);
}
}
@keyframes spin {
from {
transform: rotate(0deg);
}
to {
transform: rotate(360deg);
}
}
#loaderContainer {
background-color: beige;
background: linear-gradient(-45deg, #ee7752, #e73c7e, #23a6d5, #d523c6) 0 0/300% 300%;
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
display: flex;
justify-content: center;
align-items: center;
z-index: 9999;
}
#loader {
display: flex;
width: 100px;
height: 100px;
justify-content: space-around;
align-items: center;
animation: spin 2s linear infinite;
}
.dot {
width: 20px;
height: 20px;
background-color: #23a6d5;
border-radius: 50%;
animation: pulse 1s ease-in-out infinite;
}
.dot:nth-child(2) {
animation-delay: 0.3s;
background-color: #23d5ab;
}
.dot:nth-child(3) {
animation-delay: 0.6s;
background-color: #ee7752;
}
#loadingText {
position: absolute;
margin-top: 140px;
font-size: 16px;
color: #fff;
}
最后在第一阶段结束后,设置一个2秒的定时器,删除新加的Loading层,以展示游戏内容
js
var script = document.createElement("script");
script.src = loaderUrl;
script.onload = () => {
createUnityInstance(canvas, config, (progress) => {
console.info("progress: " + 100 * progress + "%");
}).then((unityInstance) => {
window.unityInstance = unityInstance;
// 第一阶段结束,第二阶段开始,设置关闭Loading层的计时器
setTimeout(() => {
closeLoading();
}, 2000);
}).catch((message) => {
alert(message);
});
};
document.body.appendChild(script);
运行后,最终效果如图: