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

1. 概要

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

作成するアプリの概要

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

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

この Codelab を終了すると、ゲームで次のことができるようになります。

  • 実世界の平面を検出し、その上にプレイグラウンドを描画します。
  • カメラの画角からの光線を投げつけ、平面との交差を検出します。
  • 現実世界の照明条件に反応してゲームに臨場感を与えます。

学習内容

  • Unity の AR Foundation を使用するプロジェクトをセットアップする方法
  • ARPlaneManager を使用して新しい飛行機をサブスクライブする方法。
  • Raycast を使用して仮想ジオメトリとの交差点を見つける方法
  • ARLightEstimationData を使用してシーンを照明する方法。

必要なもの

2. 開発環境を設定する

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

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

Android デバイスの AR エクスペリエンスは、ARCore 対応デバイスで利用可能な ARCore によって駆動されます。開発用デバイスが AR に対応していることを確認します。または、正しく構成された AR 互換の Android Emulator インスタンスを使用することもできます。

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

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

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

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

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

Universal Render Pipeline テンプレートを使用して新しいプロジェクトを作成します。わかりやすい名前と適切な場所を指定して、[CREATE] をクリックします。

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

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

  1. [ウィンドウ >パッケージ マネージャー

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

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

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

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

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

ビルド設定を変更する

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

  1. [ファイル >ビルド設定
  2. [Platform] ペインで [Android] を選択します。
  3. 必要に応じて、[Development Build] と [Script Debugging] を有効にして、アプリの実行中にデバッグ情報を保持します。
  4. [Switch Platform] をクリックします。

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

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

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

  1. 左側のペインで、[Player] セクションをクリックします。
  2. [Android] タブの [Other Settings] で、[Graphics APIs] から [Vulkan] を削除します。

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

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

Universal Render Pipeline テンプレートには、このチュートリアルでは使用しないゲーム オブジェクトがいくつか含まれています。

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

  1. AR Foundation オブジェクトを追加する。[Hierarchy] ペインを右クリックします。このメニューを使用して以下を追加できます。
  • XR >AR セッション: このオブジェクトは AR エクスペリエンスのライフサイクルを制御します。
  • XR >AR Session Origin: このオブジェクトは AR 座標を Unity ワールド座標に変換します。
  • 浅い睡眠 >ディレクショナル ライト: ゲーム オブジェクトを照明するための光源を提供します。

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

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

レンダリングを設定する

Unity の Universal Render Pipeline で AR Foundation に対応するには、1 つの変更が必要です。

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

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

設定を確認する

  1. デバイスが電源に接続されていて、ADB デバッグがオンになっていることを確認してください。
  2. [ファイル] >ビルドして実行します。アプリがデバイスにアップロードされ、インストールが完了すると起動します。
  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. [Assets] タブを選択し、「Driving Surface Plane」を検索します。

スターター パッケージのこのプレハブは、飛行機の装飾として使用される砂のような床のテクスチャを提供します。

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

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

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

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

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

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

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

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

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

アプリを実行する

  1. [ファイル] >Build And Run... を選択して、変更をテストします。
  2. 現実世界の水平面にデバイスを向けて動かすことで、ARCore の世界認識の精度が上がります。

  1. ARCore が平面を検出すると、現実世界の表面を覆うテクスチャが表示されます。ARPlaneManager は、検出されたプレーンごとに指定された Plane Prefab をインスタンス化します。Driving Surface Plane プレハブには、特定の ARPlane のメッシュを作成する ARPlaneMeshVisualizer コンポーネントが含まれています。

次のステップでは、検出された平面をプレイグラウンドとして使用します。

4. 検出されたプレーンに対してヒットテストを行う

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

照準レチクルを作成する

このアプリのコントロール スキームでは、プレーヤーがスマートフォンを表面に向けることによって行われます。指定された場所を視覚的に明確に示すため、照準線を使用します。

「定着」するためにはコピーするにはヒットテストを使用しますヒットテストは、特定の方向に光線を投げたときに交差を計算する手法です。ヒットテストを使用して、カメラの画角の交差点を検出します。

レチクルを追加する

  1. 画面下部の [Project] ペインで、[Assets] >スターター パッケージ
  2. プロジェクトの [Hierarchy] ペインに [Reticle Prefab] をドラッグしてシーンに配置します。
  3. 階層内のレチクルを選択します。
  4. インスペクタで [Add Component] をクリックします。スターター パッケージから ReticleBehaviour スクリプトを追加します。このスクリプトには、レチクルを制御するためのボイラープレートが含まれています。
  5. ReticleBehaviour スクリプトは前に作成した Driving Surface Manager に依存するため、Driving Surface Manager 選択ツールをクリックして依存関係を追加します。[Scene] タブを選択し、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. [ファイル] >Build And Run... を選択して、変更をテストします。
  2. デバイスを平面に向けると、レチクルがカメラの動きに追随するのを確認できます。

車を作成

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

CarManager をシーンに追加する

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

この CarManager の動作は、レチクルが配置されている平面上におもちゃの車を発生させます。必要に応じて、CarBehaviour スクリプトを参照して、自動車のプログラムの仕組みを確認してください。

試乗

  1. [ファイル] >[Build And Run] を選択して、変更をテストします。
  2. 飛行機をタップすると、その場所に小さな車が表示されます。この車はレチクルに従って進んでいきます。

ゲーム要素を追加する

プレーヤーがシーン内のエンティティを操作できるようになったので、プレーヤーに走行する目的地を与えます。

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

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

ゲームをテストする

  1. [ファイル] >[Build And Run] を選択して、変更をテストします。2. 車を作成すると、パッケージが生成されます。
  2. 荷物まで車で行きます。
  3. 新しいアイコンがランダムな場所に表示されます。

5. 照明予測の設定

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

照明予測を有効にする

  1. [Hierarchy] で [AR Session Origin] を展開し、[AR Camera] オブジェクトを選択します。
  2. [Inspector] で、[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. [ファイル] >[Build And Run] を選択して、変更をテストします。
  2. シーン内のオブジェクトを見ると、環境の照明に応じてオブジェクトの色が変わってしまうことがあります。
  3. 可能であれば、照明を変更してみてください。たとえば、今いる部屋のライトを消してみます。オブジェクトのライトが、実際のライトの変化に適応することがわかります。

6. まとめ

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

学習した内容

  • Unity の AR Foundation と Universal Rendering Pipeline を使用して基本的なプロジェクトをセットアップする方法
  • ARPlaneManager を使用して新しい飛行機をサブスクライブする方法。
  • Raycast を使用して仮想ジオメトリとの交差点を検出する方法
  • ARLightEstimationData を使用してシーンを照明する方法。

次のステップ

ボーナス割り当て

ここで開発したゲームをさらに拡張したい場合は、以下のアイデアを参考にしてください。

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