Skip to content

Interacting with web browsers from within the Unity editor.

License

Notifications You must be signed in to change notification settings

sropelato/UnityBrowserBridge

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

15 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Unity Browser Bridge

When building a Unity project for the web, you can interact with the web browser's JavaScript engine directly from your script code (see WebGL: Interacting with browser scripting).

To test these browser interactions, you need to build the project and run it in the web browser. This can be rather time-consuming as compiling for WebGL tends to take a while.

Unity Browser Bridge (UBB) allows you to test browser interactions directly from the Unity editor.

How does it work?

In a WebGL build, browser interaction is implemented by integrating the functions you defined in the .jslib file into the your script code, which eventually gets translated into JavaScript. Similarly, the browser can invoke methods in your code using the SendMessage function on the Unity instance.

Within the Unity editor, there is no direct way of accessing a JavaScript engine present in web browsers. UBB therefore uses Selenium WebDriver to control a web browser with which your script code interacts.

The remote-controlled browser connects to a local HTTP server from where it loads an interface page including user-defined JavaScript files. Your script code then invokes the ExecuteJS method with the JavaScript command to be executed in the browser. UBB instructs the web driver to execute the command and returns the result as return value (if there is any).

The interface page contains a mockup of the Unity instance (which would be present in a WebGL build) to emulate the SendMessage function. When invoked, the SendMessage function sends a request to the local HTTP server which forwards the message to the corresponding game object on the Unity side. Please note that, like in the real WebGL build, messages from the browser to your script code are unidirectional (i.e. they have no return values). Figure 1 gives a high-level overview of the components involved in the interaction between your project and the web browser.

Overview browser interaction Figure 1: Overview of the interaction between your Unity project and the web browser when compiled into a WebGL build (left) and using Unity Browser Bridge in the Unity editor (right).

How do I use it?

Prerequisites

Here's what you need in order to use Unity Browser Bridge:

Import Unity Browser Bridge

Import UnityBrowserBridge_v1.0.0.unitypackage into your project. Drag the UnityBrowserBridge prefab (in UnityBrowserBridge/Prefabs) into your scene. In the inspector, you can see the following following settings:

Setting Description
Browser The web browser which will be controlled by Unity Browser Bridge. The browser and the web driver must be installed for this to work.
Web Driver Directory Path to the directory in which the web driver is located. If this is left empty, the web driver will be searched on your system's PATH.
HTTP Server Port The port on which the local HTTP server will listen for connections.
Index file The index file opened when the browser connects to Unity Browser Bridge. Changing this may result in UBB not woking properly.
Include JavaScript Files Your JavaScript files included in the WebGL project. The path will first be resolved relative to the Assets directory or, if not successful, as an absolute path.

Configure your script to use Unity Browser Bridge

Assume you want to execute a simple JavaScript command, for example console.log('hello world'), from your script code. For this to work, you need to define this command in the .jslib file. This could look something like this:

mergeInto(LibraryManager.library, {
    PrintHelloWorld: function() {
        console.log('hello world')
    }   
})

In your script code, you would then define the PrintHelloWorld function like this:

[DllImport("__Internal")]
public static extern void PrintHelloWorld();

Now you can call PrintHelloWorld() from anywhere in your script code and it should execute the console.log command above when compiled into a WebGL build.

To make it work in the editor, the PrintHelloWorld() method needs to be changed as follows:

public static void PrintHelloWorld() {
    UnityBrowserBridge.Instance.ExecuteJS("console.log('hello world')");
}

If everything has been configured correctly, running your project in the Unity editor should open a browser window and display the UBB overview page. Turning on Show live browser calls allows you to see the JavaScript commands that UBB executes in the browser, in this example, the console.log('hello world') command.

Screenshot UBB with 'hello world' example Figure 2: Unity Browser Bridge status page displayed in the remote-controlled web browser. It shows a list of included JavaScript files, if any, and a log of commands executed in the browser and messages sent from the browser to Unity. For performance reasons, both logs are disabled by default.

In a next step, you can use Unity's platform-dependent macros to avoid having to change the definition of the PrintHelloWorld function every time you want to build your project:

#if UNITY_WEBGL && !UNITY_EDITOR
    [DllImport("__Internal")]
    public static extern void PrintHelloWorld();
#else
    public static void PrintHelloWorld() {
        UnityBrowserBridge.Instance.ExecuteJS("console.log('hello world')");
    }
#endif

With this in place, your project can be run in the Unity editor and compiled into a WebGL build, both with working browser interaction.

The example project

The example project (UnityBrowserBridgeExample_v1.0.0.unitypackage) contains a sample with a fully-configured UBB setup. It demonstrates how to invoke JavaScript functions with parameters and return types and how to handle function calls from the browser.

Please note that the example project does not include the Unity Browser Bridge implementation. In order to work, the main package UnityBrowserBridge_v1.0.0.unitypackage must be imported as well.

Contents

The WebGLTemplates/UBBExample folder contains all files required to define a WebGL template which will be used when compiling the project to a WebGL build. The file TemplateData/myscript.js is included in the template and defines the functions getDateAndTime and getDateAndTimeAsync which return a formatted date string.

Plugins/BrowserInteraction.json defines the two wrapper functions GetDateAndTime and GetDateAndTimeAsync which will invoke the JavaScript functions in myscript.js.

The controller (Scripts/MainController.cs) handles the calls to the wrapper functions (using UBB when run in the editor, or directly when compiled to WebGL).

The example scene (Scenes/UnityBrowserBridgeExample.scene) contains a simple UI with two buttons to display the current date (Figure 3), a game object with the MainController script, and the UnityBrowserBridge object (from UnityBrowserBridge/Prefabs/UnityBrowserBridge.prefab). Note that the myscript.js file is listed under Include JavaScript Files.

Screenshot UBB example scene Figure 3: Unity Browser Bridge example project. Two buttons can be used to get and display the current date and time from the browser.

How to run the example project

Configure Unity Browser Bridge to use the browser of your choice. Make sure the appropriate web driver is installed. If the executable is not on your system's PATH, set the directory containing the driver executable in Web Driver Directory (Figure 4).

If configured correctly, a browser window displaying the UBB status page should appear when you enter play mode (Figure 5). Pressing the first button, Get Date And Time, invokes the getDateAndTime function which directly returns the formatted date string. Get Date And Time (Async) invokes getDateAndTimeAsync respectively which invokes the SetDateAndTime callback method in MainController.cs (after a 1000 ms delay).

As in the hello world example above, we use Unity's macros to make our code work in the WebGL build as well as in the editor. When compiled to WebGL, GetDateAndTime and GetDateAndTimeAsync are linked to the wrapper functions in BrowserInteraction.json. In the editor, they use Unity Browser Bridge instead. The example shows that ExecuteJS<T>() has a return type T while ExecuteJS() (without the diamond) has no return type:

...

#if UNITY_WEBGL && !UNITY_EDITOR

    [DllImport("__Internal")]
    public static extern string GetDateAndTime(string locale);
    [DllImport("__Internal")]
    public static extern void GetDateAndTimeAsync(string locale);

#else

    public static string GetDateAndTime(string locale) {
	    return UnityBrowserBridge.Instance.ExecuteJS<string>("getDateAndTime('" + locale + "')");
    }

    public static void GetDateAndTimeAsync(string locale) {
		UnityBrowserBridge.Instance.ExecuteJS("getDateAndTimeAsync('" + locale + "')");
	}

#endif

public void SetDateAndTime(string dateAndTimeString) {
    dateAndTimeText.text = dateAndTimeString;
    getDateAndTimeAsyncButton.interactable = true;
}

...

Screenshot UBB configuration Figure 4: Unity Browser Bridge configuration. The web driver executable (here chromedriver) is located in /usr/local/bin which is defined as the Web Driver Directory. The myscript.js file is listed to be included in the web project so its functions can be accessed by Unity Browser Bridge.

Screenshot UBB with example project Figure 5: Unity Browser Bridge status page of the example project with the included myscript.js file. Enabling the live calls shows the browser calls from Unity and the messages sent to Unity.

Of course, the example project can be built as a WebGL project and should show the same behavior like when tested in the Unity editor (Figure 6). Make sure to use the UBBExample WebGL template as it contains the required myscript.js file.

Screenshot example project WebGL Figure 6: Example project compiled to WebGL.

License

The source code, binaries and all included assets of Unity Browser Bridge are released under the MIT license.

Included software

The Selenium framework (used to interact with the web driver) is licensed under the Apache 2.0 license (License file included in Assets/UnityBrowserBridge/Plugins/SeleniumLicense.txt).

jQuery (used in the example WebGL template) is licensed under the MIT license (License file included in Assets/WebGLTemplates/UBBExample/TemplateData/jQueryLicense.txt).