Hit Testing Sample
This sample demonstrates how to hit test against points and planes found in the real world.
For basic information about hit testing via raycasts and what AR Foundation's AR Raycast Subsystem
component does, please refer to the Unity documentation.
In order to use this feature it has to be enabled in the OpenXR plugin settings located under Project Settings > XR Plug-in Management > OpenXR (> Android Tab)
.
The wordings ray casting and hit testing are used interchangeably throughout the documentation.
How the sample works
If Use Scene Understanding Plane Detection is enabled in the Plane Detection feature settings, the ARRaycastHit.trackableId
field will always return the trackableId of 0-0
as the session-unique identifier for the trackable that was hit. If Use Scene Understanding Plane Detection is disabled, the ARRaycastHit.trackableId
will return the trackableIds of the planes that the raycast has hit.
Adding the AR Raycast Manager
to the AR Session Origin
GameObject will enable the ray casting subsystem. If there is no plane manager available, the Hit Testing
feature will create the underlying foundations for hit testing. If a plane manager will be spawned later on, the underlying plane detection subsystem will be adjusted for that manager and hit tracking might work differently (for instance, results depend on the plane filters set on the plane manager). For optimal results, enable all filters on the plane manager, if you use hit testing as well. If you don't use a separate plane manager, the hit testing feature will handle this automatically for best results.
The AR Raycast Manager
component provides a field for defining a prefab to spawn upon successfully intersecting with a plane. For this sample, the prefab has been left blank, since this functionality is implemented in the Hit Testing Sample Controller
component.
The raycast manager's Raycast
function will return a boolean value depending on if the ray has hit a plane or not. The hit result(s) will be added to the ARRaycastHit list, sorted by ascending distance (i.e. closest first).
public void Update() {
CastRay();
_activeIndicator.transform.position = _desiredPosition;
}
private void CastRay() {
Ray ray = new Ray(_cameraTransform.position, _cameraTransform.forward);
List<ARRaycastHit> hitResults = new List<ARRaycastHit>();
if (_raycastManager.Raycast(ray, hitResults)) {
_desiredPosition = hitResults[0].pose.position;
...
}
else {
...
}
}
The sample scene has a default red colored gizmo indicator that follows the gaze. Every frame a raycast is created from the origin of the head to the direction of the gaze. If the raycast hits a plane, the indicator gizmo will change color and move to the hit position. If it doesn't hit anything, the indicator gizmo will remain the same.