デバイスマップの作成方法
ARアプリケーションでデバイスマップを使用する前に、デバイスマップを作成して保存する必要があります。 このチュートリアルでは、Unityプロジェクトでデバイスマップを作成して保存する方法と、デバイスマッピングを最大限に活用するためのヒントについて説明します。
前提条件
ARDKがインストールされたUnityプロジェクトと、基本的なARシーンが必要です。 詳しくは、Lightship ARDKの設定および基本ARシーンの設定を参照してください。
デバイスマップの作成
デバイスマップを作成し、保存する:
- Hierarchy** で XROrigin を選択し、Inspector で Add Component をクリックして
ARDeviceMappingManager
を追加します。 - Hierarchy**でARシーンのルートを右クリックし、Create Emptyを選択します。 新しいオブジェクト の名前を
DeviceMappingDemo
とする。 - Hierarchyから
DeviceMappingDemo
を選択し、InspectorでAdd Componentをクリックします。 新しいスクリプトを検索して追加し、名前をMapper.cs
とします。 - Mapper.cs`を開き、その内容を以下のスニペットで置き換える:
using System;
using System.Collections;
using System.IO;
using Niantic.Lightship.AR.Mapping;
using UnityEngine;
using UnityEngine.UI;
public class Mapper : MonoBehaviour
{
}
-
マッパーのUI要素を追加する:
- 階層で右クリックし、Createメニューを開き、UIサブメニューからButtonを選択します。 これでCanvas**要素が作成され、そこにボタンが追加されます。
-
このスニペットを
Mapper
クラスに追加して、ボタンが押されたときに10秒間マッピングする:[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秒は十分な時間だ。 より広い範囲をマッピングする場合は、マッピング時間を長くしてください。
-
UIコードの後に、
ARDeviceMappingManager.DeviceMapFinalized
のイベントリスナーを追加して、マップを保存するタイミングが分かるようにします:private const string MapFileNamePrefix = "SerializedDeviceMapData";
private void 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);
}
}
次のステップ
デバイスマップを作成して保存したら、デバイスマップを使 用して実世界のコンテンツを配置する方法に進みます。