Unity: Build and Deploy WebGL Game

One of the competitive advantages of using a game engine is in-built support for multiple platforms. “Write once, run anywhere” — a phrase, usually associated with Java-based applications, is indeed applicable for Unity as well. In this tutorial I’ll show you how easy, but not exactly straightforward it is to build and deploy your game to a website.

Prerequisites

I’m using Unity 2021.2.13. This tutorial will re-use the code from my previous one — Unity: Create your own Wordle in under 24 hours. Make sure to check it beforehand.

As always, project sources are available at GitHub, find the link at the end of the page.

There are 3 parts in this tutorial: Unity setup, Deploying and custom templates and a Bonus section about how to change the previously developed Wordle Clone game to allow endless gameplay with no daily limit.

Part 1. Unity setup

First of all we should set up the Editor to support WebGL as a platform. Conveniently, with the help of Unity Hub it is a trivial task:

  1. Press on the Editor version
  2. Press on the “Add platform” button
  3. Select WebGL Build Support and install it

Once installation is complete and Unity is open we should switch the Platform to WebGL in the Build Setting menu:

Re-importing of assets and recompilation of scripts might take a few minutes. Once complete, your project is now ready to be built and deployed.

Part 2. Deploying and custom templates

Before moving on to the build and deployment processes let’s first understand what we are about to build here.
Let me quote one of the Unity Documentation pages:

When you build a WebGL project, Unity embeds the Player in an HTML page so a browser can open it. A WebGL template is a configuration setting that allows you to control what this HTML page looks like, so that you can test, demonstrate, and preview your WebGL application in the HTML page.

In other words, we are about to build an HTML page with certain in-built JavaScript components (aka WebGL).
Luckily, you don’t need to be a guru of JS in order to create a WebGL game — Unity takes care of it mostly.
Let’s go ahead and build the game now:

Note! I’ve pre created the Web folder in advance.

The very first build usually takes quite some time as Unity needs to compile all the artifacts. Subsequent builds are usually just a couple of seconds long.
Looking at the the Web folder content we can see:

  • Build folder — which contains the game itself (js files)
  • TemplateData folder — which contains logos and style.css
  • index.html — the HTML page that will display the game

If you try to open the index.hml page in your browser now the following error will be displayed:

The error is quite clear — the artifacts that were created are meant to be run in a web container. If you already have a website you can go ahead and upload the content of the Web folder directly there. Otherwise, you need to use the “Build and Run” option which will spin up a web container that is capable of running the game on your localhost:

Well, it doesn’t look right. That’s where we should look deeper into Player Settings. There, under the Resolution and Presentation tab you can find the currently selected WebGL template as well as the default Canvas sizes:

As you can see, the default width is 960 and the default height is 600. Since our game is in the Portrait orientation width should be smaller than height, so let’s try to swap them and rebuild the project.

Now it already looks way better! We can play with the sizes further, till the game is properly displayed in your browser. But there is a better solution — custom templates.

From all the available templates, I’d recommend using A Better Unity WebGL one, with a few modifications applied. But first, we should import it to our project. Get the Unity 2020 version unitypackage file from the Releases page, and import it. The new folder — WebGLTemplates will be created under Assets:

Looking into the Better2020 folder you will see the already familiar TemplateData folder and index.html file. Additionally, you can customize a loading logo, a thumbnail, and a favicon. Before we build the very final version of the game let’s apply a few changes to the template.

  1. As per this GitHub issue, in order to make the game size responsive we will add a few lines into Assets/WebGLTemplates/Better2020/TemplateData/style.css:
#unity-container {
width: 100%;
height: 100%;
display: flex; /* added */
justify-content: center; /* added */
align-items: center; /* added */
}
#unity-canvas {
width: 100%;
height: 100%;
max-width: 461px; /* added */
max-height: 738px; /* added */
}

2. Since we want the game to look good on mobile too, as per this GitHub issue we will add one line in Assets/WebGLTemplates/Better2020/index.html:

if (/iPhone|iPad|iPod|Android/i.test(navigator.userAgent)) {
container.className="unity-mobile";
config.devicePixelRatio=Math.min(config.devicePixelRatio, 2); // added
}

Lastly, go to Player Setting and make sure that the Better2020 WebGL Template is selected. I also prefer to hide the full screen button:

Note! Default Canvas sizes have no effect on the final template.

Now hit the “Build and Run” button to check the final result:

You can now go ahead and upload the artifacts to your website. I prefer to use WinSCP for that, just copy the content of the Web folder as is and check the result in your browser.

Before wrapping up the tutorial here, I want to quickly show you how to introduce an endless gameplay with no daily limit into this game.

Part 3. Bonus. Endless Wordle.

There are just a few minor changes needed in order to make the game playable endlessly.
First, we should delete the PlayerPrefsUtils script together with its usages as well as the “Come tomorrow” screen. Next, we will add a Play button to the Statistic screen:

Conveniently, all the logic about handling current word to be guesses was already implemented previously. Thus, the button’s sole purpose will be to restart the current scene:

The only missing piece here is to handle the case when a user runs out of the words. In order to cover it, we will add a TextMesh (inactive by default) to inform a player that the game is now finished.
Then, once the current game is over we need to check if there are more words available to guess and react accordingly:

Final result after all the changes:

Afterwards

Well done finishing the tutorial! Now you know how to make a WebGL version of your game.

Should you have any questions please leave them in the comments section below.

The project source files can be found at this GitHub repository. For WebGL support check out this commit and for the Bonus part check out this branch.

You can check it all in action in the games:

  • Datele — a spin-off where you are guessing a date instead of a word
  • Categorle — a variant where you are guessing a word 4–7 letters long in a given category

For the most comprehensive list of Wordle-like games and resources online be sure to check out this page.

Support

If you like the content you read and want to support the author — thank you very much!
Here is my Ethereum wallet for tips:
0xB34C2BcE674104a7ca1ECEbF76d21fE1099132F0

--

--

--

Serious software engineer with everlasting passion for GameDev. Dreaming of next big project. https://pudding.pro

Love podcasts or audiobooks? Learn on the go with our new app.

Recommended from Medium

Linking Xcode and GitHub

chain links

Learn to code a website from scratch

Setting up test data for browser tests ⚡

Which analysis should you use — SWOT or RAID?

Commonly used Linux Commands you should know 3

#007 Orlando thinks: Wordle is great for learning to code

A man playing “Wordle” on an iPhone and the title art of the article “Orlando thinks #007”

Criminal Lawyer Utah

20 Array Coding Problems for Interview Preparation

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store
Pudding Entertainment

Pudding Entertainment

Serious software engineer with everlasting passion for GameDev. Dreaming of next big project. https://pudding.pro

More from Medium

Script communication in unity using GetComponent:

Saving Data in Unity3D Using PlayerPrefs

Sphere Scene in Unity URP

A low-poly knight 3D model!