Closed Schaggo closed 3 years ago
There is a new component called ARRaycastManager. You should add it to the same GameObject as ARSessionOrigin component in the tutorial and than you can perform Raycast methods using that ARRaycastManager. π
Thanks! I managed to find the migration docs (duh!) but still struggle to instantiate the placement indicator. Xcode spits out a NullReference within UpdatePlacementPose().
I had the same problem, try changing Camera.current to Camera.main
Thanks, man! I tried with a public camera reference to the arcam, but that didn't work. Saved me a headache!
I have found migration docs, followed all...but still have not figured out how it really works...
here have my script:
using System.Collections; using System.Collections.Generic; using UnityEngine; using UnityEngine.XR.ARFoundation; using UnityEngine.XR; using UnityEngine.XR.ARSubsystems; using System;
public class ArTabToPlaceObject : MonoBehaviour { public GameObject objectToPlace; public GameObject placementIndicator; private Camera myCamera; private ARSessionOrigin arOrigin; private ARRaycastManager raycastManager; private Pose placementPose; private bool placementPoseIsValid = false;
void Start()
{
arOrigin = FindObjectOfType<ARSessionOrigin>();
raycastManager = FindObjectOfType<ARRaycastManager>();
}
void Update()
{
UpdatePlacementPose();
UpdatePlacementIndicator();
if (placementPoseIsValid && Input.touchCount > 0 && Input.GetTouch(0).phase == TouchPhase.Began)
{
PlaceObject();
}
}
private void PlaceObject()
{
Instantiate(objectToPlace, placementPose.position, placementPose.rotation);
}
private void UpdatePlacementIndicator()
{
if (placementPoseIsValid)
{
placementIndicator.SetActive(true);
placementIndicator.transform.SetPositionAndRotation(placementPose.position, placementPose.rotation);
}
else
{
placementIndicator.SetActive(false);
}
}
private void UpdatePlacementPose()
{
var screenCenter = Camera.main.ViewportToScreenPoint(new Vector3(0.5f, 0.5f));
var hits = new List<ARRaycastHit>();
raycastManager.Raycast(screenCenter, hits, TrackableType.Planes);
placementPoseIsValid = hits.Count > 0;
if (placementPoseIsValid)
{
placementPose = hits[0].pose;
var cameraForward = Camera.current.transform.forward;
var cameraBearing = new Vector3(cameraForward.x, 0, cameraForward.z).normalized;
placementPose.rotation = Quaternion.LookRotation(cameraBearing);
}
}
}
here have my script:
using System.Collections; using System.Collections.Generic; using UnityEngine; using UnityEngine.XR.ARFoundation; using UnityEngine.XR; using UnityEngine.XR.ARSubsystems; using System;
public class ArTabToPlaceObject : MonoBehaviour { public GameObject objectToPlace; public GameObject placementIndicator; private Camera myCamera; private ARSessionOrigin arOrigin; private ARRaycastManager raycastManager; private Pose placementPose; private bool placementPoseIsValid = false;
void Start() { arOrigin = FindObjectOfType<ARSessionOrigin>(); raycastManager = FindObjectOfType<ARRaycastManager>(); } void Update() { UpdatePlacementPose(); UpdatePlacementIndicator(); if (placementPoseIsValid && Input.touchCount > 0 && Input.GetTouch(0).phase == TouchPhase.Began) { PlaceObject(); } } private void PlaceObject() { Instantiate(objectToPlace, placementPose.position, placementPose.rotation); } private void UpdatePlacementIndicator() { if (placementPoseIsValid) { placementIndicator.SetActive(true); placementIndicator.transform.SetPositionAndRotation(placementPose.position, placementPose.rotation); } else { placementIndicator.SetActive(false); } } private void UpdatePlacementPose() { var screenCenter = Camera.main.ViewportToScreenPoint(new Vector3(0.5f, 0.5f)); var hits = new List<ARRaycastHit>(); raycastManager.Raycast(screenCenter, hits, TrackableType.Planes); placementPoseIsValid = hits.Count > 0; if (placementPoseIsValid) { placementPose = hits[0].pose; var cameraForward = Camera.current.transform.forward; var cameraBearing = new Vector3(cameraForward.x, 0, cameraForward.z).normalized; placementPose.rotation = Quaternion.LookRotation(cameraBearing); } }
}
That was quick! I will try it! Thanks a loooot!
i also had the problem, that I tried to use the placement indicator as a prefab. nope - you have to actually have it in the scene
i also had the problem, that I tried to use the placement indicator as a prefab. nope - you have to actually have it in the scene
Didn't managed it to work... Can I look in your source project?
I just used the git and changed the script.
What isn't working?
What isn't working?
raycastManager.Raycast(screenCenter, hits, **TrackableType.Planes**);
TrackableType throws me error...
using UnityEngine.XR.ARSubsystems;
There is a new component called ARRaycastManager. You should add it to the same GameObject as ARSessionOrigin component in the tutorial and than you can perform Raycast methods using that ARRaycastManager. π
How is this done exactly? Right now my indicator is hanging in mid air. Most likely because the raycastManager isn't found upon start? Do I have to add a new GameObject and attach something containing the ARRaycastManager?
using UnityEngine.XR.ARSubsystems;
I'm using the XR.ARSubsystem and I get the same results no matter if the var screenCenter is Camera.current or Camera.main. I have also read the documentation for the two Raycast methods on unitys homepage. Unfortunately I don't understand this stuff good enough π
I think I had a similar issue where the indicator wasn't flat to the surface, because I forgot to put the quad in an empty game object. Another thing is to reference the indicator that is actually in the scene not a prefab.
Wow, thank you for the amazingly quick answer. It isn't that it doesn't lay flat. The position of the indicator is that of the the phone when the app starts. It's worth to mention that I'm using ARFoundation in combination with ARCore on an Android phone.
I have an interaction object which has the ARTapToPlaceObject script as well as a reference to the placement indicator. I'm not sure if I placed the quad in an empty game object. How do I check that? The quad is visible and a child to the placement indicator.
I've also chosen to use another .png for the indicator but that can't matter one bit.
Also I'm using Unity 2018.4.0f1
Ah that might be the Problem. This threat is referring to 2019.2 and arfoundation 2.02.
I think if you just download the git and run it, you should be good to go. Although I havenβt tested on android.
I got it to work via a course I'm taking and by talking with some friends that know more about Unity. The course is: Handheld AR App Development with Unity and you can audit the course for free. Thanks for the help Schaggo!
Its not working for me. I couldn't view the placement indicator at all first even though i have added that gameobject
@anesask try with importing also arsubstystem: using UnityEngine.XR.ARSubsystems;
I got it to work via a course I'm taking and by talking with some friends that know more about Unity. The course is: Handheld AR App Development with Unity and you can audit the course for free. Thanks for the help Schaggo!
do you mind telling me exactly how you got the indicator to be placed on surfaces instead of it appearing wherever the camera starts? I'm having the same problem right now π
Do you only need to add ARRaycastManager
in the script, or do you also need to add it as a component in the hierarchy? If the latter, how do you do that? It's not available under the XR menu like AR Session Origin.
Add the ARRaycastManager component to the AR Session Origin. Then you use the raycastmanager in your script to perform the raycasts. You do not need to add it to the Hierarcy.
How do I add the ARRaycastManager component to the AR Session Origin?
Click on the "Add Component" and search for ARRaycastManager. In the script either use Getcomponent or add it using [SerializeField]. Here is a simple script using the mentioned manager.
using System.Collections.Generic; using UnityEngine; using UnityEngine.XR.ARFoundation; using UnityEngine.XR.ARSubsystems;
public class RaycastObject : MonoBehaviour { [SerializeField] ARRaycastManager raycastManager; [SerializeField] GameObject objectPrefab;
private GameObject placedObject;
private List<ARRaycastHit> s_Hits = new List<ARRaycastHit>();
private bool isObjectPlaced = false;
void Update()
{
if (Input.touchCount > 0 && Input.GetTouch(0).phase == TouchPhase.Began)
{
Touch touch = Input.GetTouch(0);
bool hitFound = raycastManager.Raycast(touch.position, s_Hits, TrackableType.Planes);
if (hitFound && !isObjectPlaced)
{
var hit = s_Hits[0];
Vector3 newPosition = hit.pose.position;
Quaternion newRotation = hit.pose.rotation;
placedObject = Instantiate(objectPrefab, newPosition, newRotation);
isObjectPlaced = true;
}
else
{
var hit = s_Hits[0];
Vector3 newPosition = hit.pose.position;
Quaternion newRotation = hit.pose.rotation;
placedObject.transform.position = newPosition;
placedObject.transform.rotation = newRotation;
}
}
}
}
Edit: I'm logging from my script and I'm not getting any hits from the raycast. placementPoseIsValid is always false. How do I troubleshoot the Raycast Manager?
Thanks for your continued help, @Organwolf! I have added the AR Raycast Manager to the AR Session Origin object. I'm no longer getting any errors in my script (below) using the raycast method on the raycast manager, which is a win.
But when building and running the app on my Android device I'm still not seeing the placement indicator. π€·ββ
Here's my ar session origin and my script in the hierarchy: https://imgur.com/a/Roci25f
The script itself is below. I know this is beyond the scope of what you helped me with but if anything jumps out at out you please let me know. Thanks again.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.XR.ARFoundation;
using UnityEngine.XR;
using UnityEngine.XR.ARSubsystems;
using System;
public class ARTapToPlaceObject : MonoBehaviour
{
public GameObject objectToPlace;
public GameObject placementIndicator;
private Camera myCamera;
private ARSessionOrigin arOrigin;
private ARRaycastManager raycastManager;
private Pose placementPose;
private bool placementPoseIsValid = false;
void Start()
{
arOrigin = FindObjectOfType<ARSessionOrigin>();
raycastManager = FindObjectOfType<ARRaycastManager>();
}
void Update()
{
UpdatePlacementPose();
UpdatePlacementIndicator();
Debug.Log(placementPoseIsValid);
if (placementPoseIsValid && Input.touchCount > 0 && Input.GetTouch(0).phase == TouchPhase.Began)
{
PlaceObject();
}
}
private void PlaceObject()
{
Instantiate(objectToPlace, placementPose.position, placementPose.rotation);
}
private void UpdatePlacementIndicator()
{
if (placementPoseIsValid)
{
placementIndicator.SetActive(true);
placementIndicator.transform.SetPositionAndRotation(placementPose.position, placementPose.rotation);
}
else
{
placementIndicator.SetActive(false);
}
}
private void UpdatePlacementPose()
{
var screenCenter = Camera.main.ViewportToScreenPoint(new Vector3(0.5f, 0.5f));
var hits = new List<ARRaycastHit>();
raycastManager.Raycast(screenCenter, hits, TrackableType.Planes);
Debug.Log(hits);
placementPoseIsValid = hits.Count > 0;
if (placementPoseIsValid)
{
placementPose = hits[0].pose;
var cameraForward = Camera.main.transform.forward;
var cameraBearing = new Vector3(cameraForward.x, 0, cameraForward.z).normalized;
placementPose.rotation = Quaternion.LookRotation(cameraBearing);
}
}
}
Edit: I'm logging from my script and I'm not getting any hits from the raycast. placementPoseIsValid is always false. How do I troubleshoot the Raycast Manager?
Thanks for your continued help, @Organwolf! I have added the AR Raycast Manager to the AR Session Origin object. I'm no longer getting any errors in my script (below) using the raycast method on the raycast manager, which is a win.
But when building and running the app on my Android device I'm still not seeing the placement indicator. π€·ββ
Here's my ar session origin and my script in the hierarchy: https://imgur.com/a/Roci25f
The script itself is below. I know this is beyond the scope of what you helped me with but if anything jumps out at out you please let me know. Thanks again.
using System.Collections; using System.Collections.Generic; using UnityEngine; using UnityEngine.XR.ARFoundation; using UnityEngine.XR; using UnityEngine.XR.ARSubsystems; using System; public class ARTapToPlaceObject : MonoBehaviour { public GameObject objectToPlace; public GameObject placementIndicator; private Camera myCamera; private ARSessionOrigin arOrigin; private ARRaycastManager raycastManager; private Pose placementPose; private bool placementPoseIsValid = false; void Start() { arOrigin = FindObjectOfType<ARSessionOrigin>(); raycastManager = FindObjectOfType<ARRaycastManager>(); } void Update() { UpdatePlacementPose(); UpdatePlacementIndicator(); Debug.Log(placementPoseIsValid); if (placementPoseIsValid && Input.touchCount > 0 && Input.GetTouch(0).phase == TouchPhase.Began) { PlaceObject(); } } private void PlaceObject() { Instantiate(objectToPlace, placementPose.position, placementPose.rotation); } private void UpdatePlacementIndicator() { if (placementPoseIsValid) { placementIndicator.SetActive(true); placementIndicator.transform.SetPositionAndRotation(placementPose.position, placementPose.rotation); } else { placementIndicator.SetActive(false); } } private void UpdatePlacementPose() { var screenCenter = Camera.main.ViewportToScreenPoint(new Vector3(0.5f, 0.5f)); var hits = new List<ARRaycastHit>(); raycastManager.Raycast(screenCenter, hits, TrackableType.Planes); Debug.Log(hits); placementPoseIsValid = hits.Count > 0; if (placementPoseIsValid) { placementPose = hits[0].pose; var cameraForward = Camera.main.transform.forward; var cameraBearing = new Vector3(cameraForward.x, 0, cameraForward.z).normalized; placementPose.rotation = Quaternion.LookRotation(cameraBearing); } } }
I just revisited the project and upgraded to the latest frameworks (ArFoundation 2.13 /Arkit 2.11/ Unity 2019.2.4f1)
Your script worked from the start so there must be something in your editor settings. Do you get a NullReference warning when hitting play or in Xcode when running the app?
I'm actually running this on a Pixel 2 with ARCore.
2019.2.4f1 Pixel 2 AR Foundation 2.0.2 ARCore XR Plugin 2.0.2
If I change the TrackableType.Planes to TrackableType.All then I get intermittent hits and the placement indicator will draw, but it's patchy in and out.
@eckmLJE
try changing the option inside your arcamera tracker pose to update. i have the same problem
@ulisesmora Sorry, could you rephrase that? I'm not following.
There is a new component called ARRaycastManager. You should add it to the same GameObject as ARSessionOrigin component in the tutorial and than you can perform Raycast methods using that ARRaycastManager. π
How is this done exactly? Right now my indicator is hanging in mid air. Most likely because the raycastManager isn't found upon start? Do I have to add a new GameObject and attach something containing the ARRaycastManager?
I have the same issue. Did you resolve it? If so, please let me know. I'm also trying with an android phone by the latest version of ARFoundation.
@ulisesmora i tried changing the ar camera option to update, but it didin't solve..
Someone solve it??
@andreac add an ar raycast manager component to your ar session origin, i think it will work
Edit: I'm logging from my script and I'm not getting any hits from the raycast. placementPoseIsValid is always false. How do I troubleshoot the Raycast Manager? Thanks for your continued help, @Organwolf! I have added the AR Raycast Manager to the AR Session Origin object. I'm no longer getting any errors in my script (below) using the raycast method on the raycast manager, which is a win. But when building and running the app on my Android device I'm still not seeing the placement indicator. π€·ββ Here's my ar session origin and my script in the hierarchy: https://imgur.com/a/Roci25f The script itself is below. I know this is beyond the scope of what you helped me with but if anything jumps out at out you please let me know. Thanks again.
using System.Collections; using System.Collections.Generic; using UnityEngine; using UnityEngine.XR.ARFoundation; using UnityEngine.XR; using UnityEngine.XR.ARSubsystems; using System; public class ARTapToPlaceObject : MonoBehaviour { public GameObject objectToPlace; public GameObject placementIndicator; private Camera myCamera; private ARSessionOrigin arOrigin; private ARRaycastManager raycastManager; private Pose placementPose; private bool placementPoseIsValid = false; void Start() { arOrigin = FindObjectOfType<ARSessionOrigin>(); raycastManager = FindObjectOfType<ARRaycastManager>(); } void Update() { UpdatePlacementPose(); UpdatePlacementIndicator(); Debug.Log(placementPoseIsValid); if (placementPoseIsValid && Input.touchCount > 0 && Input.GetTouch(0).phase == TouchPhase.Began) { PlaceObject(); } } private void PlaceObject() { Instantiate(objectToPlace, placementPose.position, placementPose.rotation); } private void UpdatePlacementIndicator() { if (placementPoseIsValid) { placementIndicator.SetActive(true); placementIndicator.transform.SetPositionAndRotation(placementPose.position, placementPose.rotation); } else { placementIndicator.SetActive(false); } } private void UpdatePlacementPose() { var screenCenter = Camera.main.ViewportToScreenPoint(new Vector3(0.5f, 0.5f)); var hits = new List<ARRaycastHit>(); raycastManager.Raycast(screenCenter, hits, TrackableType.Planes); Debug.Log(hits); placementPoseIsValid = hits.Count > 0; if (placementPoseIsValid) { placementPose = hits[0].pose; var cameraForward = Camera.main.transform.forward; var cameraBearing = new Vector3(cameraForward.x, 0, cameraForward.z).normalized; placementPose.rotation = Quaternion.LookRotation(cameraBearing); } } }
I just revisited the project and upgraded to the latest frameworks (ArFoundation 2.13 /Arkit 2.11/ Unity 2019.2.4f1)
Your script worked from the start so there must be something in your editor settings. Do you get a NullReference warning when hitting play or in Xcode when running the app?
I'm definitely getting the NullReferenceException error on UpdatePlacementPose(). If you have a fix for this, I would be so grateful!
In case anyone is still interested in solving NullReferenceException error. There are two changes to solve this issue:
It works for me on AR foundation 4.1.5 and ARKit 4.1.5. Cheers.
I followed your tutorial on YouTube. Using unity 2018.3 everything works like a charm. Trying on 2019.2 I get the error that ARSessionOrigin does not contain a definition for Raycast.
So far I couldn't find a reference to raycasting in the documentation.
Any hint?
Hi, I have the same issue. I add ar raycast manager in ar session origin but no prefab shows up... what's your solution, does it means I need to add a script to modofiy it?
Check out the demo projects
I followed your tutorial on YouTube. Using unity 2018.3 everything works like a charm. Trying on 2019.2 I get the error that ARSessionOrigin does not contain a definition for Raycast.
So far I couldn't find a reference to raycasting in the documentation.
Any hint?