上級チュートリアル: ゲームボードのナビゲーション
プロシージャルなゲームプレイが可能となり、キャラクターが環境内に現れ、リアルで没入感のある挙動で移動する高度なカスタムAR体験をビルドする。
このチュートリアルでは、 Gameboard
を設定し、物理環境をスキャンして、ユーザー環境の内部理解を得る方法の例を紹介します。また、このコンポーネントのスマートな配置やナビゲーション機能をARアプリケーションに活用する方法についても詳しく説明します。
シーンをセットアップする
現在 ゲームボード は環境を理解するためにメッシングをベースとしてビルドされています。開始するには、 メッシング: はじめに チュートリアルのステップに従ってください。
Unityエディターで繰り返し作業を行う場合は、 モックメッシュ を使用することをお勧めします。 MeshLoader
プレハブをシーンに追加すると簡単に行うことができます。
以下のゲームボードのシーンやコードについては、 Assets/ARDKExamples/ContextAwareness/Gameboard
ディレクトリ下の ARDK-examples
を参照してください。
また、このサンプルシーンでは、グラフィカルユーザーインターフェイス(GUI)とタッチ入力で GameboardExampleManager
スクリプトを使用して、エージェントの配置や移動を行うことができます。
レイヤー
ゲームボードは、シーン内の ARMeshManager
コンポーネントによって生成されたUnityメッシュに対するレイキャスティングに依存しています。ARDK使用例パッケージを自分のプロジェクトにインポートしている場合は、次のように行う必要があります。
プロジェクトに新しいレイヤー
ARDK_Gameboard
を追加します(Edit(編集) > Project Settings(プロジェクト設定) > Tags and Layers(タグとレイヤー) の順に移動)。レイヤー
GameboardMeshChunk.prefab
をARDK_Gameboard
に設定し、ARMeshManagerでメッシュプレハブとして使用するように設定されていることを確認します。GameboardManager
スクリプトを探し、シーンのどこかに追加します。その Scan Settings(スキャン設定) -> Layer Mask(レイヤーマスク) の値をARDK_Gameboard
に設定します。
構成
GameboardManagerクラスは、ゲームボードを作成したり、スキャンのトリガーによってカメラの前で定期的に更新する上で役立ちます。ゲームボードの設定では、プレイ可能なエリアの定義方法や検出方法を変更できます。
TileSize
: グリッド上のノードのメトリックサイズ。このサイズが小さいほど、グリッドの解像度は高くなります。高解像度のグリッドは、同じスキャン領域で実行されるレイキャストの数が多くなることを意味します。これにより、アプリケーションのパフォーマンスに影響を及ぼす可能性があります。
FlatFloorTolerance
: セル内のノードのノイズを判断する際に使用する標準偏差の許容値を指します。この値の範囲外のセルはノイズが非常に多く、プレイ可能であるとみなされます。
MaxSlope
: 推定される面は、多くの場合、完全に平面ではありません。この値は、隣接するノードを平面とみなすために許容される最大角度を度単位で定義します。
StepHeight
: 2つのセルが同一平面上にあると見なすことができる最大標高差。
スキャン
その中でも特に重要なメソッドが Gameboard.Scan(origin, range)
です。
スキャンすると、物理世界におけるゲームボードの内部解釈が更新されます。世界座標の原点を範囲付きで指定することで、アプリケーションに必要な世界の部分のみが更新されます。GameboardManagerスクリプトでは、スキャン間隔 ごとにカメラの前で新しいスキャンをトリガーして、ゲームボードを更新できます。GameboardManagerの UpdateGameboard
関数は次のようになります。
private Camera _camera; float _scanRange; private void UpdateGameboard() { var cameraTransform = _camera.transform; var playerPosition = cameraTransform.position; var playerForward = cameraTransform.forward; // The origin of the scan should be in front of the player var origin = playerPosition + Vector3.ProjectOnPlane(playerForward, Vector3.up).normalized; // Scan the environment Gameboard.Scan(origin, range: _scanRange); }
この方法では、融合されたメッシュを原点から重力に平行にレイキャストします。ボードの解像度によっては、この方法によってパフォーマンスに影響を及ぼす可能性があります。GameboardManagerは、デフォルトで1秒間に10回スキャンするように設定されています。
スマートな配置
Gameboard.RayCast
メソッドを使うと、目的の位置が占有可能かどうかについてゲームボードにクエリを実行できます。この機能は、オブジェクトやゲームキャラクターを障害物(家具など)から離してスポーンするために使用されます。
using Niantic.ARDK.Extensions.Gameboard; Camera _camera; IGameboard _gameboard; GameObject _object; void HandlePlacement() { // Get a ray pointing in the user's look direction var cameraTransform = _camera.transform; var ray = new Ray(cameraTransform.position, cameraTransform.forward); // Intersect the Gameboard with the ray if (_gameboard.RayCast(ray, out Vector3 hitPoint)) { // Check whether the object can be fit in the resulting position if (_gameboard.CheckFit(center: hitPoint, 0.4f)) { _object.transform.position = hitPoint; } } }
ナビゲーション
経路探索エージェントの動作を指定する AgentConfiguration
に基づき、2つの位置間の経路を探索する Gameboard.CalculatePath()
メソッドを使用します。
経路検索メソッドの簡単な呼び出し方は以下のとおりです:
using Niantic.ARDK.AR.Configuration; IGameboard _gameboard; // Create an agent with jumping capabilities AgentConfiguration agentConfiguration = AgentConfiguration.CreateJumpingAgent(); bool success = _gameboard.CalculatePath(fromPosition, toPosition, agentConfiguration, out Path path);
結果として得られる経路には、指定された位置の間で障害物のない最短経路を表す Waypoint's
の配列が含まれます。この経路に沿ってゲームキャラクターがアニメーション化されるかどうかは、アプリケーションによって異なります。結果は、完全な経路、不完全な経路、または有効な経路が見つからなかった場合も返ります。経路が不完全な場合は toPosition に到達できないため、到達可能な最短の位置に移動します。無効な経路には次のような理由が考えられます。
ゲームボードにプレイ可能なエリアがない
ゲームボードに
fromPosition
が設定されていない
fromPosition
とtoPosition
が同一の値に設定されている
経路探索を使用して環境内を移動する基本的なエージェントの実装方法については、 Assets/ARDKExamples/ContextAwareness/Gameboard/GameboardAgent.cs
下にあるARDK使用例プロジェクトを参照してください。