Web Player Streaming is critical for providing a great web gaming experience for the end user. The idea behind web games is that the user can view your content almost immediately and start playing the game as soon as possible instead of making them wait for a progress bar. This is very achievable, and we will explain how.
This section will focus on publishing to online game portals. Streaming is useful for all kinds of contents, and it can easily be applied to many other situations.
Online game portals expect that some form of game play really starts after downloading at most 1 MB of data. If you don’t reach this, it makes it that much less likely for a portal to accept your content. From the user’s perspective, the game needs to start quickly. Otherwise their time is being wasted and they might as well close the window.
On a 128 kilobit cable connection you can download 16 KB per second or 1 MB per minute. This is the low end of bandwidth online portals target.
The game would optimally be set up to stream something like this:
The key point to keep in mind is to think in wait times for a user on a slow connection. Never let them wait.
Now, don’t panic if your web player currently is 10 MB. It seems daunting to optimize it, but it turns out that with a little effort it is usually quite easy to structure your game in this fashion. Think of each above step as an individual scene. If you’ve made the game, you’ve done the hard part already. Structuring some scenes around this loading concept is a comparative breeze!
If you open the console log (Open Editor Log button in the Console window(Desktop Platforms); Help -> Open Editor console log menu OSX) after or during a build, you can see the size of each individual scene file. The console will show something like this:
* Player size statistics***
Level 0 'Main Menu' uses 95.0 KB compressed.
Level 1 'Character Builder' uses 111.5 KB compressed.
Level 2 'Level 1' uses 592.0 KB compressed.
Level 3 'Level 2' uses 2.2 MB compressed.
Level 4 'Level 3' uses 2.3 MB compressed.
Total compressed size 5.3 MB. Total decompressed size 9.9 MB.
This game could use a little more optimization! For more information, we recommend you read the reducing file size page.
Load the menu first. Showing an animated logo is a great way to make time go by unnoticed, thus letting the download progress further.
Make the first level be short and not use a lot of assets. This way, the first level can be loaded quickly, and by keeping the player occupied playing it for a minute or two you can be sure that the download of all remaining assets can be completed in the background. Why not have a mini tutorial level where the user can learn the controls of the game? No reason for high-res textures here or loads of objects, or having all your enemies in the first level. Use the one with the lowest poly-count. And yes, this means you might have to design your game with the web player experience in mind.
There is no reason why all music must be available when the game starts. Externalize the music and load it via the WWW class. Unity compresses audio with the high quality codec, Ogg Vorbis. However even when compressed, audio takes up a lot of space, and if you have to fit things into 3 MB, if you have 5 minutes of music all the compression in the world won’t save you. Sacrifices are needed. Load a very short track that you can loop until more music has been downloaded. Only load more music when the player is hooked on the first level.
Optimize your textures using their Import Settings. After you externalize music, textures easily take up 90% of the game. Typical texture sizes are too big for web deployment. In a small browser window, sometimes big textures don’t even increase the visual fidelity at all. Make sure you use textures that are only as big as they must be (and be ready for more sacrifices here). Halving the texture resolution actually makes the texture size a quarter of what it was. And of course all textures should be DXT compressed.
Generally reduce the size of your web players. There is a manual page committed to the utilities Unity offers for optimizing file size here. Although Unity uses cutting edge LZMA-based compression which usually compresses game data to anywhere from one half to a third of the uncompressed size, you’ll need to try everything you can.
Try to avoid Resources.Load. While Resources.Load can be very handy, Unity will not be able to order your assets by when they are first used when you use Resources.Load, because any script could attempt to load the Resource. You can set which level will include all assets that can be loaded through Resources.Load in the Edit->Project Settings->Player using the First Streamed Level With Resources property. Obviously you want to move Resources.Load assets as late as possible into the game or not use the feature at all.
Streaming in Unity is level based, and there is an easy workflow to set this up. Internally, Unity does all the dirty work of tracking assets and organizing them in the compressed data files optimally, ordering it by the first scene that uses them. You simply have to ensure that the first levels in the Build Settings use as few assets as possible. This comes naturally for a “menu level”, but for a good web experience you really need make sure that the first actual game levels the player is going to play are small too.
In order to use streaming in Unity, you select Web Player Streamed in the Build Settings. Then the content automatically starts as soon as all assets used by the first level are loaded. Try to keep the “menu level” to something like 50–100 KB. The stream continues to load as fast as it can, and meanwhile live decompresses. When you look at the Console during/after a build, you can see how large the streamed data is.
You can query the progress of the stream by level, and once a level is available it can be loaded. Use GetStreamProgressForLevel for displaying a progress bar and CanStreamedLevelBeLoaded to check if all the data is available to load a specific level.
This form of streaming is of course linear, which matches how games work in most cases. Sometimes that’s not enough. Therefore Unity also provides you with API’s to load a .unity3d file manually using the WWW class. Video and audio can be streamed as well, and can start playing almost immediately, without requiring the movie to be downloaded first. Finally Textures can easily be downloaded via the WWW class, as can any textual or binary data your game might depend on.
Потоковая загрузка в веб-плеере позволяет начать игру, как только загрузится самая первая сцена с индексом 0. Если в игре 10 уровней, нет смысла заставлять пользователей ждать окончания загрузки всех ассетов для уровней 2–10 перед тем, как они смогут начать играть в первый уровень. Если вы публикуете web-проигрыватель с возможностью потоковой загрузки, ассеты будут скачиваться в порядке, соответствующем файлу сцены, в которой они находятся. Веб-проигрыватель начнёт воспроизведение, как только скачаются все ассеты из сцены с индексом 0.
Проще говоря, со включенной потоковой загрузкой пользователи смогут начать игру быстрее, чем когда-либо.
Необходимо лишь следить за тем, чтобы загрузка новой сцены происходила лишь после завершения потоковой загрузки.
Как правило, вы используете такой код для загрузки уровня в проигрывателях без потоковой загрузки:
Application.LoadLevel("levelName");
В веб-проигрывателе с потоковой загрузкой сперва следует убедиться, что потоковая загрузка уровня завершена. Это осуществляется с помощью метода CanStreamedLevelBeLoaded(). Вот как это работает:
var levelToLoad = 1;
function LoadNewLevel () {
if (Application.CanStreamedLevelBeLoaded (levelToLoad)) {
Application.LoadLevel (levelToLoad);
}
}
Если вы желаете отобразить игроку прогресс потоковой загрузки уровня, то вы можете считывать его с помощью метода GetStreamProgressForLevel() для отображения в шкале загрузки или другом представлении прогресса.
Если для веб-плеера включена опция “Offline Deployment”, то файл UnityObject.js (используемый для взаимодействия плеера со страницей, в которую он интегрирован) будет размещён рядом с плеером во время сборки. Это позволяет плееру работать с локальным файлом скрипта даже без подключения к сети. Обычно UnityObject.js скачивается с веб-сервера Unity для получения самой свежей версии.