Search code examples
unity-game-engineaugmented-realityarkitarcore

How to show a tracking line from where the model is placed in Augmented Reality?


I am looking to show a line in my app from where the model is placed so that the user knows position where the model is kept in real world. When user changes device camera away from model the line gets turned on to show where the model is. Similarly it turns off when model is detected. I have attached images to show from a similar app white dotted lines show the path. Notice how the lines disappear when the model is detected.

 LineRenderer lins;
 public GameObject Lineprefab;
 private GameObject newline;
 public Transform startpoint;

 public Renderer m_rend1;

       bool HitTestWithResultType (ARPoint point, ARHitTestResultType resultTypes) 
       {

          List<ARHitTestResult> hitResults = UnityARSessionNativeInterface.GetARSessionNativeInterface ().HitTest (point, resultTypes);

           if (hitResults.Count > 0 && check==true) 
             {

              foreach (var hitResult in hitResults)

                {


            Debug.Log ("Got hit!");
            //obj.Hideplane();
            Genplanes.SetActive(false);

            if (Select == 0) {
                Debug.Log("hit-zero!");
                Instantiate(Instaobj[0], ForSelect);
                check = false;
            }

            if (Select == 1) {
                Debug.Log("hit-one!");
                Instantiate(Instaobj[1], ForSelect);
                check = false;
            }

            if (Select == 2) {
                Debug.Log("hit-two!");
                Instantiate(Instaobj[2], ForSelect);
                check = false;
            }

                m_HitTransform.position = UnityARMatrixOps.GetPosition (hitResult.worldTransform);
                m_HitTransform.rotation = UnityARMatrixOps.GetRotation (hitResult.worldTransform);
                Debug.Log (string.Format ("x:{0:0.######} y:{1:0.######} z:{2:0.######}", m_HitTransform.position.x, m_HitTransform.position.y, m_HitTransform.position.z));

                obj.StopPlaneTracking();


                    }


              }
    return false;
        }


       private void Start()
    {

       spawngenerator();
        newline.SetActive(false);
        m_rend1 = GetComponent<MeshRenderer>();


    }







        void spawngenerator()

          {

           GameObject newline = Instantiate(Lineprefab);
           lins = newline.GetComponent<LineRenderer>();


          }


    private void LateUpdate()
        {
        lins.SetPosition(0, startpoint.position);
        lins.SetPosition(1, m_HitTransform.position);

        if( m_rend1.isVisible==true)
        {
            Debug.Log("Render is Visible");
            newline.SetActive(false);   

        }
        else if( m_rend1.isVisible==false)
        {

                newline.SetActive(true);
                Debug.Log("It is InVisible");

            Debug.Log("Render is InVisible");

        }

        }



void Update () {

#if UNITY_EDITOR   //we will only use this script on the editor side, though there is nothing that would prevent it from working on device
        if (Input.GetMouseButtonDown (0)) {
            Ray ray = Camera.main.ScreenPointToRay (Input.mousePosition);
            RaycastHit hit;

            //we'll try to hit one of the plane collider gameobjects that were generated by the plugin
            //effectively similar to calling HitTest with ARHitTestResultType.ARHitTestResultTypeExistingPlaneUsingExtent
            if (Physics.Raycast (ray, out hit, maxRayDistance, collisionLayer)) {
                //we're going to get the position from the contact point
                m_HitTransform.position = hit.point;
                Debug.Log (string.Format ("x:{0:0.######} y:{1:0.######} z:{2:0.######}", m_HitTransform.position.x, m_HitTransform.position.y, m_HitTransform.position.z));

                //and the rotation from the transform of the plane collider
                m_HitTransform.rotation = hit.transform.rotation;
            }
        }
        #else
        if (Input.touchCount > 0 && m_HitTransform != null )
        {
            var touch = Input.GetTouch(0);
            if ((touch.phase == TouchPhase.Began || touch.phase == TouchPhase.Moved) &&  !EventSystem.current.IsPointerOverGameObject(touch.fingerId))
            {
                var screenPosition = Camera.main.ScreenToViewportPoint(touch.position);
                ARPoint point = new ARPoint {
                    x = screenPosition.x,
                    y = screenPosition.y
                };

                // prioritize reults types
                ARHitTestResultType[] resultTypes = {
                    //ARHitTestResultType.ARHitTestResultTypeExistingPlaneUsingGeometry,
                    ARHitTestResultType.ARHitTestResultTypeExistingPlaneUsingExtent, 
                    // if you want to use infinite planes use this:
                    //ARHitTestResultType.ARHitTestResultTypeExistingPlane,
                    //ARHitTestResultType.ARHitTestResultTypeEstimatedHorizontalPlane, 
                    //ARHitTestResultType.ARHitTestResultTypeEstimatedVerticalPlane, 
                    //ARHitTestResultType.ARHitTestResultTypeFeaturePoint
                }; 

                foreach (ARHitTestResultType resultType in resultTypes)
                {
                    if (HitTestWithResultType (point, resultType))
                    {
                        return;
                    }
                }
            }
        }
        #endif


    }

enter image description here.

White dotted lines showin where the model is


Solution

  • First, I 'd start with checking if the model is within the bounding box of the camera https://docs.unity3d.com/ScriptReference/Renderer-isVisible.html

    if the object is not visible (isVisible == false), create a line renderer from object position to wherever it should end.

    The end point could be a camera child place just in front of it, so it looks like it starts from the user to the object.