本文へスキップ

デバイスマップを作成する

注目してほしい!

この機能は実験的なものであり、期待通りに動作しない可能性があります。 詳しくは、デバイスマッピング機能ページをご覧ください。

ARアプリケーションでデバイスマップを使用する前に、デバイスマップを作成して保存する必要があります。 このチュートリアルでは、Unityプロジェクト内でデバイスマップを作成して保存する方法と、デバイスマッピングを最大限に活用するためのヒントをご紹介します。

前提条件

ARDKがインストールされたUnityプロジェクトと、基本的なARシーンが必要です。 詳しくは、Lightship ARDKの設定および基本ARシーンの設定を参照してください。

デバイスマップを作成する

デバイスマップを作成し、保存するには、次の手順で行います。

  1. HierarchyXROrigin を選択し、 InspectorAdd Component をクリックして、 ARDeviceMappingManager を追加します。
  2. Hierarchy でARシーンのルートを右クリックし、 Create Empty を選択します。 新しいオブジェクトに DeviceMappingDemo という名前を付けます。
  3. Hierarchy から DeviceMappingDemo を選択し、 InspectorAdd Component をクリックします。 New Script を検索して追加し、 Mapper.cs という名前を付けます。
  4. Mapper.cs を開き、その内容を次のスニペットに置き換えます。
using System;
using System.Collections;
using System.IO;
using Niantic.Lightship.AR.Mapping;
using UnityEngine;
using UnityEngine.UI;

public class Mapper : MonoBehaviour
{

}
  1. 次の手順で、マッパーのUI要素を追加します。

    1. Hierarchy で右クリックして Create メニューを開き、 UI サブメニューから Button を選択します。 これで、 Canvas が作成され、ボタンがその下に追加されます。
  2. ボタンが押されたときに10秒間のマッピングを行うように、次のスニペットを Mapper クラスに追加します。

    [SerializeField]
    private ARDeviceMappingManager _deviceMappingManager;

    [SerializeField]
    private Button _startMappingButton;

    private void Start()
    {
    _startMappingButton.onClick.AddListener(OnStartMappingClicked);
    }

    // Set this function to be called when button is clicked
    public void OnStartMappingClicked()
    {
    StartCoroutine(RunMapping());
    }

    private IEnumerator RunMapping()
    {
    // disable the button after clicking so that only one map is made at a time
    _startMappingButton.gameObject.SetActive(false);
    _deviceMappingManager.SetDeviceMap(new ARDeviceMap());
    _deviceMappingManager.StartMapping();
    // change this value to map for more or less time
    yield return new WaitForSeconds(10.0f);
    _deviceMappingManager.StopMapping();
    _startMappingButton.gameObject.SetActive(true);
    }
備考

デスクやソファのような小さなエリアをマッピングするには10秒で十分です。 これよりも広い範囲をマッピングする場合は、マッピング時間を長くしてください。

  1. マップを保存するタイミングが分かるように、UIコードの後に、 ARDeviceMappingManager.DeviceMapFinalized のイベントリスナーを追加します。

    private const string MapFileName = "SerializedDeviceMapData";

    private void Start()
    {
    // Add this below the previous section's code in Start()
    _deviceMappingManager.DeviceMapFinalized += OnDeviceMapFinalized;
    }

    private void OnDeviceMapFinalized(ARDeviceMap map)
    {
    if (map.HasValidMap())
    {
    // final map generated. save to the file system
    var serializedDeviceMap = map.Serialize();
    var path = Path.Combine(Application.persistentDataPath, MapFileName);
    File.WriteAllBytes(path, serializedDeviceMap);
    Debug.Log($"Map saved");
    }
    else
    {
    Debug.LogError("Map was empty");
    }
    }
備考

最終的なデバイスマップは StopMapping() が呼び出された後に生成されますが、 DeviceMapFinalized イベントが呼び出されるまで利用できません。 ボタンが押されたら、最終化イベントが呼び出されるまで待機してください。

オプション:マッピング中にメッシュを表示する

デフォルトでは、 ARDeviceMappingManager でエリアをマッピングしている間、視覚的なフィードバックは表示されません。 プロジェクトにメッシングを追加することで、マップのカバレッジを視覚化し、カバーすべきエリアを把握することができます。 メッシュは、デバイスマップが生成された位置やローカライズが成功する可能性を正確に示すものではありませんが、マップのエリアを大まかにイメージするのに役立ちます。 Lightshipプロジェクトにメッシングを追加する方法については、メッシュの作成を参照してください。

デバイスマッピングのヒント

  • デバイスマッピングは1回のスキャンで行われるため、ローカライゼーションとトラッキングの精度は、エリアをどの程度正確にスキャンできるかに大きく左右されます。 これだけは覚えておいてください。 ローカライゼーションに問題がある場合は、再スキャンをためらわない
  • エリアをスキャンする際は、照明が非常に重要です。 ローカライゼーション時の照明がスキャンと一致しない場合は、再スキャンが必要になります (屋外と屋内の照明も含まれます)。
  • 最良の結果を得るために、スキャンする際は以下のガイドラインに従ってください。
    • 家具、住宅設備、彫像など、スキャンとローカライゼーションの間に動く可能性が低い、エリア内の特徴的な物体に焦点を当てます。
    • 地面、芝生(草)、壁、床など、色の変化がない平らな面を中心に見ることは避けてください。
    • スキャンは、動きながら行いましょう。 オブジェクトを見る視点が増えるほど、マップの正確性が向上します。

デバイスマッピングの最終版スクリプト

マッピングスクリプトの作成でお困りの場合は、以下の完成版スクリプトを参考にしてください。

クリックして、最終版のMapper.csスクリプトを表示
using System;
using System.Collections;
using System.IO;
using Niantic.Lightship.AR.Mapping;
using UnityEngine;
using UnityEngine.UI;

public class Mapper : MonoBehaviour
{
public const string MapFileName = "SerializedDeviceMapData";

[SerializeField]
private ARDeviceMappingManager _deviceMappingManager;

[SerializeField]
private Button _startMappingButton;

private void Start()
{
_deviceMappingManager.DeviceMapFinalized += OnDeviceMapFinalized;
_startMappingButton.onClick.AddListener(OnStartMappingClicked);
}

private void OnDeviceMapFinalized(ARDeviceMap map)
{
if (map.HasValidMap())
{
// final map generated. save to the file system
var serializedDeviceMap = map.Serialize();
var path = Path.Combine(Application.persistentDataPath, MapFileName);
File.WriteAllBytes(path, serializedDeviceMap);
Debug.Log($"Map saved");
}
else
{
Debug.LogError("Map was empty");
}
}

// Set this function to be called when button is clicked
public void OnStartMappingClicked()
{
StartCoroutine(RunMapping());
}

private IEnumerator RunMapping()
{
_startMappingButton.gameObject.SetActive(false);
_deviceMappingManager.SetDeviceMap(new ARDeviceMap());
_deviceMappingManager.StartMapping();
yield return new WaitForSeconds(10.0f);
_deviceMappingManager.StopMapping();
_startMappingButton.gameObject.SetActive(true);
}

}

次のステップ

デバイスマップを作成して保存したら、デバイスマップを使用して仮想コンテンツを配置するに進みましょう。