您最多选择25个主题
主题必须以中文或者字母或数字开头,可以包含连字符 (-),并且长度不得超过35个字符
96 行
3.0 KiB
96 行
3.0 KiB
using System.Collections.Generic;
|
|
using Unity.Collections;
|
|
using UnityEngine;
|
|
using UnityEngine.XR.ARFoundation;
|
|
using UnityEngine.XR.ARSubsystems;
|
|
|
|
#if UNITY_ANDROID && !UNITY_EDITOR
|
|
using UnityEngine.XR.ARCore;
|
|
#endif
|
|
|
|
/// <summary>
|
|
/// 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 <see cref="regionPrefab"/>
|
|
/// at each detected region.
|
|
/// </summary>
|
|
[RequireComponent(typeof(ARFaceManager))]
|
|
[RequireComponent(typeof(ARSessionOrigin))]
|
|
public class ARCoreFaceRegionManager : MonoBehaviour
|
|
{
|
|
[SerializeField]
|
|
GameObject m_RegionPrefab;
|
|
|
|
/// <summary>
|
|
/// Get or set the prefab which will be instantiated at each detected face region.
|
|
/// </summary>
|
|
public GameObject regionPrefab
|
|
{
|
|
get { return m_RegionPrefab; }
|
|
set { m_RegionPrefab = value; }
|
|
}
|
|
|
|
ARFaceManager m_FaceManager;
|
|
|
|
ARSessionOrigin m_SessionOrigin;
|
|
|
|
#if UNITY_ANDROID && !UNITY_EDITOR
|
|
NativeArray<ARCoreFaceRegionData> m_FaceRegions;
|
|
|
|
Dictionary<TrackableId, Dictionary<ARCoreFaceRegion, GameObject>> m_InstantiatedPrefabs;
|
|
#endif
|
|
|
|
// Start is called before the first frame update
|
|
void Start()
|
|
{
|
|
m_FaceManager = GetComponent<ARFaceManager>();
|
|
m_SessionOrigin = GetComponent<ARSessionOrigin>();
|
|
#if UNITY_ANDROID && !UNITY_EDITOR
|
|
m_InstantiatedPrefabs = new Dictionary<TrackableId, Dictionary<ARCoreFaceRegion, GameObject>>();
|
|
#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<ARCoreFaceRegion, GameObject> regionGos;
|
|
if (!m_InstantiatedPrefabs.TryGetValue(face.trackableId, out regionGos))
|
|
{
|
|
regionGos = new Dictionary<ARCoreFaceRegion, GameObject>();
|
|
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
|
|
}
|
|
}
|