using System.Collections.Generic; using Unity.Collections; using UnityEngine; using UnityEngine.XR.ARFoundation; using UnityEngine.XR.ARSubsystems; namespace UnityEngine.XR.ARFoundation.Samples { #if UNITY_ANDROID && !UNITY_EDITOR using UnityEngine.XR.ARCore; #endif /// /// This component uses the ARCoreFaceSubsystem to query for face regions, special /// regions detected within a face, such as the nose tip. Each region has a pose /// associated with it. This component instantiates /// at each detected region. /// [RequireComponent(typeof(ARFaceManager))] [RequireComponent(typeof(ARSessionOrigin))] public class ARCoreFaceRegionManager : MonoBehaviour { [SerializeField] GameObject m_RegionPrefab; /// /// Get or set the prefab which will be instantiated at each detected face region. /// public GameObject regionPrefab { get { return m_RegionPrefab; } set { m_RegionPrefab = value; } } ARFaceManager m_FaceManager; ARSessionOrigin m_SessionOrigin; #if UNITY_ANDROID && !UNITY_EDITOR NativeArray m_FaceRegions; Dictionary> m_InstantiatedPrefabs; #endif // Start is called before the first frame update void Start() { m_FaceManager = GetComponent(); m_SessionOrigin = GetComponent(); #if UNITY_ANDROID && !UNITY_EDITOR m_InstantiatedPrefabs = new Dictionary>(); #endif } // Update is called once per frame void Update() { #if UNITY_ANDROID && !UNITY_EDITOR var subsystem = (ARCoreFaceSubsystem)m_FaceManager.subsystem; if (subsystem == null) return; foreach (var face in m_FaceManager.trackables) { Dictionary regionGos; if (!m_InstantiatedPrefabs.TryGetValue(face.trackableId, out regionGos)) { regionGos = new Dictionary(); m_InstantiatedPrefabs.Add(face.trackableId, regionGos); } subsystem.GetRegionPoses(face.trackableId, Allocator.Persistent, ref m_FaceRegions); for (int i = 0; i < m_FaceRegions.Length; ++i) { var regionType = m_FaceRegions[i].region; GameObject go; if (!regionGos.TryGetValue(regionType, out go)) { go = Instantiate(m_RegionPrefab, m_SessionOrigin.trackablesParent); regionGos.Add(regionType, go); } go.transform.localPosition = m_FaceRegions[i].pose.position; go.transform.localRotation = m_FaceRegions[i].pose.rotation; } } #endif } void OnDestroy() { #if UNITY_ANDROID && !UNITY_EDITOR if (m_FaceRegions.IsCreated) m_FaceRegions.Dispose(); #endif } } }