// NOTE: Taken from https://github.com/dilmerv/UnityARFoundationEssentials/blob/master/Assets/Scripts/TrackedImageInfoMultipleManager.cs // This has been modified to fit the need of the UDRI XRTeam's use-cases using System.Collections.Generic; using System.Linq; using Unity.Logging; using Unity.Mathematics; using UnityAtoms.BaseAtoms; using UnityEngine; using UnityEngine.XR.ARFoundation; namespace MAVRIC.GEEEKCup.Samples.QRCode { public class TrackedImageChanged : MonoBehaviour { [SerializeField] private LogLevel logLevel = LogLevel.Warning; [SerializeField] private ARTrackedImageManager trackedImageManager; // [SerializeField] private GameObjectReference parentObject; [SerializeField] private GameObject[] arPrefabs; [SerializeField] private float3 scaleFactor = new (0.1f, 0.1f, 0.1f); [Tooltip("Parent object for all ARObjects. DO NOT SET MANUALLY.")] [SerializeField] private Transform parentObject; private Dictionary arObjects = new (); private void Awake() { if (trackedImageManager == null) { if (!TryGetComponent(out trackedImageManager)) { Log.Error("Failed to find ARTrackedImageManager...", this.gameObject); } } if (parentObject == null) { parentObject = gameObject.transform; } } private void OnEnable() { if (trackedImageManager == null) return; trackedImageManager.trackedImagesChanged += OnTrackedImagesChanged; SpawnAllARObjects(); } private void OnDisable() { if (trackedImageManager == null) return; trackedImageManager.trackedImagesChanged -= OnTrackedImagesChanged; for (int i = arObjects.Keys.Count - 1; i >= 0; i--) { var key = arObjects.Keys.ElementAt(i); if (arObjects.Remove(key, out var value)) { Destroy(value); } } } private void SpawnAllARObjects() { // setup all game objects in dictionary foreach (GameObject arObject in arPrefabs) { GameObject newARObject = Instantiate(arObject, Vector3.zero, Quaternion.identity); newARObject.transform.SetParent(parentObject, false); newARObject.SetActive(false); newARObject.name = arObject.name; arObjects.Add(arObject.name, newARObject); } } private void OnTrackedImagesChanged(ARTrackedImagesChangedEventArgs eventArgs) { foreach (ARTrackedImage trackedImage in eventArgs.added) { UpdateARImage(trackedImage); } foreach (ARTrackedImage trackedImage in eventArgs.updated) { UpdateARImage(trackedImage); } foreach (ARTrackedImage trackedImage in eventArgs.removed) { arObjects[trackedImage.name].SetActive(false); } } private void UpdateARImage(ARTrackedImage trackedImage) { // Assign and Place Game Object AssignGameObject(trackedImage.referenceImage.name, trackedImage.transform.position, scaleFactor, trackedImage.transform.rotation); Log.Verbose("trackedImage.referenceImage.name: {0}", trackedImage.referenceImage.name); } private void AssignGameObject(string name, Vector3 newPosition, Vector3 newScale, Quaternion newRotation) { if (arPrefabs != null) { GameObject goARObject = arObjects[name]; goARObject.transform.SetParent(parentObject, false); goARObject.SetActive(true); goARObject.transform.position = new float3(newPosition.x, parentObject.position.y, newPosition.z); goARObject.transform.localScale = newScale; goARObject.transform.rotation = newRotation; foreach (GameObject go in arObjects.Values) { Log.Verbose("Go in arObjects.Values: {0}", go.name); if (go.name != name) { go.SetActive(false); } } } } public void SetParentObject(GameObject parent) { parentObject = parent.transform; foreach (var (_, value)in arObjects) { var tempPosition = new float3(value.transform.position); value.transform.SetParent(parentObject, false); value.transform.localPosition = new float3(tempPosition.x, 0f, tempPosition.z); } } } }