using System;
using Unity.Collections;
using UnityEngine.SubsystemsImplementation;
namespace UnityEngine.XR.ARSubsystems
{
///
/// Base class for a raycast subsystem.
///
///
/// This abstract class should be implemented by an XR provider and instantiated using the SubsystemManager
/// to enumerate the available s.
///
public class XRRaycastSubsystem
: TrackingSubsystem
{
#if DEVELOPMENT_BUILD || UNITY_EDITOR
ValidationUtility m_ValidationUtility = new();
#endif
///
/// Constructor. Do not invoke directly; use the SubsystemManager
/// to enumerate the available s
/// and call Create on the desired descriptor.
///
public XRRaycastSubsystem() { }
///
/// Get the changes to the tracked raycasts (arrays of added, updated and removed) since the last call to this
/// method.
///
/// An [allocator](https://docs.unity3d.com/ScriptReference/Unity.Collections.Allocator.html)
/// to use for the returned container.
/// The set of changes since the last call to this method. The caller owns the data and is responsible
/// for calling on it.
public override TrackableChanges GetChanges(Allocator allocator)
{
var changes = provider.GetChanges(XRRaycast.defaultValue, allocator);
#if DEVELOPMENT_BUILD || UNITY_EDITOR
m_ValidationUtility.ValidateAndDisposeIfThrown(changes);
#endif
return changes;
}
///
/// Attempts to add a new persistent raycast. The raycast will be updated automatically until
/// this subsystem is stopped or destroyed, or the the raycast is removed with
/// .
///
/// A point on the screen, in normalized screen coorindates (0, 0)..(1, 1).
/// The estimated distance to the raycast target. For example, an average
/// human height might be used to estimate the distance to the floor.
/// The newly added raycast. All spatial data is relative to the XR origin.
/// `True` if the raycast was successfully added, or `false` otherwise.
public bool TryAddRaycast(Vector2 screenPoint, float estimatedDistance, out XRRaycast raycast) => provider.TryAddRaycast(screenPoint, estimatedDistance, out raycast);
///
/// Attempts to add a new persistent raycast. The raycast will be updated automatically until
/// this subsystem is stopped or destroyed, or the the raycast is removed with
/// .
///
/// A [ray](https://docs.unity3d.com/ScriptReference/Ray.html) relative to the XR origin defining the raycast.
/// The estimated distance to the raycast target. For example, an average
/// human height might be used to estimate the distance to the floor.
/// The newly added raycast. All spatial data is relative to the XR origin.
/// `True` if the raycast was successfully added, or `false` otherwise.
public bool TryAddRaycast(Ray ray, float estimatedDistance, out XRRaycast raycast) => provider.TryAddRaycast(ray, estimatedDistance, out raycast);
///
/// Removes an existing raycast by its .
///
/// The unique identifier for the raycast to remove.
public void RemoveRaycast(TrackableId trackableId) => provider.RemoveRaycast(trackableId);
///
/// Casts against trackables specified with .
///
/// A ray in session space.
/// The types of trackables to test for ray intersections.
/// The Allocator used to allocate the returned NativeArray.
/// A NativeArray of all the resulting ray intersections.
public NativeArray Raycast(
Ray ray,
TrackableType trackableTypeMask,
Allocator allocator)
{
return provider.Raycast(XRRaycastHit.defaultValue, ray, trackableTypeMask, allocator);
}
///
/// Casts a ray originating from against trackables specified with .
///
/// A point on the screen in normalized screen coordinates (0, 0) - (1, 1).
/// The types of trackables to test for ray intersections.
/// The Allocator used to allocate the returned NativeArray.
/// A NativeArray of all the resulting ray intersections.
public NativeArray Raycast(
Vector2 screenPoint,
TrackableType trackableTypeMask,
Allocator allocator)
{
return provider.Raycast(XRRaycastHit.defaultValue, screenPoint, trackableTypeMask, allocator);
}
///
/// An interface to be implemented by providers of this subsystem.
///
public class Provider : SubsystemProvider
{
///
/// Called when the subsystem is started. Will not be called again until .
///
public override void Start() { }
///
/// Called when the subsystem is stopped. Will not be called before .
///
public override void Stop() { }
///
/// Called when the subsystem is destroyed. will be called first if the subsystem is running.
///
public override void Destroy() { }
///
/// Adds a new persistent raycast. Persistent raycasts should be updated automatically until this
/// provider is stopped or destroyed or the raycast is removed with
/// .
///
/// A position on the screen in normalized screen coordinates (0, 0)..(1, 1).
/// The estimated distance to the raycast target.
/// The newly added raycast. All spatial data should be reported relative to the XR origin.
/// `True` if the raycast was added; otherwise `false`.
public virtual bool TryAddRaycast(Vector2 screenPoint, float estimatedDistance, out XRRaycast raycast)
{
raycast = XRRaycast.defaultValue;
return false;
}
///
/// Adds a new persistent raycast. Persistent raycasts should be updated automatically until this
/// provider is stopped or destroyed or the raycast is removed with
/// .
///
/// A ray in session space defining the raycast.
/// The estimated distance to the raycast target.
/// The newly added raycast. All spatial data should be reported relative to the XR origin.
/// `True` if the raycast was added; otherwise `false`.
public virtual bool TryAddRaycast(Ray ray, float estimatedDistance, out XRRaycast raycast)
{
raycast = XRRaycast.defaultValue;
return false;
}
///
/// Removes a raycast previously added with
///
/// or
///
///
/// The unique identifier associated with the raycast to remove.
public virtual void RemoveRaycast(TrackableId trackableId) { }
///
/// Get the changes to raycasts (arrays of added, updated, and removed) since the last call to this method.
///
/// A default value for s. For backwards compatibility,
/// this should be used to initialize the returned
/// [NativeArray](https://docs.unity3d.com/ScriptReference/Unity.Collections.NativeArray_1.html)s.
/// The [Allocator](https://docs.unity3d.com/ScriptReference/Unity.Collections.Allocator.html)
/// to use when allocating the returned [NativeArray](https://docs.unity3d.com/ScriptReference/Unity.Collections.NativeArray_1.html)s.
/// Arrays of added, updated, and removed raycasts since the last call to this method. The
/// changes should be allocated using . The caller owns the memory.
public virtual TrackableChanges GetChanges(XRRaycast defaultRaycast, Allocator allocator) => default;
///
/// Performs a raycast from an arbitrary ray against the types
/// specified by . Results
/// should be sorted by distance from the ray origin.
///
/// The default raycast hit that should be used as a template when populating the returned NativeArray.
/// A ray in session space from which to raycast.
/// The types to raycast against.
/// The allocator with which to allocate the returned NativeArray.
/// A NativeArray of all the resulting ray intersections.
public virtual NativeArray Raycast(
XRRaycastHit defaultRaycastHit,
Ray ray,
TrackableType trackableTypeMask,
Allocator allocator)
{
throw new NotSupportedException("Raycasting using a Ray is not supported.");
}
///
/// Performs a raycast from the camera against the types
/// specified by . Results
/// should be sorted by distance from the ray origin.
///
/// The default raycast hit that should be used as a template when populating the returned NativeArray.
/// A point on the screen in normalized (0..1) coordinates.
/// The types to raycast against.
/// The allocator with which to allocate the returned NativeArray.
/// A NativeArray of all the resulting ray intersections.
public virtual NativeArray Raycast(
XRRaycastHit defaultRaycastHit,
Vector2 screenPoint,
TrackableType trackableTypeMask,
Allocator allocator)
{
throw new NotSupportedException("Raycasting using a screen point is not supported.");
}
}
}
}