Breaking changes in 3D WebView v4

3D WebView v4 brings some exciting new APIs and improvements, and you can read the full list of changes in the release notes. This article focuses only on the small set of breaking changes introduced in v4.0. Overall, I try hard not to introduce breaking changes because I want upgrading to be as easy as possible. However, I believe that the few changes described in this article are worthwhile because they make 3D WebView significantly easier to use. Here are links to each of the changes described:

New directory structure

Who's impacted: This is the only breaking change that impacts all applications upgrading from older versions.

3D WebView v4 has a new and improved directory structure (more on that below). Because of that, if a project is upgrading to v4 from an older version, it's necessary to delete the existing Assets/Vuplex/WebView directory before upgrading. The good news is that v4 automatically detects when it is installed into a project that contains an older version and prompts the user for permission to delete the existing WebView directory, like this:

v4 migration prompt

When 3D WebView shows you this prompt, simply click the "Yes" button to allow it to delete the WebView directory. After that, please import the new v4 package back into the project a second time to complete the upgrade. Or if you'd rather import the v4 package only once, you can manually delete the WebView directory ahead of time prior to importing the package.

More details on the new directory structure

Prior to v4, 3D WebView's directory tree was organized by asset type (Scripts, Plugins, etc.) and then package name (Android, iOS, etc.), like this:

WebView/
    Editor/
        Android/
        iOS/
        Common/
        ...
    Materials/
        Android/
        iOS/
        Common/
        ...
    Plugins/
        Android/
        iOS/
        ...
    ...

While this structure was fine in the beginning when there were only two 3D WebView packages (Android and iOS), there are now six different 3D WebView packages (soon to be seven!), and this structure makes it difficult to remove one 3D WebView package without affecting the others. So starting in v4, 3D WebView's directory structure is now organized in the reverse order—by package name (Android, iOS, etc.) and then asset type (Scripts, Plugins, etc.), like this:

WebView/
    Android/
        Editor/
        Materials/
        Plugins/
        ...
    Core/
        Editor/
        Materials/
        ...
    iOS/
        Editor/
        Materials/
        Plugins/
        ...
    ...

The WebView/Core directory is the set of core assets shared by all 3D WebView packages, which were previously contained in folders named "Common".

"Resolution" moved from IWebView to the prefabs

Who's impacted: This change only impacts applications that call IWebView.SetResolution() or read IWebView.Resolution. Applications that use the InitialResolution field of WebViewPrefab or CanvasWebViewPrefab are not impacted.

In v4, the concept of "resolution" (the number of pixels per Unity unit) has been removed from IWebView and is now solely part of the prefabs (WebViewPrefab and CanvasWebViewPrefab). The impact is that if your application calls IWebView.SetResolution(), then you'll need to update it to set WebViewPrefab.Resolution or CanvasWebViewPrefab.Resolution instead, like this:

// Before (v3):
webViewPrefab.WebView.SetResolution(1000);

// After (v4):
webViewPrefab.Resolution = 1000;

If your application is using IWebView.SetResolution() or IWebView.Resolution, 3D WebView v4 generates a compiler error that instructs you to switch to WebViewPrefab.Resolution or CanvasWebViewPrefab.Resolution. Here are some additional details:

Rationale for moving Resolution from IWebView to the prefabs

In retrospect, the concept of "resolution" (pixels per Unity unit) should have always been part of the prefabs instead of IWebView itself. IWebView represents the browser, which has no inherent tie to physical Unity units like WebViewPrefab and CanvasWebViewPrefab do, and having the concept of resolution in IWebView added unneeded complexity for applications that create IWebViews directly with Web.CreateWebView() (rather than using WebViewPrefab or CanvasWebViewPrefab). I found that when developers use Web.CreateWebView(), they often just want to create a webview with a certain size in pixels and interact with it using coordinates in pixels, and the overhead of needing to deal with resolution and Unity units added unnecessary obstacles.

IWebView.Scroll() units changed

Who's impacted: This change only impacts applications that call IWebView.Scroll().

As described in the section above, the concept of "resolution" was moved from IWebView to the prefabs in v4, so IWebView no longer has a notion of Unity units. So in v4, the units for IWebView.Scroll(Vector2) have been changed from Unity units to a normalized value. The affect is that if your application calls IWebView.Scroll(), then upgrading to v4 may cause the page to scroll less or more than it previously did. To simplify scrolling, 3D WebView v4 also includes a new IWebView.Scroll(int, int) method that you can use to scroll by an amount in pixels instead. Here's an example of what calling IWebView.Scroll() looks like in v3 vs v4:

var scrollXInPixels = 10;
var scrollYInPixels = -25;

// Before (v3):
var scrollDeltaInPixels = new Vector2(scrollXInPixels, scrollYInPixels);
var scrollDeltaInUnityUnits = scrollDeltaInPixels / webView.Resolution;
webView.Scroll(scrollDeltaInUnityUnits);

// After (v4):
webView.Scroll(scrollXInPixels, scrollYInPixels);

// A second approach in v4, using a normalized value instead:
Vector2 scrollDeltaNormalized = webView.PointToNormalized(scrollXInPixels, scrollYInPixels);
webView.Scroll(scrollDeltaNormalized);

IWebView.Init() signature changed

Who's impacted: This change only impacts applications that create an IWebView directly with Web.CreateWebView() rather than using a WebViewPrefab or CanvasWebViewPrefab.

Prior to v4, the signature for IWebView.Init() looked like this:

void Init(Texture2D texture, float widthInUnityUnits, float heightInUnityUnits);

In v4, it has been simplified to:

Task Init(int widthInPixels, int heightInPixels);

So, v4 brings the following changes to IWebView.Init():

  • The texture parameter has been removed because the IWebView now creates its own texture automatically.
  • The width and height parameters are now in pixels instead of Unity units.
  • It's now asynchronous and returns a Task that completes when initialization has finished.

Here's an example of what calling IWebView.Init() looks like in v3 vs v4:

var widthInPixels = 1800;
var heightInPixels = 600;

// Before (v3):
float resolution = 1300;
var texture = await Web.CreateTexture(1, 1);
var widthInUnityUnits = widthInPixels / resolution;
var heightInUnityUnits = heightInPixels / resolution;
webView.Init(texture, widthInUnityUnits, heightInUnityUnits);

// After (v4):
await webView.Init(widthInPIxels, heightInPixels);