Hi everyone,
something weird is happening with my script, and it has to do with how the ARTrackedImageManager works.
Let me share a simplified version of my script:
using UnityEngine;
using UnityEngine.UI;
using UnityEngine.XR.ARFoundation;
using UnityEngine.XR.ARSubsystems;
public class TrackedImageInfoRuntimeManager : MonoBehaviour
{
[SerializeField]
private Text debugLog;
[SerializeField]
private Text currentImageText;
[SerializeField]
private GameObject prefabOnTrack;
[SerializeField]
XRReferenceImageLibrary xrReferenceImageLibrary;
private ARTrackedImageManager trackImageManager;
private GameObject arObjectToPlace;
void Awake()
{
arObjectToPlace = Instantiate(prefabOnTrack, Vector3.zero, Quaternion.identity);
arObjectToPlace.SetActive(false);
}
void Start()
{
Application.targetFrameRate = 60;
debugLog.text += "Creating Runtime Mutable Image Library\n";
trackImageManager = gameObject.AddComponent<ARTrackedImageManager>();
trackImageManager.referenceLibrary = trackImageManager.CreateRuntimeLibrary(xrReferenceImageLibrary);
trackImageManager.requestedMaxNumberOfMovingImages = 1;
// trackImageManager.trackedImagePrefab = prefabOnTrack;
trackImageManager.enabled = true;
trackImageManager.trackedImagesChanged += OnTrackedImagesChanged;
ShowTrackerInfo();
}
public void ShowTrackerInfo()
{
var runtimeReferenceImageLibrary = trackImageManager.referenceLibrary as MutableRuntimeReferenceImageLibrary;
debugLog.text += $"TextureFormat.RGBA32 supported: {runtimeReferenceImageLibrary.IsTextureFormatSupported(TextureFormat.RGBA32)}\n";
debugLog.text += $"Supported Texture Count ({runtimeReferenceImageLibrary.supportedTextureFormatCount})\n";
debugLog.text += $"trackImageManager.trackables.count ({trackImageManager.trackables.count})\n";
debugLog.text += $"trackImageManager.trackedImagePrefab.name ({trackImageManager.trackedImagePrefab.name})\n";
debugLog.text += $"trackImageManager.maxNumberOfMovingImages ({trackImageManager.requestedMaxNumberOfMovingImages})\n";
}
void OnDisable()
{
trackImageManager.trackedImagesChanged -= OnTrackedImagesChanged;
}
void OnTrackedImagesChanged(ARTrackedImagesChangedEventArgs eventArgs)
{
foreach (ARTrackedImage trackedImage in eventArgs.added)
{
UpdateARImage(trackedImage);
}
foreach (ARTrackedImage trackedImage in eventArgs.updated)
{
UpdateARImage(trackedImage);
}
}
public void EnableAR()
{
trackImageManager.enabled = true;
debugLog.text = $"Status of AR is: {trackImageManager.enabled}\n";
}
public void DisableAR()
{
trackImageManager.enabled = false;
debugLog.text = $"Status of AR is: {trackImageManager.enabled}\n";
}
private void UpdateARImage(ARTrackedImage trackedImage)
{
// Display the name of the tracked image in the canvas
currentImageText.text = trackedImage.referenceImage.name;
arObjectToPlace.SetActive(true);
// Assign and Place Game Object
arObjectToPlace.transform.parent = trackedImage.transform;
arObjectToPlace.transform.localPosition = Vector3.zero;
arObjectToPlace.transform.localScale = new Vector3(-trackedImage.referenceImage.size.x, 0.005f, -trackedImage.referenceImage.size.y);
// AssignGameObject(trackedImage.referenceImage, trackedImage.transform.position);
debugLog.text = $"trackedImage.position: {trackedImage.transform.position}\n prefab.position: {arObjectToPlace.transform.position}";
}
}
The logic is simple: I instantiate an XRReferenceImageLibrary at runtime and set it to enabled = true. Then, if the camera detects one of the images included there, I instantiate an object on top of the detected image (a video player in this case) and print the name of the detected image on the screen.
I also added some buttons to the canvas that enable/disable the ARTrackedImageManager. Here’s what causes the weird thing:
- I open the app
- I disable the ARTrackedImageManager and, indeed, when I frame the target image included in the XRReferenceImageLibrary no object gets instantiated.
- I then move the camera to a different area of the world where no target image is present and enable the ARTrackedImageManager again. My expectation was that I would not see anything until I focused again on the target image. Yet, it seems that as soon as I re-enable the ARTrackedImageManager, it knows that I previously framed the target image and instantly instantiate the object at the right place (and prints out the target image name), which basically means it runs the UpdateARImage method even if I’m not pointing the camera to the target image.
Can you explain such behaviour?
Is the ARTrackedImageManager always working on the background even when I set it to enabled = false? If it is disabled, how can it knows that I previously pointed the camera at the target image and why does it run the UpdateARImage?
I’d love to learn more because I would like to optimize an app that relies heavily on such AR manager (here’s my other thread if you want to chime in).