ARTrackedObjectManager.cs
5.91 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
using System;
using System.Collections.Generic;
using UnityEngine.XR.ARSubsystems;
namespace UnityEngine.XR.ARFoundation
{
/// <summary>
/// A manager for <see cref="ARTrackedObject"/>s. Uses the <c>XRObjectTrackingSubsystem</c>
/// to recognize and track 3D Objects in the physical environment.
/// </summary>
[DefaultExecutionOrder(ARUpdateOrder.k_TrackedObjectManager)]
[DisallowMultipleComponent]
[RequireComponent(typeof(ARSessionOrigin))]
[HelpURL(HelpUrls.ApiWithNamespace + nameof(ARTrackedObjectManager) + ".html")]
public sealed class ARTrackedObjectManager : ARTrackableManager<
XRObjectTrackingSubsystem,
XRObjectTrackingSubsystemDescriptor,
#if UNITY_2020_2_OR_NEWER
XRObjectTrackingSubsystem.Provider,
#endif
XRTrackedObject,
ARTrackedObject>
{
[SerializeField]
[Tooltip("The library of objects which will be detected and/or tracked in the physical environment.")]
XRReferenceObjectLibrary m_ReferenceLibrary;
/// <summary>
/// The <c>ARObjectLibrary</c> to use during Object detection. This is the
/// library of objects which will be detected and/or tracked in the physical environment.
/// </summary>
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;
/// <summary>
/// If not null, instantiates this prefab for each detected object.
/// </summary>
public GameObject trackedObjectPrefab
{
get => m_TrackedObjectPrefab;
set => m_TrackedObjectPrefab = value;
}
/// <summary>
/// Get the prefab to instantiate for each <see cref="ARTrackedObject"/>.
/// </summary>
/// <returns>The prefab to instantiate for each <see cref="ARTrackedObject"/>.</returns>
protected override GameObject GetPrefab() => m_TrackedObjectPrefab;
/// <summary>
/// Invoked once per frame with information about the <see cref="ARTrackedObject"/>s that have changed, i.e., been added, updated, or removed.
/// This happens just before <see cref="ARTrackedObject"/>s are destroyed, so you can set <c>ARTrackedObject.destroyOnRemoval</c> to <c>false</c>
/// from this event to suppress this behavior.
/// </summary>
public event Action<ARTrackedObjectsChangedEventArgs> trackedObjectsChanged;
/// <summary>
/// The name to be used for the <c>GameObject</c> whenever a new Object is detected.
/// </summary>
protected override string gameObjectName => "ARTrackedObject";
/// <summary>
/// Sets the Object library on the subsystem before Start() is called on the base class.
/// </summary>
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
}
}
/// <summary>
/// Invoked just after each <see cref="ARTrackedObject"/> has been updated.
/// </summary>
/// <param name="trackedObject">The <see cref="ARTrackedObject"/> being updated.</param>
/// <param name="sessionRelativeData">New data associated with <paramref name="trackedObject"/>.
/// All spatial data is relative to the <see cref="ARSessionOrigin"/>.</param>
protected override void OnAfterSetSessionRelativeData(
ARTrackedObject trackedObject,
XRTrackedObject sessionRelativeData)
{
var guid = sessionRelativeData.referenceObjectGuid;
XRReferenceObject referenceObject;
if (!m_ReferenceObjects.TryGetValue(guid, out referenceObject))
{
Debug.LogErrorFormat("Could not find reference object with guid {0}", guid);
}
trackedObject.referenceObject = referenceObject;
}
/// <summary>
/// Invokes the <see cref="trackedObjectsChanged"/> event.
/// </summary>
/// <param name="added">A list of objects added this frame.</param>
/// <param name="updated">A list of objects updated this frame.</param>
/// <param name="removed">A list of objects removed this frame.</param>
protected override void OnTrackablesChanged(
List<ARTrackedObject> added,
List<ARTrackedObject> updated,
List<ARTrackedObject> removed)
{
if (trackedObjectsChanged != null)
{
using (new ScopedProfiler("OnTrackedObjectsChanged"))
trackedObjectsChanged(
new ARTrackedObjectsChangedEventArgs(
added,
updated,
removed));
}
}
void UpdateReferenceObjects()
{
m_ReferenceObjects.Clear();
if (m_ReferenceLibrary == null)
return;
foreach (var referenceObject in m_ReferenceLibrary)
m_ReferenceObjects[referenceObject.guid] = referenceObject;
}
Dictionary<Guid, XRReferenceObject> m_ReferenceObjects = new Dictionary<Guid, XRReferenceObject>();
}
}