using System; using System.Collections.Generic; using UnityEngine; using UnityEngine.UI; using UnityEngine.XR.ARSubsystems; using UnityEngine.XR.ARFoundation; /// This component listens for images detected by the XRImageTrackingSubsystem /// and overlays some information as well as the source Texture2D on top of the /// detected image. /// [RequireComponent(typeof(ARTrackedImageManager))] public class TrackedImageInfoManager : MonoBehaviour { [SerializeField] [Tooltip("The camera to set on the world space UI canvas for each instantiated image info.")] Camera m_WorldSpaceCanvasCamera; /// /// The prefab has a world space UI canvas, /// which requires a camera to function properly. /// public Camera worldSpaceCanvasCamera { get { return m_WorldSpaceCanvasCamera; } set { m_WorldSpaceCanvasCamera = value; } } [SerializeField] [Tooltip("If an image is detected but no source texture can be found, this texture is used instead.")] Texture2D m_DefaultTexture; /// /// If an image is detected but no source texture can be found, /// this texture is used instead. /// public Texture2D defaultTexture { get { return m_DefaultTexture; } set { m_DefaultTexture = value; } } ARTrackedImageManager m_TrackedImageManager; void Awake() { m_TrackedImageManager = GetComponent(); } void OnEnable() { m_TrackedImageManager.trackedImagesChanged += OnTrackedImagesChanged; } void OnDisable() { m_TrackedImageManager.trackedImagesChanged -= OnTrackedImagesChanged; } void UpdateInfo(ARTrackedImage trackedImage) { // Set canvas camera var canvas = trackedImage.GetComponentInChildren(); canvas.worldCamera = worldSpaceCanvasCamera; // Update information about the tracked image var text = canvas.GetComponentInChildren(); text.text = string.Format( "{0}\ntrackingState: {1}\nGUID: {2}\nReference size: {3} cm\nDetected size: {4} cm", trackedImage.referenceImage.name, trackedImage.trackingState, trackedImage.referenceImage.guid, trackedImage.referenceImage.size * 100f, trackedImage.size * 100f); var planeParentGo = trackedImage.transform.GetChild(0).gameObject; var planeGo = planeParentGo.transform.GetChild(0).gameObject; // Disable the visual plane if it is not being tracked if (trackedImage.trackingState != TrackingState.None) { planeGo.SetActive(true); // The image extents is only valid when the image is being tracked trackedImage.transform.localScale = new Vector3(trackedImage.size.x, 1f, trackedImage.size.y); // Set the texture var material = planeGo.GetComponentInChildren().material; material.mainTexture = (trackedImage.referenceImage.texture == null) ? defaultTexture : trackedImage.referenceImage.texture; } else { planeGo.SetActive(false); } } void OnTrackedImagesChanged(ARTrackedImagesChangedEventArgs eventArgs) { foreach (var trackedImage in eventArgs.added) { // Give the initial image a reasonable default scale trackedImage.transform.localScale = new Vector3(0.01f, 1f, 0.01f); UpdateInfo(trackedImage); } foreach (var trackedImage in eventArgs.updated) UpdateInfo(trackedImage); } }