Search Unity

Question Large / detailed objects "follow" the camera.

Discussion in 'AR' started by beeri2001, Feb 26, 2021.

  1. beeri2001

    beeri2001

    Joined:
    Nov 27, 2018
    Posts:
    1
    Hello,

    I am currently working on an AR project where I want to Instantiate a pretty large object (A kindof level / world) so the user is able to walk around asif he/she were actually inside of that world, but I am having trouble getting it to work.

    I have an ARPointCloudManager, ARAnchorManager, ARPlaneManager and an ARTrackedImageManager.
    On startup of the AR scene, all of these are active.
    When the TrackedImageManager finds it's reference image it instantiates an object (using it's prefab slot in the inspector) that in turn, when it has successfully tracked it's position, instantiates the actual level.
    When the Image is detected, the TrackedImageManager is disabled, and when the Level has been created it is given an ArAnchor.

    When the PlaneManager finds a plane, it attaches an ArAnchor to it.

    I have tried instantiating the level with the ARSessionOrigin as it's parent and without, but didn't notice any difference.
    I have also tried instantiating the level with the PointCloud (prefab object that the Manager creates) as it's parent, this didn't solve it either.
    I also tried using the closest ArAnchor as a parent and unfortunatly, this did not result in a difference either.

    The pivot if the level is set to the bottom of the Ground, where I would want it to be on the IRL floor.
    (The embedded image link doesn't seem to work with a google drive link)
    https://drive.google.com/file/d/1yZLsm_zSbR9qxBEr1FM_RNIiCdLV2yWl/view?usp=sharing

    I also have a video showcasing the problem:
    https://drive.google.com/file/d/14GuVYKXlUNAriZHyJ3vyqakiqZHc4_Y_/view?usp=sharing

    This same problem occurs when, instead of the entire level, I try to instantiate just a single one of the ships in the level, or a number of the corals used in the level, the larger / more detailed the object(s), the more it moves with the camera.

    My phone: Samsung Galaxy A40.
    Unity version: 2019.4.19f1 LTS.
    ARFoundation: 4.1.3.
    ARCore XR Plugin: 4.1.3.

    This ArManager script has a function "DetectedTrackedImage" which is called when the TrackedImageManager's prefab is created & tracked, it then instantiates the level.

    Code (CSharp):
    1. public static ArManager Instance;
    2.  
    3.     [Header("References")]
    4.     [SerializeField] private ARTrackedImageManager m_trackedImageManager;
    5.     [SerializeField] private ARRaycastManager m_raycastManager;
    6.     [SerializeField] private ARSessionOrigin m_sessionOrigin;
    7.     [SerializeField] private ARAnchorManager m_anchorManager;
    8.     [SerializeField] private ARPlaneManager m_planeManager;
    9.  
    10.     [Header("Settings")]
    11.     [SerializeField] private GameObject m_prefabToSpawn;
    12.  
    13.     private List<ARAnchor> m_anchors = new List<ARAnchor>();
    14.  
    15.     private void Awake()
    16.     {
    17.         if (Instance == null)
    18.         {
    19.             Instance = this;
    20.             m_planeManager.planesChanged += OnPlanesChanged;
    21.         }
    22.     }
    23.     public void OnPlanesChanged(ARPlanesChangedEventArgs args)
    24.     {
    25.         if(args.added.Count > 0)
    26.         {
    27.             foreach (ARPlane plane in args.added)
    28.             {
    29.                 m_anchors.Add(m_anchorManager.AttachAnchor(plane, new Pose(plane.transform.position, plane.transform.rotation)));
    30.             }
    31.         }
    32.     }
    33.  
    34.     public void DetectedTrackedImage(Pose trackedImagePose)
    35.     {
    36.         m_trackedImageManager.enabled = false;
    37.         m_planeManager.enabled = false;
    38.  
    39.         ArInstantiate(m_prefabToSpawn, trackedImagePose.position, trackedImagePose.rotation);
    40.     }
    41.  
    42.     private Transform FindClosestAnchor(Vector3 objectPos)
    43.     {
    44.         if(m_anchors.Count <= 0) { return null; }
    45.  
    46.         float closestDistance = float.MaxValue;
    47.         ARAnchor closestAnchor = null;
    48.  
    49.         foreach (ARAnchor anchor in m_anchors)
    50.         {
    51.             float dis = Vector3.Distance(anchor.transform.position, objectPos);
    52.             if (dis < closestDistance)
    53.             {
    54.                 closestAnchor = anchor;
    55.                 closestDistance = dis;
    56.             }
    57.         }
    58.  
    59.         return closestAnchor.transform;
    60.     }
    61.  
    62.     public GameObject ArInstantiate(GameObject objectToCreate, Vector3 pos, Quaternion rot)
    63.     {
    64.         GameObject obj = Instantiate(objectToCreate, pos, rot, m_sessionOrigin.transform); // , FindClosestAnchor(trackedImagePose.position)
    65.  
    66.         if (obj.GetComponent<ARAnchor>() == null)
    67.         {
    68.             obj.AddComponent<ARAnchor>();
    69.         }
    70.  
    71.         return obj;
    72.     }
    73.  
    74.     public ARRaycastManager GetRaycastManager()
    75.     {
    76.         return m_raycastManager;
    77.     }
    And this script is attached to that TrackedImageManager's prefab to call the ArManager's "DetectedTrackedImage" when it has been tracked successfully (It seems the trackedImage isn't instantiated in the correct position, it takes a couple of frames for it to move to the correct position).

    Code (CSharp):
    1. private ApplicationState m_state = ApplicationState.Scanning;
    2.  
    3.     private void Awake()
    4.     {
    5.         FindObjectOfType<ARTrackedImageManager>().trackedImagesChanged += OnTrackedImagesUpdated;
    6.     }
    7.  
    8.     public void OnTrackedImagesUpdated(ARTrackedImagesChangedEventArgs args)
    9.     {
    10.         if (m_state == ApplicationState.Scanning)
    11.         {
    12.             m_state = ApplicationState.ProcessingDetectedImage;
    13.  
    14.             transform.rotation = Quaternion.Euler(0, transform.eulerAngles.y, 0);
    15.  
    16.             StartCoroutine(WaitForTrackedComplete(SetWorldAnchor));
    17.         }
    18.     }
    19.  
    20.     private IEnumerator WaitForTrackedComplete(Action<Pose> callback)
    21.     {
    22.         yield return new WaitUntil(() => { Debug.LogError("checking tracked state"); return transform.position != Vector3.zero; });
    23.  
    24.         callback(new Pose(transform.position, transform.rotation));
    25.     }
    26.  
    27.     public void SetWorldAnchor(Pose pose)
    28.     {
    29.         List<ARRaycastHit> hits = new List<ARRaycastHit>();
    30.         ArManager.Instance.GetRaycastManager().Raycast(new Vector2(Screen.width / 2, Screen.height / 2), hits, UnityEngine.XR.ARSubsystems.TrackableType.PlaneWithinPolygon);
    31.  
    32.         if(hits.Count > 0)
    33.         {
    34.             Debug.Log("Created");
    35.             transform.position = new Vector3(pose.position.x, hits[0].pose.position.y, pose.position.z);
    36.             ArManager.Instance.DetectedTrackedImage(new Pose(transform.position, transform.rotation));
    37.             m_state = ApplicationState.Running;
    38.             FindObjectOfType<ARTrackedImageManager>().trackedImagesChanged -= OnTrackedImagesUpdated;
    39.         }
    40.         else
    41.         {
    42.             Debug.LogError("state set to \"Scanning\"");
    43.             m_state = ApplicationState.Scanning;
    44.         }
    45.     }
    46.  
    47.     public enum ApplicationState
    48.     {
    49.         Scanning,
    50.         ProcessingDetectedImage,
    51.         Running
    52.     }
    Any help or advice would be greatly appreciated, thank you in advance.
     
    Last edited: Mar 1, 2021
  2. cdra0624

    cdra0624

    Joined:
    Aug 4, 2015
    Posts:
    1
    I have the same problem, could you solve it?
    Is it okay to share it in here?
     
    YangHyunSuk1 likes this.