Unity の AR Foundation を使用して AR ゲームを作成する

1. 概要

ARCore は、スマートフォンで拡張現実エクスペリエンスを構築するための Google のフレームワークです。Unity の AR Foundation を使用して、クロス プラットフォームの AR アプリケーションを構築できます。

作成するアプリの概要

この Codelab では、AR Foundation を使用してシンプルなゲームを作成します。このゲームの目的は、ハンドヘルド デバイスで操作する車を使って荷物を集めることです。

ただし、完全に仮想の世界ではこのようにはなりません。物理的な原子とデジタル ビットを組み合わせて、プレーヤーの周囲の環境を認識するゲームを作成し、新しいタイプのプレーヤー エクスペリエンスを生み出します。

この Codelab を終了する時点では、ゲームは次のようになります。

  • 現実世界の平面を検出し、その上にプレイフィールドを描画します。
  • カメラのビューからレイをキャストし、平面との交差を検出します。
  • 現実世界の照明条件に反応して、ゲームにさらなるリアリズムをもたらします。

学習内容

  • Unity の AR Foundation を使用するプロジェクトを設定する方法。
  • ARPlaneManager を使用して新しいプランに登録する方法。
  • Raycast を使用して仮想ジオメトリとの交差を検出する方法
  • ARLightEstimationData を使用してシーンをライティングする方法。

必要なもの

2. 開発環境を設定する

このステップでは、Unity の AR Foundation を使用して開発を行うための環境を準備します。

デバイスが AR に対応していることを確認する

Android デバイスでの AR エクスペリエンスは ARCore によって実現されます。ARCore は ARCore 対応デバイスで利用できます。開発用デバイスが AR に対応していることを確認します。または、正しく構成された AR 対応の Android エミュレータ インスタンスを使用することもできます。

デバイスで USB デバッグを設定する

デバッグアプリを実行するには、デバイスで開発者向けオプションを有効にする必要があります。まだ有効にしていない場合は、Android のドキュメントの開発者向けオプションと USB デバッグを有効にするを参照してください。

Unity(2020.3 LTS)をインストールする

ワークステーションに Unity 2020 LTS をインストールします。この Codelab では、Unity の UI のスクリーンショットは 2020.3(LTS)バージョンで表示されています。他のバージョンの Unity でも動作する可能性がありますが、追加の手順が必要になる場合があります。表示される画面は、ここに示されているスクリーンショットとは異なる場合があります。

新しいプロジェクトを作成

ユニバーサル レンダー パイプライン テンプレートを使用して、新しいプロジェクトを作成します。わかりやすい名前と適切な場所を指定して、[作成] を押します。

必要なフレームワークをインストールする

Unity の AR Foundation は Unity Package Manager にあります。

  1. [Window] > [Package Manager] をクリックして開きます。

  1. このウィンドウで、この Codelab で使用するパッケージをインストールします。 アイコンを使用してエントリを展開すると、これらのフレームワークの最新バージョンが表示されます。次の各フレームワークの最新バージョンをインストールします。
    • AR Foundation
    • ARCore XR プラグイン

完了すると、パッケージ マネージャーは次のようになります。

スターター パッケージをインストールする

この Codelab では、Codelab の一部を迅速に進めるためのプレハブとスクリプトを含むスターター パッケージを提供しています。これにより、AR Foundation の使用方法に集中できます。

  1. [Assets] > [Import Package] > [Custom Package...] を開いて starter-package.unitypackage を開き、スターター パッケージをインストールします。
  2. ポップアップ ウィンドウで、すべてが選択されていることを確認します。
  3. [インポート] をクリックします。

ビルド設定を変更する

アプリケーションは Android で実行されるため、ビルド プラットフォームを Android に変更します。

  1. [File] > [Build Settings] を開きます。
  2. [プラットフォーム] ペインで、[Android] を選択します。
  3. 必要に応じて、アプリの実行中にデバッグ情報を保持するために、[開発ビルド] と [スクリプト デバッグ] を有効にします。
  4. [Switch Platform] をクリックします。

プロジェクトの設定を変更する

起動時に XR システムを初期化するように AR Foundation を構成する必要があります。

  1. [Edit] > [Project Settings...] を開き、[XR Plug-in Management] セクションをクリックします。
  2. [Android] タブで、[ARCore] を有効にします。

  1. 左側のペインで、[プレーヤー] セクションをクリックします。
  2. [Android] タブの [その他の設定] で、[グラフィック API] から [Vulkan] を削除します。

  1. ARCore を使用する AR 必須アプリでは、API レベル 24 以上が必要です。下にスクロールして [最小 API レベル] を見つけます。最小 API レベルを 24 に設定します。

必要なシーン要素を追加する

ユニバーサル レンダリング パイプライン テンプレートには、このチュートリアルでは使用しないゲーム オブジェクトがいくつか含まれています。

  1. SampleScene 内のすべてのゲーム オブジェクトを削除します。

  1. AR Foundation オブジェクトを追加します。[階層] ペインを右クリックします。このメニューを使用して、次のものを追加できます。
  • XR > AR Session: このオブジェクトは、AR エクスペリエンスのライフサイクルを制御します。
  • XR > AR Session Origin: このオブジェクトは、AR 座標を Unity のワールド座標に変換します。
  • [Light] > [Directional Light]: ゲーム オブジェクトを照らす光源を提供します。

階層は次のようになります。

  1. 階層で作成した AR Session Origin を展開し、AR Camera オブジェクトを選択します。インスペクターで、タグを MainCamera に変更します。

レンダリングを設定する

Unity のユニバーサル レンダリング パイプラインを AR Foundation と互換性を持たせるには、1 つの変更が必要です。

  1. [Project] ペインで、[Assets] > [Settings] に移動して ForwardRenderer アセットを見つけます。

  1. [ForwardRenderer] を選択します。
  2. [Inspector] ペインで、[Add Renderer Feature] を使用して [AR Background Renderer Feature] を追加します。このコンポーネントは、シーンにカメラフィードをレンダリングします。

設定を確認する

  1. デバイスが接続され、ADB デバッグがオンになっていることを確認します。
  2. [File] > [Build And Run...] をクリックします。これにより、アプリがデバイスにアップロードされ、インストールが完了すると起動します。
  3. デバイスの画面にカメラフィードが表示されます。

次のステップでは、アプリに機能を追加していきます。

3. 現実世界の平面を検出する

基本的なシーンが設定されたので、ゲームの開発を開始できます。このステップでは、平面を検出し、シーンに描画します。

ARPlaneManager コンポーネントを追加する

ARPlaneManagerARPlane を検出し、デバイスの環境認識が変化したときにゲーム オブジェクトを作成、更新、削除します。

  1. [Hierarchy] ペインを使用して、空の GameObject を作成します。
  2. 名前を Driving Surface Manager に変更します。このコンポーネントは、プレーヤーが選択するまで飛行機を表示します。
  3. 新しいゲーム オブジェクトを選択します。[Inspector] ペインで [Add Component] をクリックして、[AR Plane Manager] を追加します。

  1. Plane Prefab フィールドを設定して ARPlaneManager を構成します。
    1. None の横にあるボタンをクリックして、[Select GameObject] ウィンドウを表示します。
    2. [アセット] タブを選択し、[Driving Surface Plane] を検索します。

スターター パッケージのこのプレハブは、プレーンの装飾として使用される粗い床のテクスチャを提供します。

  1. Detection ModeHorizontal に変更します。これにより、ARPlaneManager は水平面のみを提供するように構成され、運転に最適になります。

ARRaycastManager コンポーネントを追加する

ARRaycastManager はレイキャスト機能を公開します。次のステップでは、このオブジェクトを使用してユーザーにコントロールを提供します。

  1. [Hierarchy] ペインで Driving Surface Manager というオブジェクトが選択されていることを確認します。
  2. インスペクターで [Add Component] をクリックして、ゲーム オブジェクトに ARRaycastManager コンポーネントを追加します。

このコンポーネントに必要な構成はありません。

DrivingSurfaceManager コンポーネントを追加する

DrivingSurfaceManager は、ARPlane を選択できるようにするスターター パッケージのヘルパースクリプトです。ARPlane を選択すると、他のすべてのプレーンが非表示になり、新しいプレーンが無効になります。

  1. [Hierarchy] ペインで Driving Surface Manager というオブジェクトが選択されていることを確認します。
  2. インスペクターで [Add Component] をクリックして、ゲーム オブジェクトに DrivingSurfaceManager コンポーネントを追加します。

このコンポーネントに必要な構成はありません。

アプリを実行する

  1. [File] > [Build And Run...] をクリックして、変更内容をテストします。
  2. デバイスを現実世界の水平な面に向け、デバイスを動かして ARCore の世界認識を向上させます。

  1. ARCore が平面を検出すると、現実世界のサーフェスが土のテクスチャで覆われます。ARPlaneManager は、検出された各平面に対して指定された Plane Prefab をインスタンス化します。Driving Surface Plane プレハブには、指定された ARPlane のメッシュを作成する ARPlaneMeshVisualizer コンポーネントがあります。

次のステップでは、検出された平面をプレイフィールドとして使用します。

4. 検出された平面に対してヒットテストを行う

前のステップでは、平面を検出できるアプリケーションをプログラミングしました。これらの平面はゲームのシーンに反映されます。次に、照準レティクルと、検出された平面の表面を走行する車を作成して、これらの平面とのインタラクティビティを追加します。

照準レティクルを作成する

このアプリの操作方法は、スマートフォンを表面に向けるというものです。指定された場所を視覚的にわかりやすく示すために、照準レチクルを使用します。

このレティクルを AR プレーンに「固定」するには、ヒットテストを使用します。ヒットテストは、特定の方向にレイをキャストするときに交差を計算する手法です。ヒットテストを使用して、カメラのビューの方向にある交差を検出します。

レチクルを追加する

  1. 画面下部の [Project] ペインで、[Assets] > [Starter Package] に移動します。
  2. Reticle Prefab をプロジェクトの Hierarchy ペインにドラッグして、シーンに配置します。
  3. 階層でレティクルを選択します。
  4. インスペクタで、[Add Component] をクリックします。スターター パッケージから ReticleBehaviour スクリプトを追加します。このスクリプトには、レティクルを制御するためのボイラープレートが含まれています。
  5. ReticleBehaviour スクリプトは前に作成した Driving Surface Manager に依存するため、Driving Surface Manager 選択ツールをクリックして依存関係を追加します。[シーン] タブを選択し、Driving Surface Manager を選択します。

ReticleBehaviour を編集する

ReticleBehavior スクリプトは、デバイスのビューポートの中央にある平面に照準を配置します。

  1. Script フィールドをダブルクリックして、ReticleBehaviour.cs スクリプトを開きます。
  2. カメラの ViewToScreenPoint を使用して画面の中心を特定します。Update() メソッドを編集して、次の内容を追加します。
var screenCenter = Camera.main.ViewportToScreenPoint(new Vector3(0.5f, 0.5f));
  1. このポイントを使用してレイキャストを行います。次のものを追加します。
var hits = new List<ARRaycastHit>();
DrivingSurfaceManager.RaycastManager.Raycast(screenCenter, hits, TrackableType.PlaneWithinBounds);

変数 hits には、ray と交差するトラッカブル上の点を表す ARRaycastHit が含まれます。

  1. hits リストをクエリして、交差点のスポットを特定します。DrivingSurfaceManager に含まれるロックされた平面を優先し、存在しない場合は最初にヒットした平面を使用します。Update() の末尾に次のように追加します。
CurrentPlane = null;
ARRaycastHit? hit = null;
if (hits.Length > 0)
{
    // If you don't have a locked plane already...
    var lockedPlane = DrivingSurfaceManager.LockedPlane;
    hit = lockedPlane == null
        // ... use the first hit in `hits`.
        ? hits[0]
        // Otherwise use the locked plane, if it's there.
        : hits.SingleOrDefault(x => x.trackableId == lockedPlane.trackableId);
}
  1. hit に結果が含まれている場合は、この GameObject の変換をヒット位置に移動します。
if (hit.HasValue)
{
    CurrentPlane = DrivingSurfaceManager.PlaneManager.GetPlane(hit.Value.trackableId);
    // Move this reticle to the location of the hit.
    transform.position = hit.Value.pose.position;
}
Child.SetActive(CurrentPlane != null);

レティクルをテストする

  1. [File] > [Build And Run...] をクリックして、変更内容をテストします。
  2. デバイスを平面に向けると、レチクルがカメラの動きに合わせて動きます。

車を作成する

プレイヤーは、照準の位置に向かって走行するおもちゃの車を操作します。この車のモデルと動作は、スターター パッケージで提供されています。

シーンに CarManager を追加する

  1. [Hierarchy] で、新しい空の GameObject を作成します。
  2. 名前を Car Spawner に変更します。
  3. 作成したオブジェクトを選択します。[Hierarchy] ペインで、[Add Component] をクリックして CarManager コンポーネントを追加します。
  4. 各フィールドの選択ツールをクリックして、CarManager の依存関係を設定します。
    • Car Prefab: [Assets] で [Car Prefab] を選択します。
    • Reticle: [Scene] で、[Reticle Prefab] を選択します。
    • Driving Surface Manager: [Scene] で [Driving Surface Manager] を選択します。

この CarManager の動作により、照準が置かれている平面にミニカーが生成されます。必要に応じて、CarBehaviour スクリプトで車のプログラミング方法をご確認ください。

試乗

  1. [File] > [Build And Run] をクリックして、変更をテストします。
  2. 平面をタップすると、その場所に小さな車が表示されます。この車は照準を追跡します。

ゲーム要素を追加する

プレーヤーがシーン内のエンティティを操作できるようになったので、プレーヤーが向かうべき目的地を設定します。

  1. Hierarchy に新しい空の GameObject を作成します。
  2. 名前を Package Spawner に変更します。
  3. 作成したオブジェクトを選択します。[Hierarchy] ペインで、[Add Component] をクリックして PackageSpawner コンポーネントを追加します。
  4. 各フィールドの選択ツールをクリックして、PackageSpawner の依存関係を設定します。
    • パッケージ プレハブ: [アセット] で [パッケージ プレハブ] を選択します。
    • Driving Surface Manager: [Scene] で [Driving Surface Manager] を選択します。

この PackageSpawner の動作により、パッケージがまだ存在しない場合、ロックされた ARPlane のランダムな場所に新しいパッケージが生成されます。

ゲームをテストする

  1. [File] > [Build And Run] をクリックして、変更をテストします。2. 車を作成すると、パッケージが生成されます。
  2. 荷物まで車で移動します。
  3. 新しいものがランダムな場所に表示されます。

5. 照明推定を設定する

基本的なゲームが完成したので、AR シーンにリアリティを加えましょう。このステップでは、ARCore の Lighting Estimation API を使用して、カメラから入力されるフレームに基づいて現実世界に存在する照明を検出します。この情報は、現実世界の照明に合わせてシーンの照明を調整するために使用されます。

照明推定を有効にする

  1. [Hierarchy] で [AR Session Origin] を展開し、[AR Camera] オブジェクトを選択します。
  2. [インスペクタ] で、[AR Camera Manager] スクリプトを開きます。
  3. [Lighting Estimation] フィールドを [Everything] に変更します。

方向性ライトを変更する

  1. [Hierarchy] で、[Directional Light] オブジェクトを選択します。
  2. そこに LightEstimation コンポーネントを追加します。スターター パッケージのこのコンポーネントは、ライティングの変更をサブスクライブするためのボイラープレートを提供します。
  3. FrameReceived() 関数に次のコードを追加します。
ARLightEstimationData lightEstimation = args.lightEstimation;

if (lightEstimation.averageBrightness.HasValue)
    Light.intensity = lightEstimation.averageBrightness.Value;

if (lightEstimation.averageColorTemperature.HasValue)
    Light.colorTemperature = lightEstimation.averageColorTemperature.Value;

if (lightEstimation.colorCorrection.HasValue)
    Light.color = lightEstimation.colorCorrection.Value;

if (lightEstimation.mainLightDirection.HasValue)
    Light.transform.rotation = Quaternion.LookRotation(lightEstimation.mainLightDirection.Value);

if (lightEstimation.mainLightColor.HasValue)
    Light.color = lightEstimation.mainLightColor.Value;

if (lightEstimation.mainLightIntensityLumens.HasValue)
    Light.intensity = lightEstimation.averageMainLightBrightness.Value;

if (lightEstimation.ambientSphericalHarmonics.HasValue)
{
    RenderSettings.ambientMode = AmbientMode.Skybox;
    RenderSettings.ambientProbe = lightEstimation.ambientSphericalHarmonics.Value;
}

変更のテスト

  1. [File] > [Build And Run] をクリックして、変更をテストします。
  2. シーン内のオブジェクトを見ると、環境の照明に応じて色付けされていることがわかります。
  3. 可能であれば、照明を調整してみてください。たとえば、部屋の照明を消してみます。オブジェクトの照明が現実世界の照明の変化に合わせて調整されます。

6. まとめ

これで完了です。Unity AR Foundation に関するこの Codelab は終了しました。

学習した内容

  • Unity の AR Foundation とユニバーサル レンダリング パイプラインを使用して基本的なプロジェクトを設定する方法。
  • ARPlaneManager を使用して新しいプランに登録する方法。
  • Raycast を使用して仮想ジオメトリとの交差を検出する方法。
  • ARLightEstimationData を使用してシーンをライティングする方法。

次のステップ

ボーナス課題

ここで作成したゲームを拡張したい場合は、次のアイデアを検討してください。

  • PackageManager が新しいパッケージを生成したときに TextMeshPro を変更して、ゲームにスコア カウンタを追加します。
  • パフォーマンス オーバーレイを有効にすると、ゲームの実行中にパフォーマンス情報を確認できます。
  • 永続レイキャストを使用して、まずシーンに新しいオブジェクトを配置します。そのエリアで平面が検出されると、オブジェクトがその平面にスナップするように更新されます。