How to map/localize Unity world coordinate to the tracked object coordinate

Hello all,

Instead of using QR, we are planning to use 1 object to localize our XR app in iPhone. Since now I found this script and were trying to implement it but couldn’t succeed. PS. I am using ARKit and Unity 6.

Would be greatfull if you have any suggestions for resolve this : )

Thanks for your time.

using UnityEngine;
using UnityEngine.XR.ARFoundation;
using UnityEngine.XR.ARSubsystems;
using System.Collections.Generic;

public class ARWorldAlignmentHandler : MonoBehaviour
{
    [SerializeField]
    private ARTrackedObjectManager trackedObjectManager;

    [SerializeField]
    private GameObject xrOrigin; // Reference to XR Origin (AR Session Origin or XR Origin)

    [SerializeField]
    private Material trackedObjectMaterial; // Material to apply to tracked objects

    private Dictionary<TrackableId, GameObject> trackedObjectInstances = new Dictionary<TrackableId, GameObject>();
    private Dictionary<TrackableId, Pose> lastKnownTransforms = new Dictionary<TrackableId, Pose>();

    private bool isWorldAligned = false;

    void OnEnable()
    {
        if (trackedObjectManager != null)
        {
            trackedObjectManager.trackedObjectsChanged += OnTrackedObjectsChanged;
        }
    }

    void OnDisable()
    {
        if (trackedObjectManager != null)
        {
            trackedObjectManager.trackedObjectsChanged -= OnTrackedObjectsChanged;
        }
    }

    private void OnTrackedObjectsChanged(ARTrackedObjectsChangedEventArgs args)
    {
        // Handle added tracked objects
        foreach (var trackedObject in args.added)
        {
            CreateOrUpdateTrackedObject(trackedObject);
            AlignARWorldToTrackedObject(trackedObject);
        }

        // Handle updated tracked objects
        foreach (var trackedObject in args.updated)
        {
            CreateOrUpdateTrackedObject(trackedObject);
            // Uncomment the next line if you want continuous alignment when the tracked object updates
            // AlignARWorldToTrackedObject(trackedObject);
        }

        // Handle removed tracked objects
        foreach (var trackedObject in args.removed)
        {
            if (trackedObjectInstances.TryGetValue(trackedObject.trackableId, out GameObject instance))
            {
                lastKnownTransforms[trackedObject.trackableId] = new Pose(instance.transform.position, instance.transform.rotation);
                Destroy(instance);
                trackedObjectInstances.Remove(trackedObject.trackableId);
            }
        }
    }

    private void CreateOrUpdateTrackedObject(ARTrackedObject trackedObject)
    {
        if (trackedObjectInstances.TryGetValue(trackedObject.trackableId, out GameObject instance))
        {
            // Update existing tracked object instance position and rotation
            instance.transform.position = trackedObject.transform.position;
            instance.transform.rotation = trackedObject.transform.rotation;
            lastKnownTransforms[trackedObject.trackableId] = new Pose(trackedObject.transform.position, trackedObject.transform.rotation);
        }
        else
        {
            // Create a new GameObject representing the tracked object
            GameObject newObject = GameObject.CreatePrimitive(PrimitiveType.Cube);
            newObject.transform.position = trackedObject.transform.position;
            newObject.transform.rotation = trackedObject.transform.rotation;

            // Assign the custom material to the new object if available
            if (trackedObjectMaterial != null)
            {
                newObject.GetComponent<Renderer>().material = trackedObjectMaterial;
            }

            trackedObjectInstances[trackedObject.trackableId] = newObject;
            lastKnownTransforms[trackedObject.trackableId] = new Pose(newObject.transform.position, newObject.transform.rotation);
        }
    }

    private void AlignARWorldToTrackedObject(ARTrackedObject trackedObject)
    {
        if (!isWorldAligned)
        {
            // Desired position and rotation in Unity space (typically zero)
            Vector3 desiredPosition = Vector3.zero;
            Quaternion desiredRotation = Quaternion.identity;

            // Calculate positional offset
            Vector3 positionOffset = desiredPosition - trackedObject.transform.position;

            // Calculate rotational offset
            Quaternion rotationOffset = desiredRotation * Quaternion.Inverse(trackedObject.transform.rotation);

            // Adjust xrOrigin's position and rotation
            xrOrigin.transform.position += positionOffset;
            xrOrigin.transform.rotation = rotationOffset * xrOrigin.transform.rotation;

            isWorldAligned = true;

            Debug.Log($"AR World aligned with tracked object. XR Origin position: {xrOrigin.transform.position}, rotation: {xrOrigin.transform.rotation}");
        }
    }
}