本文へスキップ
バージョン: 3.4

深度を使って画面上の地点を現実世界の位置に変換する

ARDK 3.0の深度マップ出力により、平面やメッシュを使用せずに、ARシーンにオブジェクトを動的に配置することができます。 この例では、深度出力をもとに画面上の地点を選択し、オブジェクトを配置する方法を解説します。

前提条件

Lightship ARを有効にしたUnityのプロジェクトが必要です。 詳細については、 ARDK 3 のインストールを参照してください。

ヒント

初めて深度を使うのであれば、 Accessing and Displaying Depth Information は、深度のより単純な使用例を提供しており始めやすいです。

手順

メインシーンがAR対応でない場合は、次のように設定します。

  1. Main Camera を削除します。

  2. ARSessionXROrigin を階層に追加し、 AR Occlusion Manager Component をどちらかに追加します。

    AR SessionとXR OriginAR Occlusion Manager
  3. 深度のピッキングとプレハブの配置を処理するスクリプトを作成します。 Depth_ScreenToWorldPositionと名付け、対応するコードを追加する。

クリックするとDepth_ScreenToWorldPositionスクリプトが表示されます。
using Niantic.Lightship.AR.Utilities;
using UnityEngine;
using UnityEngine.XR.ARFoundation;
using UnityEngine.XR.ARSubsystem; public class Depth_ScreenToWorldPosition : MonoBehaviourARSubsystems;
public class Depth_ScreenToWorldPosition : MonoBehaviour
{
public AROcclusionManager _occMan;
public ARCameraManager _arCameraManager;
public Camera _camera;
public GameObject _prefabToSpawn;
private Matrix4x4 m_DisplayMatrix;
XRCpuImage? depthimage;
private void OnEnable()
{
_arCameraManager.frameReceived += OnCameraFrameEventReceived;
}
private void OnDisable()
{
_arCameraManager.frameReceived -= OnCameraFrameEventReceived;
}
private void OnCameraFrameEventReceived(ARCameraFrameEventArgs args)
{
// 画面から画像への変換をキャッシュ
if (args.displayMatrix.HasValue)
{
#if UNITY_IOS
m_DisplayMatrix = args.displayMatrix.Value.transpose;
#else
m_DisplayMatrix = args.displayMatrix.Value;
#endif
}.
}
void Update()
{
if (!_occMan.subsystem.running)
{
return;
}
if (_occMan.TryAcquireEnvironmentDepthCpuImage(out
var image))
{
depthimage?.Dispose();
depthimage = image;
}
else
{
return;
}.
#if UNITY_EDITOR
if (Input.GetMouseButtonDown(0))
{
var screenPosition = new Vector2(Input.mousePosition.x, Input.mousePosition.y);
#else
if (Input.touches.Length > 0) {
var screenPosition = Input.GetTouch(0).position;
#endif
if (depthimage.HasValue)
{
// Sample eye depth
var uv = new Vector2(screenPosition.x / Screen.width, screenPosition.y / Screen.height);
var eyeDepth = depthimage.Value.Sample<float>(uv, m_DisplayMatrix);
// ワールド位置を取得
var worldPosition =
_camera.ScreenToWorldPoint(new Vector3(screenPosition.x, screenPosition.y, eyeDepth));
//デプスマップ上にモノをスポーンする
Instantiate(_prefabToSpawn, worldPosition, Quaternion.identity);
}.
}
}
}
  1. Depth_ScreenToWorldPosition スクリプトを、 XROrigin のコンポーネントとして、 Hierarchy に追加します:
    1. Hierarchy ウィンドウで、 XROriginを選択し、 Inspectorで、 Add Component をクリックします。
    2. Depth_ScreenToWorldPosition スクリプトを検索し、選択します。
  2. シーンにスポーンするオブジェクトとして使用するため、 Cube を作成します:
    1. Hierarchyで右クリックし、 Create メニューで、 3D Object にマウスオーバーし、 Cubeを選択します。
    2. 新しい Cube オブジェクトを Hierarchy から Assets ウィンドウにドラッグしてプレハブを作成し、 Hierarchyから削除します。 ( Assets ウィンドウの Cube は残るはずです)。
  3. Depth_ScreenToWorldPosition スクリプトのフィールドを割り当てます:
    1. Hierarchy ウィンドウで、 XROriginを選択し、 Inspector ウィンドウで、 Depth_ScreenToWorldPosition Component を展開します。
    2. XROriginOcc Man フィールドに割り当てます。
    3. メインカメラカメラ フィールドに割り当てます。
    4. メインカメラを _arCameraManagerフィールドに割り当てます。
    5. 新しい Cube プレハブを Prefab to Spawn フィールドに割り当てます。
  4. Build Settings(ビルド設定) を開き、 Build and Run(ビルドと実行) をクリックしてデバイスにビルドし、試してみましょう。

詳細情報