using System;
using System.Collections.Generic;
using UnityEngine.XR.ARSubsystems;
using Unity.XR.CoreUtils;
using UnityEngine.Serialization;
namespace UnityEngine.XR.ARFoundation
{
///
/// Creates, updates, and removes GameObjects with components under the
/// 's .
///
///
/// When enabled, this component subscribes to event to update face data.
/// If this component is disabled, and there are no other subscribers to those events,
/// face detection will be disabled on the device.
///
/// Related information: AR Face Manager component
///
[RequireComponent(typeof(XROrigin))]
[DisallowMultipleComponent]
[DefaultExecutionOrder(ARUpdateOrder.k_FaceManager)]
[AddComponentMenu("XR/AR Foundation/AR Face Manager")]
[HelpURL("features/face-tracking")]
public sealed class ARFaceManager : ARTrackableManager<
XRFaceSubsystem,
XRFaceSubsystemDescriptor,
XRFaceSubsystem.Provider,
XRFace,
ARFace>
{
[SerializeField]
[Tooltip("If not null, instantiates this prefab for each created face.")]
GameObject m_FacePrefab;
///
/// Getter/setter for the Face Prefab.
///
public GameObject facePrefab
{
get => m_FacePrefab;
set => m_FacePrefab = value;
}
[SerializeField]
[Tooltip("The maximum number of faces to track simultaneously.")]
int m_MaximumFaceCount = 1;
///
/// Get or set the requested maximum number of faces to track simultaneously
///
public int requestedMaximumFaceCount
{
get => subsystem?.requestedMaximumFaceCount ?? m_MaximumFaceCount;
set
{
m_MaximumFaceCount = value;
if (enabled && subsystem != null)
{
subsystem.requestedMaximumFaceCount = value;
}
}
}
///
/// Get the maximum number of faces to track simultaneously.
///
public int currentMaximumFaceCount => subsystem?.currentMaximumFaceCount ?? 0;
///
/// Get the supported number of faces that can be tracked simultaneously. This value
/// might change when the configuration changes.
///
public int supportedFaceCount => subsystem?.supportedFaceCount ?? 0;
///
/// Raised for each new detected in the environment.
///
[Obsolete("facesChanged has been deprecated in AR Foundation version 6.0. Use trackablesChanged instead.", false)]
public event Action facesChanged;
///
/// Attempts to retrieve an .
///
/// The TrackableId associated with the .
/// The if found. null otherwise.
public ARFace TryGetFace(TrackableId faceId)
{
m_Trackables.TryGetValue(faceId, out ARFace face);
return face;
}
///
/// Invoked just before calling `Start` on the Subsystem. Used to set the `requestedMaximumFaceCount`
/// on the subsystem.
///
protected override void OnBeforeStart()
{
subsystem.requestedMaximumFaceCount = m_MaximumFaceCount;
}
///
/// Invoked just after an has been updated.
///
///
///
protected override void OnAfterSetSessionRelativeData(
ARFace face,
XRFace sessionRelativeData)
{
face.UpdateMesh(subsystem);
if (subsystem.subsystemDescriptor.supportsEyeTracking)
face.UpdateEyes();
}
///
/// Invoked when the base class detects trackable changes.
///
/// The list of added s.
/// The list of updated s.
/// The list of removed s.
[Obsolete("OnTrackablesChanged() has been deprecated in AR Foundation version 6.0.", false)]
protected override void OnTrackablesChanged(
List added,
List updated,
List removed)
{
if (facesChanged != null)
{
using (new ScopedProfiler("OnFacesChanged"))
facesChanged?.Invoke(new ARFacesChangedEventArgs(added, updated, removed));
}
}
///
/// Get the Prefab that will be instantiated for each . Can be `null`.
///
/// The prefab that will be instantiated for each .
protected override GameObject GetPrefab() => m_FacePrefab;
///
/// The name assigned to each `GameObject` belonging to each .
///
protected override string gameObjectName => "ARFace";
}
}