🤳 UnityのWebGLでスマホ判定
WebGLでPCとスマホの両方から使うコンテンツを作っていて、スマホの判定をする必要があったので実装してみたものの、つまづきどころがいくつかあったので次回困らないようにメモ。
実装方法は以下。
Unityでユーザーエージェントを受け取るためのプラグインを作成する
まずは /Assets/Plugins/
に GetUserAgent.jslib
というファイルを作って、Unityにメッセージを送信するプラグインを作成します。
mergeInto(LibraryManager.library, {
GetUserAgent: function () {
window.unityInstance.SendMessage('UAChecker', 'SetUserAgent', window.navigator.userAgent.toLowerCase())
},
});
テンプレートHTMLを作成+設定する
上記.jslib
を使ってUnityにメッセージを送信するのですが、グローバル変数にunityInstance
が無いとSendMessage
がUnityまで届かないので、createUnityInstance
後の返り値であるunityInstance
をグローバル変数に設定するようにテンプレートを修正します。
/Assets/WebGLTemplates/TestUAChecker/
に一旦ビルドしたファイル群をコピーして、index.html
を編集します。
script.onload = () => {
createUnityInstance(canvas, config, (progress) => {
progressBarFull.style.width = 100 * progress + "%";
}).then((unityInstance) => {
loadingBar.style.display = "none";
window.unityInstance = unityInstance;//<--追加分
fullscreenButton.onclick = () => {
unityInstance.SetFullscreen(1);
};
}).catch((message) => {
alert(message);
});
};
あとは、 Edit > Project Settings > Player > Resolution and Presentation でWebGLビルドの際に上記で作成したテンプレートを使用するように設定しておきます。
C#スクリプトからプラグインを呼び出す
あとはプロジェクト内で実際に動かすスクリプト、UAChecker.cs
を作成します。
using System.Runtime.InteropServices;
using UnityEngine;
public class UAChecker : MonoBehaviour
{
[DllImport("__Internal")]
private static extern void GetUserAgent();
public static string ua { get; private set; } = "";
void Start()
{
#if (UNITY_WEBGL && !UNITY_EDITOR)
GetUserAgent();
#endif
}
public void SetUserAgent(string value)
{
#if (UNITY_WEBGL && !UNITY_EDITOR)
ua = value;
#endif
}
public static bool IsSmartPhone
{
get
{
return ua.Contains("iphone") || ua.Contains("android");
}
}
}
ゲーム開始時にGetUserAgent
を実行したら、JavaScript側からSetUserAgent
が返ってくるので、送られてきたユーザーエージェントを保存しているだけです。
.jslib
ではUACheckerという名前をつけたGameObjectにSendMessage
するように記載したので、UACheckerという名前をつけたGameObjectを作成してこのスクリプトをアタッチしておきます。
スマートフォンのチェックはUAChecker.IsSmartPhone
を実行すると、保存されているユーザーエージェントから判定して真偽値を受け取れるようになっています(他の判定がしたい時にもプラグインを修正する手間を省きたいのでこんな作りにしています)。
if(UAChecker.IsSmartPhone)
{
//スマホの場合の挙動
};
UAChecker
にユーザーエージェントが保存された後にしか正しい値が帰ってこないので、Start
以降に参照する必要があります。
スクリプトの実行順を設定する
それで、最初の話に戻るのですが何につまづいたかというと、
- ユーザーエージェントのチェックをしたいスクリプト達がUACheckerを参照する時に、まだ初期化されていない事がある
- 上記理由からUACheckerが最初に動いてほしいので
Awake
、OnEnable
に入れてみたものの、まだunityInstance
が準備されていないみたいで動作せず - 仕方なしに
Start
にGetUserAgent
を記載 - それだとやはり使う側の
Start
が先に実行されてしまう事がある
という流れで正しい値が取れてなくてオヤっとなったのですが、スクリプトの実行順を設定する事で解決しました。 なんか最初動いてた気がしてたのに、いつの間にか動かなくなっていて不思議だったんですがどこかで実行順が前後したのが原因だったのかも…
スクリプトの実行順は[DefaultExecutionOrder(-1)]
とか書いておいても良いのですが、どこかで非推奨になるみたいな記事を見かけたような見かけてないような気がしたので、Script Execution Orderから設定しました。
Edit > Project Settings > Script Execution Order にこんな感じで追加しておくと想定していた通りに動作してくれます。
参考リンク:
Comment
comments powered by Disqus