2
1
お題は不問!Qiita Engineer Festa 2024で記事投稿!
Qiita Engineer Festa20242024年7月17日まで開催中!

【Unity】UnityでAppleVisionPro を用いてARPlane/ARMeshを利用する方法と注意点【VisionOS】

Last updated at Posted at 2024-07-08

Graffity でVisionPro とUnityを用いてゲーム開発をしているcovaです。
今回はVisionPro 向けAR/MRコンテンツを作るにあたって ARPlane(平面検知)ARMesh はよく使われますが、使い方に気をつけないと意図通りの挙動にならなかったトラブルがあったので備忘録として記事化しました。

TL;DR (今北産業)

  • Unityで行う場合はARFoundation のフレームワークに則って出来るぞ!
    • ARFoundation を使ったことがない方はスマホAR等で利用方法をざっくり理解しておくと良いです
  • ARMesh を当たり判定で使う場合はCollider周りの設定を正しく行わないと、意図しない形にCollision用Mesh が変形してしまうので要注意
  • ARPlane は普通に使えるし、属性も取れるのでSceneSegmentation/SceneUnderstanding とかにはMeshよりPlaneの方がよかったりします

検証環境

項目 version等
Unity 2022.3.20f1
PolySpatial 1.2.3
Xcode 15.2
VisionOS 1.0.2~2.0beta

PolySpatial 導入について

以下の内容は様々な方がTechブログで記載されていたり、公式の導入ドキュメントがあるのでそちらをご覧ください

  • Proライセンスの設定方法
  • PolySpatial をUPMで入れる方法

基本的な使い方

共通の設定項目

Scene 周り

  1. AR動かす用のコンポーネントを配置しましょう
    1. XROriginの設定
      スクリーンショット 2024-07-03 18.04.38.png
      • TrackingOriginMode はFloor にしておくのがお勧めです
        • DeviceやNotSpecified だと現実との位置計算が面倒なので素直に床を高さ=0にするのが楽です
      • よくわからなかったらPolySpatial のMixedRealityのサンプルSceneをそのまま利用しちゃうのが楽です
    2. ARSessionの配置
      • 基本的にはデフォルトの状態で問題ないです
        スクリーンショット 2024-07-03 18.07.25.png
      • よくわからなかったらPolySpatial のMixedRealityのサンプルSceneをそのまま利用しちゃうのが楽です
    3. VolumeCamera がUnbounded になっているか確認しましょう
      スクリーンショット 2024-07-03 18.08.33.png
      • Bounded だったりWindow だと基本的にはAR周りが正しくとれないです

ProjectSettings

  1. XR Plug-in Management でvisionOS を有効化しましょう
    スクリーンショット 2024-07-03 18.38.18.png

  2. AppleVisionOS のところでMR向け設定をしましょう
    スクリーンショット 2024-07-03 18.39.04.png

    • InitializeHandTrackingOnStartUp はハンドトラッキングをする場合は必須です
    • HandsTrackingUsageDescription はハンドトラッキング利用アプリの初回起動時に表示するメッセージです
      • ここが空だとビルドが通らなかったりします
      • Info.plist に正しく反映されないままXcodeビルドが通ると実際にアプリを起動しようとしてもすぐクラッシュするなどの問題を引き起こす原因になります
    • World Sendsing Usage Description は 入力必須 です
      • ここを入力しないと HandsTrackingUsageDescription と同様の問題の原因になります
    • UpperLimbVisibility は チェックを入れると手の位置と被った3DObjectが存在する場合、自動的にOpaqueでもアルファブレンドで透過する処理をOS側がやってくれます
      • ただし透過度合いとかは制御不能でOSが勝手にやります
      • 特に必要なければOffでもOKです
    • IL2CPP Large Exe Workaround は脳死でチェックを入れましょう
      • Xcodeビルド時にファイルサイズとかのビルドエラーが発生する場合はこれにチェックを入れれば大体解決します

ARPlane

1.XROrigin ObjectにARPlaneManager コンポーネントをくっつけよう
- よくわからなかったらPolySpatial のMixedRealityのサンプルSceneをそのまま利用しちゃうのが楽です
- MixedReality のSampleだとデフォルトでコンポーネントがあるので何もしなくてもOKです

  1. DetectionMode を設定しよう
    スクリーンショット 2024-07-03 18.13.35.png

    • 特に何もなければEverythingで問題ないです
    • 壁とか垂直面だけ検知させたいならVertical のみにチェックを入れます
    • 逆に水平面だけ検知させたい場合は Horizontal のみにチェックを入れます
  2. 検知したMeshを可視化させよう

    • 基本的には検知した面はドット模様で表示されます
      スクリーンショット 2024-07-03 18.16.05.png
      もし色をつけたいなどあればARDefaultPlane に設定されているMaterialを変更しましょう
    • ARplane に関してはデフォルトで設定されているPrefabに検知した面の属性表示用のUIがついてます
      スクリーンショット 2024-07-03 18.16.00.png
      ただ確認用であれば特に手を加える必要はないです

ARMesh

  1. ARMeshManager Component がヒエラルキーにない場合は追加しましょう. 追加する場合はXROrigin GameObjectにそのままくっつけてもOKです
    スクリーンショット 2024-07-03 18.35.38.png
    • Density(密度) は特に指定がなければデフォルトの0.5のままで.
      • 密度を上げると頂点数が増えてパフォーマンスにも影響が出るので要注意
  2. Mesh を可視化しよう
    • ARMeshManager の AR Default Mesh は市松模様でMeshを表示してくれます
      スクリーンショット 2024-07-03 18.36.22.png
    • またMeshはいくつかのObject毎に分かれて管理されます
      • このとき、どのObjectがどのMeshに属しているか?とかID情報が必要な場合は後述の Mesh 表示加工Scriptを適応してください

ARPlane/ARMesh の応用的な使い方

当たり判定をつける

まず現実空間をスキャンしたらやりたくなること1つ目です。
基本的にはUnityのPhysics系のコンポーネントをシンプルに設定するだけで問題ないのですが、やり方によっては色々トラブルを引き起こす可能性があるので要注意です.

投擲物にRigidbody をつけて当たり判定を実装する場合

- こちらの場合は特に何も気にせず実装できます

  1.  投擲物側のObjectに Rigidbody と Collider (できればSphereCollider. 次点でBox/CapsuleCollider) を設定
    - IsTrigger のOn/Offはどちらでも良いです
  2. ARPlane とARmesh表示用のPrefabそれぞれにMeshColliderを設定する
    • ARPlane に関しては厳密さを求めなければBoxColliderで代用も可能
    • ARMeshに関してはMeshColliderでないと正しくとれない
    • MeshColliderconvex はOff にしよう
      • 計算量は増えるが  convex を onにする後述の問題が発生してしまう
    • ARPlane/ARMesh 側のColliderはできれば IsTrigger = Off にしましょう

このようにすれば基本的には現実の見た目とおおよそ一致する場所に当たり判定が生成されます

ARPlane/ARMesh側にRigidbody をつけて当たり判定を実装する場合

コンテンツによっては投擲物の個数が当たり判定Objectより多く出るなんて場合もあります。
その場合はARPlane/ARMesh 側にRigidbody をつけて当たり判定を行わせることで投擲物側の処理コストを下げるというパフォーマンスの稼ぎ方もあります。

その場合ARPlane/ARMesh 側にRigidbodyを追加するのですが、MeshCollider において、Rigidbodyを併用する場合以下の制約があります。

  • MeshCollider のConvexフラグをOffにする場合Rigidbody.isKinematic フラグをOnにしないと動かない
    • isKinematic フラグをOffだと当たり判定がとれない
    • Convex フラグをOnにするとARMeshの当たり判定が見た目通りにならない

ARMeshとMeshCollider のconvex フラグにまつわる問題

Unity のMeshColliderのマニュアルを確認しましょう.

バーチャルキャストさんのTechブログ 等でも紹介されていますが

そこではConvex フラグについて以下のような記述があります.

これを有効にすると、メッシュコライダーは他のメッシュコライダーと衝突します。 Convex (凸状) のメッシュコライダーは三角形面数の上限が 255 に制限されます。

詳細は割愛しますが凸型にすることで当たり判定の計算コストをかなり減らすことができるのtMeshCollider利用した当たり判定をとるときはConvex フラグをOnにします。

一方で、後半の文章にある メッシュコライダーは三角形面数の上限が 255 に制限 が非常に厄介です。

一般的にゲームでMeshCollider はそこまでハイポリのものには使わないです。
(敵キャラの判定も、判定があるところにSphere ColliderやCapsuleColliderを複数置いて、Meshの範囲をカバーするように配置して軽量化を図って実装されることがほとんどです. 主人公キャラ等も胴体、腕、足それぞれにCapsuleCollider を配置で十分なため、MeshColliderは使いません)

しかし、リアルタイムスキャンして取得したARMeshについてはポリゴン数が255を優に超える場合があります。(リアルタイムでMeshのReductionは難しいため)そうするとARMesh にConvexフラグを適応すると、 見た目のMesh当たり判定用のMesh が  異なる という現象が生じます。

結果として、何もない空中に謎の当たり判定が生まれるなどの副作用が生じます

現実のものでOcculusion(背後に隠れてるところは見えない)させる

こちらについては以前の記事でも記載しましたが、ARPLane/ARMesh Prefabの各Renderer に設定されているMaterialのShader を AR/Basic Occulusion にするだけです。

これだけで現実のObjectの背後にあるコンテンツは一部/全体を隠すことが出来ます。
また上記の当たり判定を併用すれば、現実の背後にある敵には、 現実のものが邪魔で攻撃できない ということが実現可能です。

2
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
1