【Unity】WebGLで現在のURLを取得する

WebGL環境で現在ページのURLを取得するにはどうすればいいの~?

スクリプトからすぐ得られるわ。Application.absoluteURLプロパティを参照すればいいの。

WebGLゲームで現在表示中のページのURLを取得する方法の紹介です。

URLはApplication.absoluteURLプロパティから取得できます。

var currentURL = Application.absoluteURL;

得られるURLは、クエリパラメータを含むURIです。
また、URLはエスケープされています。

URLを解析して情報を取り出したい場合は、別途解析処理を実装する必要があります。

本記事では、URL取得から解析処理までの方法について解説します。なお、本記事を読み進めるにあたってはUnity C#の基本知識が必要になりますので、予めご了承ください。

動作環境
  • Unity2021.1.21f1

Application.absoluteURLからページのURLを取得する

WebGL環境の場合、Application.absoluteURLプロパティは、現在表示中のページのURLを返却します。

なお、AndroidやiOS、Universal Windows Platform (UWP)プラットフォームでは、ディープリンクが返却されます。詳細は上記リファレンスをご覧ください。

また、Unityエディタ環境では空文字列が返却されるようです。

サンプルスクリプト

CurrentURLExample.cs
using UnityEngine;
using UnityEngine.UI;

public class CurrentURLExample : MonoBehaviour
{
    // 現在のURLを表示するテキスト
    [SerializeField] private Text _urlText;

    private void Start()
    {
        // 現在のURLをテキストに設定
        _urlText.text = Application.absoluteURL;
    }
}

上記スクリプトを適当なゲームオブジェクトにアタッチし、Url TextにURL表示用のuGUIテキストを指定します。

実行結果

取得されるURLはエスケープされた形式

Application.absoluteURLプロパティから得られるURLはエスケープされた形式です。

ブラウザに表示されるURL

https://nekojara.city/search?s=こじゃら

Application.absoluteURLが返却するURL

https://nekojara.city/search?s=%E3%81%93%E3%81%98%E3%82%83%E3%82%89

そのため、エスケープされていないデータを扱いたい場合は、一度エスケープ解除する必要があります。

この辺りの処理は、後述のUriクラスを用いると扱いが楽になります。

取得したURLの解析

取得したURLを解析して情報を取り出したい場合は、.NETのUriクラスを使うと便利です。

Uriクラスは、次のようにインスタンス化して使います。

// Uriインスタンスを生成
var uri = new Uri("https://nekojara.city/search?s=こじゃら");

// エスケープされた「?」を含むクエリパラメータ(?s=%E3%81%93%E3%81%98%E3%82%83%E3%82%89)
var escapedQuery = uri.Query;
// エスケープ解除された「?」を除くクエリパラメータ(s=こじゃら)
var unescapedQuery = uri.GetComponents(UriComponents.Query, UriFormat.Unescaped);

ほかにもポート番号やパスなど様々な情報をUriクラスのプロパティから取得できます。詳細は上記公式ドキュメントをご覧ください。

クエリパラメータの内容を解析する

Uriクラスを使うとURLの様々な情報を取得できますが、クエリパラメータの内容までは解析されません。

例えば、

https://nekojara.city?a=あ&b=い&c=う

の「?」以降のクエリパラメータを、

[a] => あ
[b] => い
[c] => う

というDictionary形式で得る場合です。

本記事では、どの.NETバージョンでも確実に動く、独自解析する方法を紹介します。 [1]

エスケープ解除されたクエリパラメータを取得する

Uri.GetComponents()メソッドから取得できます。紛らわしいですが、これは.NETのUriクラスのGetComponents()メソッドで、UnityのGetComponents()メソッドではありません。

public string GetComponents(UriComponents components, UriFormat format);

第1引数componentsには、取得したいURI要素を指定します。クエリパラメータの場合はUriComponents.Queryを指定します。

第2引数formatには、特殊文字のエスケープ方法を指定します。エスケープ解除された内容を取得したい場合はUriFormat.Unescapedを指定します。

戻り値は、指定された要素の文字列です。クエリパラメータの場合は、「?」以降の部分の文字列になります。

クエリパラメータを解析してDictionary形式で取得する

得られたクエリ文字列を自力で解析してDictionary形式に変換します。

// 「?」より後ろのクエリ文字列取得
// 得られる文字列はエスケープ解除された状態
var queryStr = uri.GetComponents(UriComponents.Query, UriFormat.SafeUnescaped);

// クエリを解析し、Dictionary(Key-Value形式)に変換
var queries = queryStr
    .Split('&') // Key-Valueのペアは「&」で区切られているので分割
    .Select(x => x.Split('=')) // 「Key=Value」の表現なので、「=」でKey-Valueを分割
    .Where(x => x.Length == 2) // Key-Valueの2つ以外は不正とみなす
    .ToDictionary(x => x[0], x => x[1]); // Key-ValueのペアをDictionaryに変換

各処理の説明はコード中のコメントをご覧ください。string.Split()メソッドやLinqを駆使してDictionary形式に変換しています。

クエリを解析するのは面倒だけど、どの環境でも動く確実なやり方なんだね。

サンプルスクリプト

クエリパラメータを解析し、Key-Value形式でテキスト出力するサンプルです。

QueryParseExample.cs
using System;
using System.Linq;
using System.Text;
using UnityEngine;
using UnityEngine.UI;

public class QueryParseExample : MonoBehaviour
{
    // 現在のURLを表示するテキスト
    [SerializeField] private Text _urlText;

    private void Start()
    {
        // 現在のURLからUriインスタンスを生成
        // Unityエディタ環境では空文字でエラーとなることに注意!
        var uri = new Uri(Application.absoluteURL);

        // 「?」より後ろのクエリ文字列取得
        // 得られる文字列はエスケープ解除された状態
        var queryStr = uri.GetComponents(UriComponents.Query, UriFormat.SafeUnescaped);
        
        // クエリを解析し、Dictionary(Key-Value形式)に変換
        var queries = queryStr
            .Split('&') // Key-Valueのペアは「&」で区切られているので分割
            .Select(x => x.Split('=')) // 「Key=Value」の表現なので、「=」でKey-Valueを分割
            .Where(x => x.Length == 2) // Key-Valueの2つ以外は不正とみなす
            .ToDictionary(x => x[0], x => x[1]); // Key-ValueのペアをDictionaryに変換

        // Key-Valueの内容を表示
        var outputText = new StringBuilder();
        foreach (var query in queries)
        {
            outputText.AppendLine($"[{query.Key}] => {query.Value}");
        }

        _urlText.text = outputText.ToString();
    }
}

上記スクリプトを適当なゲームオブジェクトにアタッチし、インスペクタのUrl Textに表示するuGUIのテキストを指定します。

注意
WebGL環境で日本語を表示したい場合、日本語対応したフォントをプロジェクトにインポートする必要があります。その際、ライセンスの扱いには十分ご注意ください。

実行結果

ブラウザのアドレスバーの末尾に、

?a=あ&b=い&c=う

のような文字列を付加して、再度ページをリロードしてください。

成功すると次のようにクエリパラメータのKey-Valueが表示されるようになります。

iframeタグによる埋め込み時の挙動

iframeタグでWebGLが動作するページを埋め込んでいる場合は、埋め込み先のURL(iframeタグのsrc属性に指定されているURL)が現在のURLとして取得されます。

親ページのURLではないことに注意する必要があります。

さいごに

現在表示中のURLを取得するだけならApplication.absoluteURLプロパティを参照するだけなので非常に簡単です。

クエリパラメータの解析は、自分で解析処理を実装する必要がある点は面倒ですが、Uriクラスを使えばエンコードのことを気にする必要がなく少し楽になります。

例えばパラメータに基づいて何かゲームの進行を分岐させたい場合に重宝するかもしれません。

参考サイト