はじめに
こんにちは、unityエンジニアのchappyです。
UnityでWebGL向けのゲームを開発する際、PCかモバイルかで入力処理を切り分けたい事がありました。
モバイル端末の判定はJavaScriptを経由してUserAgentを取得するのがメジャーですが、手法によってはWebGLテンプレートを編集する必要があります。
unityroomではWebGLテンプレートは利用できず、固定のhtmlとなるためこの手法は利用できません。
そこで今回はWebGLテンプレートを使わない、unityroomに対応した手法でUserAgentを取得します。
環境
- Unity 6000.0.32f1
- 2025/05/03時点で最新のChrome
※unityroomやブラウザの仕様変更により、同じunityバージョンでも動作しなくなる可能性があります。
コード
mergeInto(LibraryManager.library, {
GetUserAgentString: function () {
const userAgent = window.navigator.userAgent;
const length = lengthBytesUTF8(userAgent) + 1; // Null終端を含む
const pointer = _malloc(length); // メモリ確保
stringToUTF8(userAgent, pointer, length); // 文字列コピー
return pointer; // メモリアドレスを返す
},
});
Unity公式ではjslibファイルをAssets/Plugins/WebGLフォルダに配置する事を推奨しているようです。
Assets以下に配置すれば動作する事は確認しています。
using UnityEngine;
using System.Runtime.InteropServices;
public class UserAgentHelper : MonoBehaviour
{
#if UNITY_WEBGL && !UNITY_EDITOR
[DllImport("__Internal")]
private static extern System.IntPtr GetUserAgentString();
#endif
public static string UserAgent { get; private set; } = "";
// 処理順の問題か、Awakeだと動作しない事があったので注意!
private void Start()
{
#if UNITY_WEBGL && !UNITY_EDITOR
var ptr = GetUserAgentString();
UserAgent = Marshal.PtrToStringUTF8(ptr);
#endif
Debug.Log($"UserAgent: {UserAgent}");
}
}
Start()
内でjslibのGetUserAgentString()
を呼び出し、UserAgentを取得します。
後は文字列に mobile
などが含まれているかで判定するだけです。
必要に応じて #if UNITY_WEBGL
などのプリプロセッサや Application.platform
などを併用して頂ければと思います。
private static bool IsMobileWebGL()
{
#if UNITY_WEBGL
return UserAgent.Contains("mobile") ||
UserAgent.Contains("android") ||
UserAgent.Contains("iphone") ||
UserAgent.Contains("ipad");
#else
return false;
#endif
}
おわりに
当初はWebGLテンプレートとjslib側からのSendMessageでUserAgentを取得していましたが、いざunityroomにアップロードしたら動作しなかったため変更しました。
結果的にWebGLテンプレートを触る必要がなくなり、シンプルな処理に出来て良かったです。