Allow making hybrid Unity apps, based on web technologies. Windows, MacOS, Android and iOS compatible. With a communication gateway between Unity and Javascript.
This will allow a transparent WebView to be on top of Unity graphics, and will manage communication between Javascript and Unity runtime. Performances are pretty good on iOS and Android.
The WebView part is from this unity package. To enable WebView capabilites, download it and install it into your Unity project.
To be able to use web view properly, html and other assets have to be copied to the device.
This is done automatically by WebViewComponent.cs
.
- Copy
WebViewComponent.cs
intoAssets/App/Scripts/
- Create a new GameObject into your Unity scene.
- Select
WebViewComponent
as a new behavior. - Enter web files to be copied on the device.
- Keep
index.html
on top so it's automatically loaded on startup.
Web files will be copied from Assets/StreamingAssets/webview/
.
Keep a flat file system (no folders).
The communication Gateway is a javascript file to load from the WebView. This file is available as an ES6 javascript module and is also available if you use Solidify lib.
Edit directly method messageFromWebView
into WebViewComponent.cs
(at line 120) to implement your actions into Unity.
For ex :
if (pParameters[0] == @"myAction")
{
gameObject.doThis( pParameters[1], pParameters[2] );
return @"";
}
You can also respond to javascript by a return
if (pParameters[0] == @"myAction")
{
return @"{json: 'yes !'}";
}
Note that you can send complex values thanks to JSON.
Return null
if this is an async action. Then call webViewDirectHandler
to send back answer to the WebView when it's done :
if (pParameters[0] == @"takeScreenshot")
{
StartCoroutine (this.cameraObject.TakePhoto( (value) =>
{
// Now we can send back our answer
this.webViewDirectHandler(
@"{photo:" + value + "}"
);
}));
// We return null here to keep the JS Promise open
return null;
}
- Init your gateway
UnityGateway.initGateway()
an handler is also available because this method is async. - Call your action with
UnityGateway.callUnity('myAction', 'a string parameters', 5)
Important : Javascript is sending commands to Unity through URL parameters. So this is not advice to send Huge data or files. Also, there is no JSON encoding when message are going this way. Only string are received into Unity, you have to parse them manually.
Call this method from Unity to send a message to the WebView WebViewComponent.sendMessageToWebView(@"{message: 'hello from unity', value: 5}")
This is also JSON here.
Listen to messages in javascript, with :
UnityGateway.onMessage = (jsonObject) =>
{
console.log('Message from Unity !', jsonObject);
};
If you are using Solidify lib, onMessage
is a Signal
:
UnityGateway.onMessage.add(this.myHandler, this);
Unity is sending commands to Javascript by injection, so there is nearly no technical limit about size or types.
To know if your webview is running into a Unity environment, check UnityGateway.isUnity == true
.
If you are not in Unity environment, every UnityGateway.callUnity
will respond automatically with a parameter {isUnity: false}
, to avoid blocking.