using System;
using System.Collections.Generic;
using UnityEngine.XR.ARSubsystems;
using Unity.XR.CoreUtils;
namespace UnityEngine.XR.ARFoundation
{
///
/// A manager for s. Uses the XRObjectTrackingSubsystem
/// to recognize and track 3D objects in the physical environment.
///
///
/// Related information: AR Tracked Object Manager component
///
[DefaultExecutionOrder(ARUpdateOrder.k_TrackedObjectManager)]
[DisallowMultipleComponent]
[RequireComponent(typeof(XROrigin))]
[AddComponentMenu("XR/AR Foundation/AR Tracked Object Manager")]
[HelpURL("features/object-tracking")]
public sealed class ARTrackedObjectManager : ARTrackableManager<
XRObjectTrackingSubsystem,
XRObjectTrackingSubsystemDescriptor,
XRObjectTrackingSubsystem.Provider,
XRTrackedObject,
ARTrackedObject>
{
[SerializeField]
[Tooltip("The library of objects which will be detected and/or tracked in the physical environment.")]
XRReferenceObjectLibrary m_ReferenceLibrary;
///
/// The ARObjectLibrary to use during object detection. This is the
/// library of objects which will be detected and tracked in the physical environment.
///
public XRReferenceObjectLibrary referenceLibrary
{
get => m_ReferenceLibrary;
set
{
m_ReferenceLibrary = value;
UpdateReferenceObjects();
if (subsystem != null)
{
subsystem.library = m_ReferenceLibrary;
}
}
}
[SerializeField]
[Tooltip("If not null, instantiates this prefab for each detected object.")]
GameObject m_TrackedObjectPrefab;
///
/// If not null, instantiates this Prefab for each detected object.
///
public GameObject trackedObjectPrefab
{
get => m_TrackedObjectPrefab;
set => m_TrackedObjectPrefab = value;
}
///
/// Get the Prefab to instantiate for each .
///
/// The prefab to instantiate for each .
protected override GameObject GetPrefab() => m_TrackedObjectPrefab;
///
/// Invoked once per frame with information about the s that have changed (that is, been added, updated, or removed).
/// This happens just before s are destroyed, so you can set ARTrackedObject.destroyOnRemoval to false
/// from this event to suppress this behavior.
///
[Obsolete("trackedObjectsChanged has been deprecated in AR Foundation version 6.0. Use trackablesChanged instead.", false)]
public event Action trackedObjectsChanged;
///
/// The name to be used for the GameObject whenever a new object is detected.
///
protected override string gameObjectName => "ARTrackedObject";
///
/// Sets the object library on the subsystem before Start() is called on the base class.
///
protected override void OnBeforeStart()
{
UpdateReferenceObjects();
if (referenceLibrary != null)
{
subsystem.library = referenceLibrary;
}
else
{
enabled = false;
#if DEVELOPMENT_BUILD
Debug.LogWarning($"{nameof(ARTrackedObjectManager)} '{name}' was enabled but no reference object library is specified. To enable, set a valid reference object library and then re-enable this component.");
#endif
}
}
///
/// Invoked just after each has been updated.
///
/// The being updated.
/// New data associated with .
/// All spatial data is relative to the .
protected override void OnAfterSetSessionRelativeData(
ARTrackedObject trackedObject,
XRTrackedObject sessionRelativeData)
{
if (m_ReferenceLibrary != null && m_ReferenceObjectCount != m_ReferenceLibrary.count)
{
// Since reference libraries can change, make sure
// our reference object dictionary is up to date.
UpdateReferenceObjects();
}
var guid = sessionRelativeData.referenceObjectGuid;
if (!m_ReferenceObjects.TryGetValue(guid, out var referenceObject))
{
Debug.LogError($"Could not find reference object with guid {guid}");
}
trackedObject.referenceObject = referenceObject;
}
///
/// Invokes the event.
///
/// A list of objects added this frame.
/// A list of objects updated this frame.
/// A list of objects removed this frame.
[Obsolete("OnTrackablesChanged() has been deprecated in AR Foundation version 6.0.", false)]
protected override void OnTrackablesChanged(
List added,
List updated,
List removed)
{
if (trackedObjectsChanged != null)
{
using (new ScopedProfiler("OnTrackedObjectsChanged"))
trackedObjectsChanged?.Invoke(
new ARTrackedObjectsChangedEventArgs(
added,
updated,
removed));
}
}
void UpdateReferenceObjects()
{
m_ReferenceObjects.Clear();
m_ReferenceObjectCount = 0;
if (m_ReferenceLibrary == null)
return;
foreach (var referenceObject in m_ReferenceLibrary)
{
m_ReferenceObjects[referenceObject.guid] = referenceObject;
}
m_ReferenceObjectCount = m_ReferenceObjects.Count;
}
int m_ReferenceObjectCount;
Dictionary m_ReferenceObjects = new Dictionary();
}
}