WebGLで閲覧可能な道案内コンテンツ作成およびモバイル対応
はじめに:
神田駅からロジックススクエア事務所までの道のりを全天球パノラマ写真を用いて、WebGLで閲覧可能な道案内コンテンツを作成すること、またスマートフォンの操作にも対応させることが目的です。
開発環境:
使用機材
THETA S
Mac mini
MacOS:Big Sur バージョン11.4
使用ソフト
Unity 2020.3.15f2
VisualStudio for Mac 8.10.8 (build 0)
Unityでの実装:
パノラマ写真の表示
THETAで撮影したパノラマ写真を以前投稿した360度全天球パノラマのWebGLコンテンツをUnityで作るを参考にして、撮影したパノラマ写真の数だけ全天球モデルを用意し、パノラマ写真を表示およびHotSpotを追加しました。
スマートフォン対応
Unity WebGLは現在、スマートフォンのブラウザに対応していないため、PC用に実装した操作方法では挙動が異なる場合があります。
今回はJavaScriptを用いてWebGLでアクセスしている端末がスマートフォンか否かの判別を行います。
WebGL向けにビルドすると作成されるindex.htmlを修正します。変数var unityScene;
を宣言し、これにcreateUnityInstance
で生成されるunityInstance
を代入します。
また、index.html内に下記スクリプトを適用してJavaScriptを呼び出せるようにします。
<script src="UnityFunction.js"></script>
JavaScriptから呼び出す関数を作成します。今回はsetSmartPhoneが呼ばれたらisSmartPhoneにtrueを代入するように作成しました。
//スマホかどうかを保存しておく
public bool isSmartPhone { get; private set; } = false;
//JavaScriptから呼び出すメソッド
public void setSmartPhone()
{
isSmartPhone = true;
}
下記JavaScriptのスクリプトでWebGLでアクセスしている端末がAndroid、IOS、iPadOSかそれ以外かを判別します。端末がスマートフォンならばsetSmartPhone関数を呼び出します。外部ファイルで識別しているのでiPadOSのように新規でOSが出た場合でも、そのOSを識別できるように条件式を修正すればビルドし直すこともなく対応可能です。
function UnityCheckPlatform(){
//ユーザーエージェントを取得して全て小文字に変換する
var ua = window.navigator.userAgent.toLowerCase();
//端末がiPadか否かの判定
var ipad = ua.indexOf('ipad') > -1 || ua.indexOf('macintosh') > -1 && 'ontouchend' in document;
if (ua.indexOf("android") != -1 || ua.indexOf("iphone") != -1 || ipad) {
//ゲームオブジェクトのCheckManagerにアタッチされているスクリプトの関数のsetSmartPhoneModeを呼ぶ
unityScene.SendMessage('CheckManager', 'setSmartPhoneMode');
}
}
上記のJavaScriptを呼ぶためのスクリプトを作成します。Assets/Plugins下にjslibの拡張子をもつファイルを作成し以下のように記述すると、UnityからJavaScriptで作成した関数のUnityCheckPlatformを呼ぶことができます。
mergeInto(LibraryManager.library, {
CheckPlatform: function () {
UnityCheckPlatform();
},
});
これでJavaScriptでWebGLでアクセスしている端末がスマートフォンか否かを判別することができます。
スワイプ、ズームインズームアウトでのカメラ操作
スマートフォンで操作する際にはInput.GetMouseButton
ではなく、Input.TouchCount
を使用します。
以下のスクリプトを適用させることで画面スワイプで視点の回転ができるようになります。横方向の回転は無制限に回転でき、縦方向の回転は-90度から90度まで回転できるようになっています。
void Update()
{
//画面スワイプした時
if(checkDevice && Input.touchCount == 1)
{
Touch touch = Input.GetTouch(0);
switch(touch.phase)
{
case TouchPhase.Began:
startPos = touch.position;
case TouchPhase.Moved:
endPos = touch.position;
swipeDirX += (endPos.x - startPos.x) / 100;
swipeDirY -= (endPos.y - startPos.y) / 100;
swipeDirY = ClampAngle(swipeDirY, -90f, 90f);
Quaternion xQuaternion = Quaternion.AngleAxis(swipeDirX, Vector3.up);
Quaternion yQuaternion = Quaternion.AngleAxis(swipeDirY, Vector3.right);
Camera.main.transform.localRotation = cameraRot * xQuaternion * yQuaternion;
break;
}
}
//カメラ操作補正
private float ClampAngle(float angle, float min, float max)
{
return Mathf.Clamp(angle, min, max);
}
以下のスクリプトを適用させることで、画面ピンチイン/ピンチアウトで拡大縮小ができるようになります。
//ズームインズームアウトした時
else if(checkDevice && Input.touchCount == 2)
{
Touch touchPoint0 = Input.GetTouch(0);
Touch touchPoint1 = Input.GetTouch(1);
if (touchPoint1.phase == TouchPhase.Began)
{
startPointDistance = Vector2.Distance(touchPoint0.position, touchPoint1.position);
}
else if (touchPoint0.phase == TouchPhase.Moved && touchPoint1.phase == TouchPhase.Moved)
{
float endPointDistance = Vector2.Distance(touchPoint0.position, touchPoint1.position);
float distanceMagnification = (endPointDistance - startPointDistance) / 100;
Camera.main.fieldOfView -= distanceMagnification * scrollSpeed;
if (Camera.main.fieldOfView < minFov)
{
Camera.main.fieldOfView = minFov;
}
else if (Camera.main.fieldOfView > maxFov)
{
Camera.main.fieldOfView = maxFov;
}
}
}
デモ:
スマートフォンでも操作できるようにした道案内のWebGLコンテンツのデモ動画になります。
PCではChromeで、IPhoneのsafariで動作確認済みです。
- PCで操作する場合
マウスのドラッグ操作:カメラの回転
ホイール操作:ズームイン/ズームアウト
- スマートフォンで操作する場合
画面スワイプ:カメラの回転
ピンチイン/ピンチアウト:ズームイン/ズームアウト
新規タブで開きます。
まとめ:
本記事の目的の全天球パノラマ写真を用いた道案内コンテンツの作成とスマートフォンでの視点操作の実装ができました。
Unity 2020.3時点で、Unity WebGLはスマートフォンのブラウザにはサポートされてませんが、あらかじめスマートフォン用の挙動を作っておいて、スマートフォンでの操作時はそれに切り替えることでPCと同じように動作させることが可能です。
今回はJavaScriptを利用して、WebGLを表示している端末がスマートフォンか否かの判定を行いました。JavaScriptを用いれば端末の判定だけでなく、ポップアップウィンドウを表示させることにより、コンテンツをより良いものにできそうです。