3D Unity WebGL animations on mobile – R&D Solutions

3D Unity WebGL animations on mobile

3d-unity-webgl-animations-on-mobile

The concept

When we have a hybrid mobile app (which is essentially an application running in the native browser) and we want to implement 3D interactive animations of some sort, one of the first options, that will pop up, when you do your research is Unity WebGL – this Unity build option allows regular Unity interactive animation to run in a web browser environment.

The WebGL build essentially cross-compiles the Unity runtime code to asm.js Javascript or WebAssembly. WebAssembly is intended to be as fast as native code. Asm.js has already come quite close to that, and WebAssembly narrows the gap further.

 

The obstacles

Not all features of Unity are available in WebGL builds. The most notably differences are:

  • Threads are not supported.
  • WebGL builds cannot be debugged in Visual Studio.
  • WebGL builds use a custom backend for Audio, based on the Web Audio API. This supports only basic audio functionality.
  • No support for virtual keyboards.

We should note, that Unity WebGL is not officially supported on mobile devices. That’s because it works in high end phones and tablets, but the low-end devices may not be powerful enough, may not have the required memory to support the content well, and may not provide fluent experience. If the target group of devices fit in those criteria – there is no problem to use in in production ready software. By default, Unity WebGL shows a warning message, when opening it on mobile, but if we are confident, that the target devices can handle the animation, the message can be disabled.

Unity WebGL is supported in the current versions of most major browsers, however there are differences in the level of support offered by the different browsers.

 

The performance

Many factors affect the performance on the WebGL. In general, we can point out two main categories of performance relations.

  • GPU performance related
    You can expect that the performance of the animation, regarding visualization of the objects and environment is close to that of the native apps, because the WebGL graphics API uses your GPU for hardware accelerated rendering.
  • CPU performance related
    Right now, the default output for the WebGL is asm.js JavaScript. So depending on the JavaScript engine of the browser you are using – you can expect pretty significant differences of the performance. If the browser make use of the asm.js spec, the delivered performance is no more than x2 slowdown compared to native code. If the browser can’t benefit from asm.js, the performance is expected to be worse.

As of Unity 5.6 – there is an experimental option to export to WebAssembly version of WebGL. Unity plans to switch the default output to WebAssembly bytecode once the feature becomes available in browser releases. On browsers that don’t support the feature, the bytecode can very efficiently be translated to text-based asm.js code using JavaScript.

A demo WebAssembly version managed to reduce the generated asm.js JavaScript code from 19 MB down to 6.3 MB. In this case, the amount of data needed to be processed by the browser is reduced by factor x3. The compressed download size is alo reduced by factor x1.4.

  • SIMD and Multi-threading
    JavaScript does not support multi-threading nor SIMD (Single instruction, multiple data). If your code uses any of them in a feature, they will see bigger slowdown then other code.
  • Memory
    The WebGL content run inside a browser, so the memory for the animation is allocated by the browser, within the browser’s memory space

    • Unity Heap
      This is where the state of the animation is stored. This includes managed and native objects, currently loaded assets and currently loaded scenes. This memory is configurable by the Unity WebGL player settings. The best setup is to keep the allocated memory to the lowest possible amount, that is enough to run the animation.
    • Asset Data
      Because WebGL doesn’t have access to a real file system, Unity writes a .data file in the browser memory, to contain all the scenes and assets of the animation during the run.
    • Memory needed to parse the code
      The Unity generated Javascript files can easily reach millions of lines of code. Depending on the Javascript engine, when loading the content, can reach to several Gigabytes on some cases. Using WebAssembly eliminate this problem.
    • Large-Allocation Http Header
      Currently this feature is only supported by Firefox – the server can use the “Large-Allocation” http header. This will tell the browser the exact memory need for the animation, and by doing so – the browser can make sure that the large memory needs are provided.

 

Interacting with browser scripting

    • Calling JavaScript functions from Unity scripts
      To use browser JavaScript in your animation – add JavaScript sources to the project, and call the functions from the script code.
      Plugin code example:

      mergeInto(LibraryManager.library, {
      
         Hello: function () {
      
            alert(“Hello, world!”);
      
         }
      
      });

      Then you call the javascript functions from the C# script:

      using UnityEngine;
      using System.Runtime.InteropServices;public class NewBehaviourScript : MonoBehaviour {
      
         [DllImport(“__Internal”)]
         private static extern void Hello();
      
         void Start() {
            Hello();
         }
      }
  • Calling Unity scripts functions from JavaScript
    You need to call methods of GameObjects in your content.

    SendMessage(objectName, methodName, 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 can be empty.

 

Touch support

While Unity WebGL does not officially support mobile devices yet, Input.touches, Input.acceleration and related APIs are implemented on browsers and devices with touch support.

Talk to us now

Contact us