【Unity】WebGL実行時に新しいタブでURLを開く

WebGLのゲームから新しいタブでページを開く方法ってないの?

プラグインを作る必要があるけど可能だわ!

本記事では、UnityのWebGL製のブラウザゲーム内から新しいタブでURLを開く方法を解説します。

結論を述べると、新しいタブでリンクを開く処理をプラグインとしてJavaScriptで実装し、C#スクリプトからそのJavaScript関数を呼び出すことで実現できます。

Unityでは、指定したURLのページを開くApplication.OpenURL()メソッドが用意されていまが、WebGL環境で呼び出すとゲームのページから移動してしまいます。
プレイ中のゲームを中断させてしまうため、プレイヤーにとって好ましくないでしょう。

古いUnityバージョンではApplication.ExternalEval()メソッド呼び出しだけで実現できたけど、Unity2019.4以降では廃止されているので要注意だわ!

手順が面倒になるけど頑張るしかないねっ!

それでは早速、手順を解説していきます。

JavaScriptプラグインの作成

WebGL用のJavaScriptプラグインは、拡張子が.jslibとして扱われます。
jslibファイルはJavaScriptで記述するソースファイルで、ブラウザのJavaScriptエンジンのAPIを直接呼び出すことが可能です。

ここでは、Assets/Plugins/WebGLディレクトリ配下にOpenNewTab.jslibとしてファイルを作成することにします。

作成したjslibファイルを選択し、Select platforms for pluginWebGLにチェックが付いていなかったら付けます。

JavaScript関数の実装

先に作成したjslibファイルに、新しいタブで指定したURLのページを開く関数を定義していきます。
以下、OpenNewTab関数を定義する例です。

OpenNewTab.jslib
mergeInto(LibraryManager.library, {
    OpenNewTab : function(url) {
        window.open(Pointer_stringify(url));
    }
});

JavaScript関数の追加は、以下公式マニュアルの手順に従っています。

自分で定義する関数は、以下のコメントの部分に複数追加していくことができます。

mergeInto(LibraryManager.library, {
    // ここに関数を実装していく
});

そして、以下の部分で新しいタブを開いています。

window.open(Pointer_stringify(url));

window.open()は、引数に指定されたURLを新しいウィンドウやタブで開くメソッドです。
URLのみを指定した場合、通常は新しいタブでページを開く動作になります。

Pointer_stringify()は、C#文字列をJavaScript文字列へと変換するヘルパー関数です。

これでJavaScript側のプラグイン実装は完了です。

C#スクリプトからJavaScript関数を呼び出す

先に作成したJavaScript関数(例ではOpenNewTab)をC#側から呼び出す処理を実装していきます。

JavaScript関数の公開宣言

まず、プラグインを呼び出すためのエントリポイントの公開宣言をします。

[DllImport("__Internal")]
private static extern void OpenNewTab(string url);

DllImport属性はダイナミックリンクライブラリ(DLL)の関数を公開宣言するためのものです。
引数に指定している文字列“__Internal”静的リンクを示します。
WebGL環境でのjslibファイルは静的リンクとなるため、このような指定をする必要があります。

そして、先に作成した例のOpenNewTab関数をexternで宣言します。
メソッドではない外部関数なのでstaticにします。

関数の呼び出し

次に、公開宣言した関数を呼び出していきます。
ここでは、スペースキーを押下したら新しいタブでページが開くようにしてみます。

サンプルスクリプトは以下のようになります。

TestOpenNewTab.cs
using System.Runtime.InteropServices;   // DllImportを使うために必要
using UnityEngine;

/// <summary>
/// 新しいタブでURLを開くテストスクリプト
/// </summary>
public class TestOpenNewTab : MonoBehaviour
{
    // 新しいタブでURLを開く
#if !UNITY_EDITOR && UNITY_WEBGL
    // WebGLビルドで有効になる
    [DllImport("__Internal")]
    private static extern void OpenNewTab(string url);
#else
    // UnityエディタやWebGL以外のプラットフォームで有効になる
    private static void OpenNewTab(string url) => Application.OpenURL(url);
#endif

    private void Update()
    {
        // スペースキーが押されたら
        if (Input.GetKeyDown(KeyCode.Space))
        {
            // 新しいタブでURLを開く
            OpenNewTab("https://nekojara.city");
        }
    }
}

次のコードで#ifディレクティブで分岐していますが、これはWebGL実行時以外(Unityエディタやそれ以外のプラットフォーム等)ではjslibファイルの関数を参照できず実行エラーとなってしまうのを回避するためです。

    // 新しいタブでURLを開く
#if !UNITY_EDITOR && UNITY_WEBGL
    // WebGLビルドで有効になる
    [DllImport("__Internal")]
    private static extern void OpenNewTab(string url);
#else
    // UnityエディタやWebGL以外のプラットフォームで有効になる
    private static void OpenNewTab(string url) => Application.OpenURL(url);
#endif

ブラウザ上でゲームを実行していないときにApplication.OpenURL()メソッドを呼び出すと、既定のブラウザが立ち上がって新しいタブでページを開きます。

そして、URLを指定して関数を呼び出す部分は以下となります。

OpenNewTab("https://nekojara.city");

ここでは固定の文字列を指定していますが、流用するときは相応しい形に書き換えてください。

一つのスクリプトにまとめているけど、あくまでもサンプルなので、定義場所やクラス構成など設計は各自でしっかり行ってね!

ここまで出来たら、C#スクリプトを適当なゲームオブジェクトにアタッチして完了です。

実行結果

しっかりと新しいタブでウィンドウが開かれていることが確認できます。

さいごに

WebGLのブラウザゲーム内から新しいタブで指定したURLのページを開く方法を解説しました。

Unityバージョンが上がってから、ネイティブプラグインを作成しなければいけなくなった点は面倒ですが、この方法に慣れるとUnity APIだけでは出来ないような高度な挙動をさせることが可能になります。

ご参考にしていただけたらと思います。

参考サイト