Unity-Technologies / arfoundation-samples

Example content for Unity projects based on AR Foundation
Other
3.07k stars 1.15k forks source link

[Bug] ARRaycastManager.Raycast doesn't seem to work when passed a ray as an argument #729

Closed Dyonisian closed 3 years ago

Dyonisian commented 3 years ago

Describe the bug

I'm trying to use ARRaycastManager to move an object to the edge of the detected plane.

I'm using it something like this - Ray ray = new Ray(arRightAnchor.transform.position, Vector3.down);

if(arRaycastManager.Raycast(ray, hits, UnityEngine.XR.ARSubsystems.TrackableType.PlaneWithinPolygon)) { //Object is still within bounds of the plane, move it }

This is inside a loop in a coroutine so I can move it incrementally and re-check every time I move the object.

If I replace the arRaycastManager raycast with a physics raycast and test it in-editor with a normal plane, the code works as expected. This suggests to me that the code is fine but either the arRaycastManager raycast function isn't working as I expect, or for whatever reason it's not detecting the ar plane that is right below the object. I don't know if there's a distance limit to the raycast hard coded maybe?

I can't use a physics raycast instead as the detected AR planes apparently don't work with physics raycasts, even if I try to add a plane mesh to the mesh filter and mesh collider of the AR Plane Visualizer.

Also, just before this code, I use arRaycastManager.raycast with a touch position input to detect screen touches to decide where to place the object on the ar plane. That works, which again suggests that the ar plane is there and the later code in which a ray is passed should work too.

Also, I'm using an older version of ARFoundation 4.0.8 due to Unity Cloud Build not being compatible with newer versions of AR Foundation. In case this might be the issue please let me know.

To Reproduce Use ARRaycastManger.Raycast with a ray passed to it to try to detect ar planes.

Expected behavior Should return true when the object is right above an ar plane.

Actual behavior Never returns true.

Smartphone (please complete the following information):

tdmowrer commented 3 years ago

I tried this on an iPhone 11 and both the screen and ray-based raycasts work as expected:

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

[RequireComponent(typeof(ARPlaneManager))]
[RequireComponent(typeof(ARRaycastManager))]
public class RaycastUsingRay : MonoBehaviour
{
    public Transform rayContent;

    public Transform screenContent;

    List<ARRaycastHit> m_RaycastHits = new List<ARRaycastHit>();

    void Update()
    {
        if (Input.touchCount == 0)
            return;

        var touch = Input.GetTouch(0);
        var screenPosition = touch.position;
        var camera = GetComponent<ARSessionOrigin>().camera;
        var ray = camera.ScreenPointToRay(screenPosition);

        var manager = GetComponent<ARRaycastManager>();

        if (manager.Raycast(ray, m_RaycastHits, TrackableType.PlaneWithinPolygon))
        {
            var pose = m_RaycastHits[0].pose;
            rayContent.transform.SetPositionAndRotation(pose.position, pose.rotation);
        }

        if (manager.Raycast(screenPosition, m_RaycastHits, TrackableType.PlaneWithinPolygon))
        {
            var pose = m_RaycastHits[0].pose;
            screenContent.transform.SetPositionAndRotation(pose.position, pose.rotation);
        }
    }
}

I don't know if there's a distance limit to the raycast hard coded maybe?

There is no distance limit with AR raycasts.

I can't use a physics raycast instead as the detected AR planes apparently don't work with physics raycasts, even if I try to add a plane mesh to the mesh filter and mesh collider of the AR Plane Visualizer.

There is nothing special about an ARPlane; it's just a component on a GameObject, and physics meshes work the same way as they do on any other GameObject. The fact that the physics raycast also fails suggests something else is going on. I suggest you draw the raycast (e.g., using a line renderer) or debug log the ray and plane's position to make sure they seem reasonable.

Dyonisian commented 3 years ago

Hi, thanks for checking it out. 2 quick thoughts on that -

  1. About the physics raycast working - If I add a plane mesh to the ArPlaneVisualizer, does the mesh grow to match the size of the plane that I see? As I move my phone and detect more planes, I think the line renderer adapts to cover that area - will this be reflected in the plane mesh?

  2. In your example code, you're still using a camera ray. The way I'm using it is with a ray from an object in the world going downwards towards the detected planes (hopefully). Is the function not meant to be used this way?

Thanks for your help and I will also try out what you suggested and confirm what the issue is.

tdmowrer commented 3 years ago
  1. If I add a plane mesh to the ArPlaneVisualizer, does the mesh grow to match the size of the plane that I see?

Yes, it does.

  1. In your example code, you're still using a camera ray. The way I'm using it is with a ray from an object in the world going downwards towards the detected planes (hopefully). Is the function not meant to be used this way?

There are two raycast APIs: one that uses a screen-space point and one that uses a world-space ray. The fact that the ray is derived from the camera position does not matter.

stale[bot] commented 3 years ago

This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.