Search Unity

Resolved Object placement in AR using raycast with intersecting planes

Discussion in 'AR' started by Deleted User, Aug 7, 2022.

  1. Deleted User

    Deleted User

    Guest

    Hi,

    I was following the Placing and Manipulating Objects in AR tutorial on Unity Learn here:
    https://learn.unity.com/tutorial/placing-and-manipulating-objects-in-ar#605103a5edbc2a6c32bf565e

    I think I have copied the SpawnableManager code accurately, and pasted it below for reference.

    If I allow the phone to "see" only the horizontal plane for the seat of a couch then the object will be placed directly on the seat where the raycast intersects the horizontal plane.

    If I move the phone backwards and allow the vertical plane on the front of the couch to be acquired, the next attempt to place an object on the seat will result in it floating in mid-air where it appears the raycast intersects with an extension of the vertical plane from the front of the couch.

    The visible AR default planes that are automatically placed appear to be the same size as the real-world dimensions, however, the raycast behaves as if those planes are infinite.

    It seems like I need to modify the raycast code to only detect the visible planes that were placed, but I haven't had luck searching for what needs to change.

    Code (CSharp):
    1. using System;
    2. using System.Collections;
    3. using System.Collections.Generic;
    4. using UnityEngine;
    5. using UnityEngine.XR.ARFoundation;
    6.  
    7. public class SpawnableManager : MonoBehaviour
    8. {
    9.     [SerializeField]
    10.     ARRaycastManager m_RaycastManager;
    11.     List<ARRaycastHit> m_Hits = new List<ARRaycastHit>();
    12.     [SerializeField]
    13.     GameObject spawnablePrefab;
    14.  
    15.     Camera arCam;
    16.     GameObject spawnedObject;
    17.  
    18.     // Start is called before the first frame update
    19.     void Start()
    20.     {
    21.         spawnedObject = null;
    22.         arCam = GameObject.Find("AR Camera").GetComponent<Camera>();
    23.     }
    24.  
    25.     // Update is called once per frame
    26.     void Update()
    27.     {
    28.         if (Input.touchCount == 0)
    29.         {
    30.             return;
    31.         }
    32.  
    33.         RaycastHit hit;
    34.         Ray ray = arCam.ScreenPointToRay(Input.GetTouch(0).position);
    35.  
    36.         if (m_RaycastManager.Raycast(Input.GetTouch(0).position, m_Hits))
    37.         {
    38.             if (Input.GetTouch(0).phase == TouchPhase.Began && spawnedObject == null)
    39.             {
    40.                 if (Physics.Raycast(ray, out hit))
    41.                 {
    42.                     if (hit.collider.gameObject.tag == "Spawnable")
    43.                     {
    44.                         spawnedObject = hit.collider.gameObject;
    45.                     }
    46.                     else
    47.                     {
    48.                         SpawnPrefab(m_Hits[0].pose.position);
    49.                     }
    50.                 }
    51.             }
    52.             else if (Input.GetTouch(0).phase == TouchPhase.Moved && spawnedObject != null)
    53.             {
    54.                 spawnedObject.transform.position = m_Hits[0].pose.position;
    55.             }
    56.  
    57.             if (Input.GetTouch(0).phase == TouchPhase.Ended)
    58.             {
    59.                 spawnedObject = null;
    60.             }
    61.         }
    62.     }
    63.  
    64.     private void SpawnPrefab(Vector3 spawnPosition)
    65.     {
    66.         spawnedObject = Instantiate(spawnablePrefab, spawnPosition, Quaternion.identity);
    67.     }
    68. }
     
  2. mikeyrafier98

    mikeyrafier98

    Joined:
    May 19, 2022
    Posts:
    37
    As far as I understand, raycast hit will not only estimate plane, pre-estimated point in 3D, and post-estimated as well.
    For the problem that you said "infinite plane", I think it's because the raycast hit one of these estimated point in 3D.
    I don't know so well, so might be try to debug that which the raycast hit.

    In AR foundation example, it can place an object only for plane:
    https://github.com/Unity-Technologies/arfoundation-samples/blob/main/Assets/Scripts/PlaceOnPlane.cs

    I think this is the one you were looking for?
     
    Deleted User likes this.
  3. KyryloKuzyk

    KyryloKuzyk

    Joined:
    Nov 4, 2013
    Posts:
    1,144
    You should add the TrackableType.PlaneWithinPolygon parameter to raycast against the visible planes.
     
  4. Deleted User

    Deleted User

    Guest

  5. tomicz

    tomicz

    Joined:
    Mar 16, 2015
    Posts:
    152