Version: 2021.1
Embedded Resources on WebGL
Cursor locking and full-screen mode in WebGL

Using WebGL templates

This page requires prior knowledge of JavaScript concepts and terminology.

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. To access WebGL templates, go to Player settings (menu: Edit > Project Settings > Player), set the platform-specific settings to WebGL, and open Resolution and Presentation.

Image of Player Resolution and Presentation window.
Image of Player Resolution and Presentation window.

By default, the WebGL Template setting has two options:

  • Default: A white page with a loading bar on a grey canvas.
  • Minimal: A minimal WebGL template with only the necessary boilerplate code to run the WebGL content.

These built-in HTML pages are useful for testing and demonstrating a minimal Player.

You can also use JavaScript to build and supply your own WebGL templates to host the Player. This is useful for production purposes, so that you can preview the Player hosted in the page where it will eventually be deployed. For example, if the Unity Player content interacts with other elements in the page via the external call interface, you should test it with a page that contains those interacting elements.

Add a WebGL template

To add custom templates to your project, navigate to your Project’s Assets folder and create a folder called WebGLTemplates. Each template is a subfolder within the WebGLTemplates folder. Each template subfolder contains an index.html file along with any other resources the page needs, such as images or stylesheets.

The easiest way to create a new custom WebGL template is to make a copy of the built-in Default or Minimal templates. These are stored in corresponding subfolders under <Unity Installation>/PlaybackEngines/WebGLSupport/BuildTools/WebGLTemplates/. Every Unity Project includes these by default. Copy one and place it in your own Project/Assets/WebGLTemplates folder, and rename it to something meaningful so you can identify your template later.

Templates in your Project’s WebGLTemplates folder appear in the Unity Player Settings’ WebGL Template setting. The name of the template is the same as its folder. To give this option a thumbnail image for easy reference, add a 128x128-pixel image to the template folder and name it thumbnail.png.

Template variables, macros, and conditional directives

During the build process, Unity pre-processes template files and evaluates all macros and conditional directives included in those files. As part of this process, Unity finds and replaces all macro declarations with the values the Editor supplies. Unity automatically pre-processes all .html, .php, .css, .js and .json files in the template folder.

Internal preprocessor variables

The following internal preprocessor variables refer to data in the Project, and Unity assigns value to them at build time according to the values the Editor supplies. Javascript macros and conditional directives can use these internal preprocessor variables.

Variable Type Description
COMPANY_NAME Строка (String) The Company Name defined in the Player Settings.
PRODUCT_NAME Строка (String) The Product Name defined in the Player Settings.
PRODUCT_VERSION Строка (String) The Version defined in the Player Settings.
WIDTH Integer The Default Canvas Width defined in the Player Settings > Resolution and Presentation.
HEIGHT Integer The Default Canvas Height in the Player Settings > Resolution and Presentation.
SPLASH_SCREEN_STYLE Строка (String) This is set to the “Dark” value when Splash Style Player Settings > Splash Image is set to Light on Dark, otherwise it is set to the “Light” value.
BACKGROUND_COLOR Строка (String) Represents the Background Color defined in a form of a hex triplet.
UNITY_VERSION Строка (String) The Unity version.
DEVELOPMENT_PLAYER Boolean This is set to true if the Development Build option is enabled.
DECOMPRESSION_FALLBACK Строка (String) This is set to “Gzip” or “Brotli”, depending on which compression method is used and which decompressor is included in the build. If neither is included, the variable is set to an empty string.
TOTAL_MEMORY Integer The initial size of the memory heap in bytes.
USE_WASM Boolean This is set to true if the current build is a WebAssembly build.
USE_THREADS Boolean This is set to true if the current build uses threads.
USE_WEBGL_1_0 Boolean This is set to true if the current build supports the WebGL1.0 graphics API.
USE_WEBGL_2_0 Boolean This is set to true if the current build supports the WebGL2.0 graphics API.
USE_DATA_CACHING Boolean This is set to true if the current build uses indexedDB caching for the downloaded files.
LOADER_FILENAME Строка (String) This is set to the filename of the build loader script.
DATA_FILENAME Строка (String) This is set to the filename of the main data file.
FRAMEWORK_FILENAME Строка (String) This is set to the filename of the build framework script.
CODE_FILENAME Строка (String) This is set to the filename of the WebAssembly module when the current build is a WebAssembly build, otherwise it is set to the filename of the asm.js module.
MEMORY_FILENAME Строка (String) This is set to the filename of the memory file when memory is stored in an external file, otherwise it is set to an empty string.
SYMBOLS_FILENAME Строка (String) This is set to the filename of the JSON file containing debug symbols when the current build is using debug symbols, otherwise it is set to an empty string.
BACKGROUND_FILENAME Строка (String) This is set to the filename of the background image when the background image is selected in the Player Settings > Splash Image, otherwise it is set to an empty string.

JavaScript macros

JavaScript macros are blocks of JavaScript code in template files, surrounded by three sets of curly brackets. This JavaScript code can use the internal preprocessor variables listed above. These variables are assigned at build time according to the values the Editor supplies. During the build, the preprocessor evaluates all macros and replaces them with the output of the variable.

You can use JavaScript macros to preprocess values supplied by the Editor. These macros can be as complex as you like. They can include multiple operators, loops, functions, and any other JavaScript constructs.

The following example line is from the index.html file used in the Default template:

<div id="unity-build-title">{{{ PRODUCT_NAME }}}</div>

If the value of the Product Name in the Player Settings is set to “My WebGL Game”, the internal preprocessor variable PRODUCT_NAME has the value “My WebGL Game”. In the output index.html file, the line appears as:

<div id="unity-build-title">My WebGL Game</div>

Below is a more complex example from the same index.html template file:

canvas.style.background = "url('" + buildUrl + "/{{{ BACKGROUND_FILENAME.replace(/'/g, '%27') }}}') center / cover";

If the target build folder is called Let’s try WebGL, and a background image is selected in the Player Settings, the internal preprocessor variable BACKGROUND_FILENAME has the value “Let’s try WebGL.jpg”. In the output index.html file, the line changes into:

canvas.style.background = "url('" + buildUrl + "/’Let%27s try WebGL.jpg') center / cover";

Conditional directives

Conditional directives #if, #else, and #endif control whether Unity includes a specific portion of the preprocessed file in the output file, or discards it for the current build.

Code that starts with an #if directive and ends with an #endif directive is called a conditional group. Conditional groups can also include #else directives. Unity evaluates the expression written after the #if as a JavaScript expression. If this expression has a truthy value (that is, a value that translates to true when evaluated in a Boolean context) Unity keeps the line group immediately following the #if directive in the output file. If the #if expression is false, and an #else directive is included in the conditional group, Unity keeps the line group immediately following the #else directive in the output. An example of a conditional group is as follows:

#if EXPRESSION
  // this block is included in the output if EXPRESSION has a truthy value
#else
  // this block is included in the output otherwise
#endif

Evaluated JavaScript expressions can include brackets, logical operators and other JavaScript constructs. Conditional directives can be nested.

Custom user variables

When you select a WebGL template, Unity parses the template and looks for Javascript macros and conditional directives. JavaScript variables are treated as custom user variables if they meet all of the following criteria:

  • They are used inside JavaScript macros and conditional directives.
  • They are not declared in the template code.
  • They are not internal preprocessor variables.

Unity automatically adds these custom user variables to the Resolution and Presentation section in the Player Settings window.

As an example, if you want to control the title of the generated index.html page directly from the Player Settings window, you first need to modify the &lt;title&gt; line of the index.html in your custom template, like this: <title>{{{ PAGE_TITLE }}}</title> After you’ve done this, re-select your custom template. This parses the template again, and you should find a Page Title field in the Resolution and Presentation > WebGL Template section of the Player Settings window.

Image of Resolution and Presentation window with custom template
Image of Resolution and Presentation window with custom template

When you enter text into this field and build your Project, the custom variable PAGE_TITLE used in the template macro automatically becomes the text in the Page Title field.

If you would like to use custom integer or float variables in your macros, use parseInt() or parseFloat() JavaScript functions in your macros to preprocess string values supplied by the Editor. This is because custom user variables are always assigned a string value.

Note: Underscore characters in variable names display as spaces inside the field to improve readability.

Structure of the index.html file

The index.html contains the code necessary to load the build and should include the following:

  • A <canvas> element. Unity runtime uses the <canvas> element to render the application.
  • JavaScript code to download the build loader. For example:
var buildUrl = "Build";
var loaderUrl = buildUrl + "/{{{ LOADER_FILENAME }}}";
var script = document.createElement("script");
script.src = loaderUrl;
script.onload = () => {
  // code for instantiating the build
};
document.body.appendChild(script);`

In this example, {{{ LOADER_FILENAME }}} is automatically resolved by the template preprocessor when the build is generated.

Alternatively, you can download the build loader using a script tag, for example: lang-js <script src="Build/{{{ LOADER_FILENAME }}}"></script>

  • JavaScript code for instantiating a build. Unity builds are instantiated using the createUnityInstance() function, which is defined in the build loader script.

The instantiation function: createUnityInstance()

The createUnityInstance() function creates a new instance of your content. You can use it like this: createUnityInstance(canvas, config, onProgress).then(onSuccess).catch(onError);

This function returns a Promise object, where:

Object Use
canvas Unity runtime uses the canvas object to render the game.
config The config object contains the build configuration, such as the code and data URLs, product and company name, and version. For more information on config definition, see the Build Configuration section on this page.
onProgress(progress) {...} The WebGL loader calls the onProgress callback object every time the download progress updates. The progress argument that comes with the onProgress callback determines the loading progress as a value between 0.0 and 1.0.
onSuccess(unityInstance) {...} The onSuccess callback is called after the build has successfully instantiated. The created Unity instance object is provided as an argument. This object can be used for interaction with the build.
onError(message) {...} The onError callback is called if an error occurs during build instantiation. An error message is provided as an argument.

The createUnityInstance() function is defined in the build loader script and is specific to the instantiated build. Therefore, if you are embedding two or more builds in the same HTML document, make sure that the createUnityInstance() function is called from an onload callback of the corresponding build loader script. For more information about the Unity WebGL Loader, see Building and Running a WebGL Project.

Build configuration

The configuration object contains the build configuration, which consists of code and data URLs, product name, company name, and version. You can define it using the following code:

var buildUrl = "Build";
var config = {
  dataUrl: buildUrl + "/{{{ DATA_FILENAME }}}",
  frameworkUrl: buildUrl + "/{{{ FRAMEWORK_FILENAME }}}",
  codeUrl: buildUrl + "/{{{ CODE_FILENAME }}}",
#if MEMORY_FILENAME
  memoryUrl: buildUrl + "/{{{ MEMORY_FILENAME }}}",
#endif
#if SYMBOLS_FILENAME
  symbolsUrl: buildUrl + "/{{{ SYMBOLS_FILENAME }}}",
#endif
  streamingAssetsUrl: "StreamingAssets",
  companyName: "{{{ COMPANY_NAME }}}",
  productName: "{{{ PRODUCT_NAME }}}",
  productVersion: "{{{ PRODUCT_VERSION }}}",
};

In the example above, the build folder URL is stored as a separate variable called buildUrl. This is useful in cases where you don’t know the relationship between the embedding page and build folder on the hosting server. It enables you to reuse the embedding code in other HTML documents. An example of when to use this is if you move the Build folder to another location on your server. You can adjust the value of the buildUrl variable on the embedding page, and you can use the same embedding code. This also applies to the StreamingAssets folder (streamingAssetsUrl).

Build interaction

After the build has successfully instantiated, the fulfilment handler callback of the Promise object receives the newly created Unity instance object as an argument. To interact with the build, call the following methods of the Unity instance:

Method Use
unityInstance.SetFullscreen(fullscreen) The SetFullscreen method toggles full screen mode. This method does not return a value.
- Full screen mode is activated when the fullscreen argument has a value of 1. *Full screen mode is disabled when the fullscreen argument has a value of 0.
unityInstance.SendMessage(objectName, methodName, value) The SendMessage method sends messages to the GameObjects. This method does not return a value.
- objectName is the name of an object in your Scene.
- methodName is the name of a method in the script, currently attached to that object.
- value can be a string, a number, or it can be empty.
unityInstance.Quit().then(onQuit) The Quit() method can be used to quit the runtime and clean up the memory used by the Unity instance. This method returns a Promise object.
- onQuit callback is called after the build runtime has quit.

  • Updated in 5.6

  • WebGL instance renamed from gameInstance to unityInstance in 2019.1 NewIn20191

Embedded Resources on WebGL
Cursor locking and full-screen mode in WebGL