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エディタ環境では空文字列が返されるようです。
サンプルスクリプト
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形式でテキスト出力するサンプルです。
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のテキストを指定します。
実行結果
ブラウザのアドレスバーの末尾に、
?a=あ&b=い&c=う
のような文字列を付加して、再度ページをリロードしてください。
成功すると次のようにクエリパラメータのKey-Valueが表示されるようになります。
iframeタグによる埋め込み時の挙動
iframeタグでWebGLが動作するページを埋め込んでいる場合は、埋め込み先のURL(iframeタグのsrc属性に指定されているURL)が現在のURLとして取得されます。
親ページのURLではないことに注意する必要があります。
さいごに
現在表示中のURLを取得するだけならApplication.absoluteURLプロパティを参照するだけなので非常に簡単です。
クエリパラメータの解析は、自分で解析処理を実装する必要がある点は面倒ですが、Uriクラスを使えばエンコードのことを気にする必要がなく少し楽になります。
例えばパラメータに基づいて何かゲームの進行を分岐させたい場合に重宝するかもしれません。