【Unity】ARCore:AugmentedImageでトラッキングが外れた時に表示用オブジェクトを破棄する
開発環境
Unity2019.1.0f2
ARCore1.9
問題点
ARCoreのUnity用PackageのAugmentedImageサンプルシーンに含まれるAugmentedImageExampleController.csの下記の部分だが、image.TrackingState == TrackingState.Stoppedとすることでトラッキングが外れた時に表示用オブジェクトを破棄するように書かれている。しかし、実際にアプリをビルドしてみると明らかに対象が画面外に出ているのにかかわらず表示用オブジェクトが破棄されずに画面内に残ったままになっている。
foreach (var image in m_TempAugmentedImages)
{
AugmentedImageVisualizer visualizer = null;
m_Visualizers.TryGetValue(image.DatabaseIndex, out visualizer);
if (image.TrackingState == TrackingState.Tracking && visualizer == null)
{
// Create an anchor to ensure that ARCore keeps tracking this augmented image.
Anchor anchor = image.CreateAnchor(image.CenterPose);
visualizer = (AugmentedImageVisualizer)Instantiate(
AugmentedImageVisualizerPrefab, anchor.transform);
visualizer.Image = image;
m_Visualizers.Add(image.DatabaseIndex, visualizer);
}
else if (image.TrackingState == TrackingState.Stopped && visualizer != null)
{
m_Visualizers.Remove(image.DatabaseIndex);
GameObject.Destroy(visualizer.gameObject);
}
}
developer guideによると動画でAugmented Imageを使用する際には、TrackingStateに加えてAugmentedImageTrackingMethodを使用しているらしい。
AugmentedImageTrackingMethodの挙動を確認してみると対象がカメラ内に映っている時はAugmentedImageTrackingMethodがFullTrackingになり、カメラの範囲外に出るとLastKnownPoseに変化した。この時、TrackingStateはTrackingのまま変化しなかった。
解決策
そこで、AugmentedImageTrackingMethodがFullTrackingの時に表示用オブジェクトを生成し、LastKnownPoseの時に破棄するように変更する。
foreach (var image in m_TempAugmentedImages)
{
AugmentedImageVisualizer visualizer = null;
m_Visualizers.TryGetValue(image.DatabaseIndex, out visualizer);
if (image.TrackingState == TrackingState.Tracking && visualizer == null)
{
if (image.TrackingMethod == AugmentedImageTrackingMethod.FullTracking)
{
Anchor anchor = image.CreateAnchor(image.CenterPose);
visualizer = (AugmentedImageVisualizer)Instantiate(
AugmentedImageVisualizerPrefab, anchor.transform);
visualizer.Image = image;
m_Visualizers.Add(image.DatabaseIndex, visualizer);
}
}
else
{
if(image.TrackingMethod == AugmentedImageTrackingMethod.LastKnownPose)
{
m_Visualizers.Remove(image.DatabaseIndex);
GameObject.Destroy(visualizer.gameObject);
}
}
}