hyoromoのブログ

最近はVRSNS向けに作ったものについて書いています

Unity製ARゲーム開発Tips集

ARに関するUnityの記事は『現実空間に何かモデルを配置してみる』といったチュートリアルで終わる記事が多く、その先にあるリリースに向けたノウハウがネット上にそれほどありませんでした。
なので今回はARゲームをリリースするにあたり、試行錯誤で把握した事、リリース後に気付いた事をTips形式で書きます。
※Android向けARゲーム開発したノウハウなため、iOSに関しては参考情報程度しかありません

リリースしたARゲーム

R18禁のゲームですが、DLSiteでAndroidのみ販売しています*1。体験版ではAR機能を試せ、R18要素が無いのでよければDLしてみて動作確認ください。
banner

環境

今回は以下の環境で行いました。

  • Unity2022.3.35f1
  • AR Foundation v5.1.5
  • Google ARCore XR Plugin v5.1.5
  • XR Core Utilities v2.3.0
  • XR Plugin Management v4.4.1
  • XR Simulation Environments v1.0.0

Tips

サポート機種

Androidの場合はARCore搭載機種でなければAR機能を使うことが出来ません。
Googleがサポート一覧を以下サイトで公開しています。ただ、この一覧に乗って無くてもサポートされている機種もあるようなので、『載ってれば動くけど、載って無ければ体験版で必ず一度は動作確認してみてね』という風にユーザーへ伝えればいいようです。
developers.google.com

iOSに関しては以下サイトの「拡張現実に対応しているiOSデバイスとiPadOSデバイスはこちらです」を確認ください。
www.apple.com

遮蔽物を認識する

現実空間の壁や人を認識してモデルより手前にある場合、その部分のモデルを非表示にする機能です。
これを対応する事でモデルを壁に隠したり、人混みに紛れさせた時に投影モデルの現実感が増します。

ARCameraコンポーネントと同じGameObjectへAR Occlusion Managerをアタッチし、遮蔽物として認識する対象を項目別に設定するだけで機能します。
ただし、プラットフォームや機種によって対応可能/不可能があります。


Environment DepthをBestにすると、カメラから現実世界の物体までの距離が分かるようになります。これで壁にモデルが隠れる事が出来ます。Depth API対応しているかどうかなため、前述した「サポート機種」で端末が対応しているか確認出来ます。非対応であれば遮蔽物があっても隠れません。
iOSは LiDARスキャナ搭載されている必要があるらしいですが、iOS向けARアプリは開発していないため実際どうかは未検証です。

Human SementationはiOSのAR Kitの機能で、人を障害物として認識する機能です。
腕や人でモデルが隠れると存在感がぐんっと引き上がって大変良いので、Androidだと使えないのが残念です。

AndroidでAR機能を使うのに必須のアプリがある

play.google.com
この『Google Play 開発者サービス(AR)』アプリがユーザーの端末にインストールされてなければAR機能は使えません。
最初これを知らなくて(Pixel2やPixel8は最初からインストール済みだった)、最初のバージョンではアプリインストールされているかのチェックをしなかったため謎エラーを発生させてしまい
機会損失をしてしまいました。苦い経験です。

なので、AR機能に関するエラーハンドリングは以下のように行っておくのが無難のようです。

async void Start() {
    // AR機能が使えるかのチェック
    await StartCoroutine(checkAr());
}

IEnumerator checkAr()
{
    if ((ARSession.state == ARSessionState.None) || (ARSession.state == ARSessionState.CheckingAvailability))
    {
        yield return ARSession.CheckAvailability();
    }

    if (ARSession.state >= ARSessionState.Ready)
    {
        // TODO:正常処理
    }
    else if (ARSession.state == ARSessionState.Unsupported)
    {
        // ARCore未搭載などのハードウェア側に問題があってAR機能を使えない
        // TODO:ARサポート対象外のエラー処理はここに書く
    }
    else if (ARSession.state == ARSessionState.NeedsInstall || ARSession.state == ARSessionState.Installing)
    {
        // 「Google Play Services for AR」が未インストールもしくはバージョンが古いので、GooglePlayからインストールもしくは更新を行ってもらう
        StartCoroutine(InstallARCoreApp());
        // TODO: アプリインストール後は再度AR機能が使えるかチェックを行うか、アプリを再起動するよう促す
    }
    else
    {
        // TODO:よく分からないけどエラーが発生した時の処理
    }
}

/// <summary>
/// 「Google Play Services for AR」をインストールするように促す
/// </summary>
private IEnumerator InstallARCoreApp()
{
    yield return ARSession.Install();
}


ARSession.Install() を呼び出すと上図のようなシステムダイアログが表示され、続行 押下すると冒頭に書いた『Google Play 開発者サービス(AR)』アプリのストアページが開きます。

未インストール時のテストは『Google Play 開発者サービス(AR)』アプリをアンインストールすれば行えます。

現実空間へ配置した時に動かないようAnker設定

現実空間に出現させたモデルをその場所に固定したい場合、ARAnchorを対象モデルにアタッチする必要があります。ただし、パフォーマンスに影響するので大量にARAnchorをアタッチせず、必要最小限に留めるのが良いようです。

//ARで表示するオブジェクト
[SerializeField]
GameObject _targetModelObj;

private void spawnModel() {
    _targetModelObj.AddComponent<ARAnchor>();
}

これを対応する事でカメラに床が映らない状態になっても表示座標が狂いにくくなります。

空間スキャン時の見た目を変更する


カメラで床と判定された場所に現れる床は AR Plane Manager の Plane Prefab のPrefabを差し替えると見た目が変わります。

Unity Editor上でのデバッグ

XR Simulation Environments を導入しておけばEditor上でシミュレート出来ます。
あくまでシミュレートなため異常系が発生せず、区切りの良い所で実機検証を必須ですが
Editor上で確認出来るのはトライ&エラーの確認を素早く行えて良いです。

1. Unity上メニューから Window > XR > AR Foundation > XR Environment 選択

2. XR Environment ビュー上で、下図のBackyard_45ftx40ftプルダウンする所から好きなテストマップを選ぶ

3. Play Modeすると選んだマップ上でテストが行える

*1:iOSは現時点EU圏以外での野良ストアが許されていないためリリース出来ません...