HandRef that takes IHand. The other components on this prefab read hand state via this reference.ShapeRecognizerActiveState components that become active when criteria of a specified shape is met.TransformRecognizerActiveState that becomes active when a transform feature (such as a particular wrist orientation) is detected.ActiveStateGroup that returns true when all dependent ActiveStates are true.ActiveStateSelector and SelectorUnityEventWrapper, which can invoke events when a pose is detected.
TransformRecognizerActiveState and shapes which are bundled in ShapeRecognizerActiveState. These are combined using ActiveStateGroup to define the pose.ShapeRecognizerActiveState checks the shapes that make up a pose against the state of every finger. If they all match, the ShapeRecognizerActiveState becomes active.ShapeRecognizer is a ScriptableObject that defines a shape. To define a shape, it uses a set of rules called Feature Configs. Feature Configs specify a required position (state) for each of the five fingers. It defines state using at least one of the finger features: curl, flexion, abduction, and opposition. ShapeRecognizer is referenced by the ShapeRecognizerActiveState component to determine if a pose is active.FingerFeatureStateProvider provides the finger states of the tracked hands and contains the state transition thresholds for each finger. It’s referenced by the ShapeRecognizerActiveState component.FingerFeatureStateThresholds is a ScriptableObject that defines the state thresholds for each finger feature. A state threshold is a set of boundaries that determine when a finger has transitioned between states. For example, the curl feature has 3 states: open, neutral, and closed. The state thresholds for curl use an angle in degrees to define when the finger’s state has changed from open to neutral, neutral to closed, or vice-versa.DefaultSettings/PoseDetection:




The axes that define the hand’s fingers, wrist, and palm.TransformRecognizerActiveState takes a TransformFeatureStateProvider, a list of transform feature configs, and a transform config. The state provider reads the raw feature values and quantizes them into TransformFeatureStates using the TransformConfig you provide in this component.TransformFeatureStateProvider provides the transform states of the tracked hand. It’s referenced by the TransformRecognizerActiveState component.RegisterConfig method can then query the state of each state tracked for configuration. It leverages FeatureStateProvider to drive state-changing logic.JointDeltaProvider is a component that tracks hand joint positions between frames and calculates the frame-to-frame position and rotation deltas. It caches joint pose data to avoid redundant calculations when multiple components need delta information for the same joints.JointVelocityActiveState and JointRotationActiveState require a reference to a JointDeltaProvider to access joint movement data. The provider only tracks joints that have been registered by active consumers, keeping overhead minimal.| Property | Description |
|---|---|
Hand | The tracked hand from which joint pose data is read each frame |
JointVelocityActiveState is an IActiveState that tracks position velocities for a list of hand joints and compares them against a target direction. If the velocity along the target axis exceeds the threshold for the minimum time, the state becomes active.| Property | Description |
|---|---|
Hand | The tracked hand that provides joint positions |
Joint delta provider | The JointDeltaProvider used to retrieve cached position deltas |
Feature configs | A list of joints and their target axes to evaluate |
Min velocity | The velocity threshold in units per second that must be exceeded for the state to become active |
Threshold width | A hysteresis buffer applied to the velocity threshold to prevent rapid toggling at the boundary |
Min time in state | The minimum duration in seconds that the velocity must exceed the threshold before the state changes |
JointRotationActiveState is an IActiveState that tracks angular velocities for a list of hand joints and compares them against a target rotation axis. If the angular velocity around the target axis exceeds the threshold for the minimum time, the state becomes active.| Property | Description |
|---|---|
Hand | The tracked hand that provides joint rotations |
Joint delta provider | The JointDeltaProvider used to retrieve cached rotation deltas |
Feature configs | A list of joints and their target rotation axes to evaluate |
Degrees per second | The angular velocity threshold in degrees per second that must be exceeded for the state to become active |
Threshold width | A hysteresis buffer applied to the angular velocity threshold to prevent rapid toggling at the boundary |
Min time in state | The minimum duration in seconds that the angular velocity must exceed the threshold before the state changes |
IActiveState components can be chained together using the Sequence component. Because Sequence components can recognize a series of IActiveStates over time, they can be used to compose complex gestures. For examples of complex gestures, see the GestureExamples sample scene.Sequence takes a list of ActivationSteps and iterates through them as they become active. Each ActivationStep consists of an IActiveState, a minimum active time, and a maximum step time. These steps function as follows:IActiveState must be active for at least the minimum active time before the Sequence proceeds to the next step.IActiveState is active for longer than the maximum step time, the step will fail and the Sequence will restart.Sequence has completed, the Sequence becomes active. If an optional RemainActiveWhile IActiveState has been provided, the Sequence will remain active as long as RemainActiveWhile is active.Sequence is the optional cooldown phase, the duration of which can be set in the RemainActiveCooldown field. A Sequence that is deactivating will wait for this cooldown timer to elapse before finally becoming inactive.SequenceActiveState is an IActiveState wrapper for a Sequence, and can either report active once the Sequence has started, once the Sequence steps have finished, or both.ActiveStateDebugTreeUI component renders a real-time visual tree of any IActiveState hierarchy on a world-space UI canvas. Each node in the tree represents one IActiveState component and displays whether it is currently active or inactive. This makes it straightforward to see which parts of a pose or gesture sequence are being recognized and which are not.ActiveStateDebugTreeUI operates on the IActiveState interface, you can use it to debug any IActiveState hierarchy in your project, not only poses. For example, you can assign an ActiveStateGroup, Sequence, or any custom IActiveState as the root to visualize its state tree.ActiveStateDebugTree prefab from Packages/com.oculus.integration.interaction/Runtime/Prefabs/Debug/ to your scene.ActiveStateDebugTreeUI component, assign the root IActiveState you want to debug, such as an ActiveStateGroup or Sequence.IActiveState node, color-coded by its current active or inactive status.| Property | Description |
|---|---|
Active state | The root IActiveState whose tree will be visualized |
Node prefab | The prefab used to render each node in the tree |
FeatureStateProvider is a generic helper class that keeps track of the current state of features, and uses thresholds to determine state changes. The class uses buffers to state changes to ensure that features do not switch rapidly between states.IFeatureStateThreshold is a generic interface that defines the functionality of all thresholds used in hand pose detection.IFeatureStateThresholds defines a collection of IFeatureStateThresholds, specific to a feature type, whether that is finger features or transform features.IFeatureThresholds provides an interface to a collection of IFeatureStateThresholds as well as MinTimeInState (i.e. a minimum threshold of time a feature can be in a certain state before transitioning to another state).IActiveState that tests to see if a hand joint is inside a collider. If a SphereCollider is specified then its radius is used for checking, otherwise the script relies on the collider’s bounds. This class is useful in case a developer wishes to see if the hand joint exists within a certain volume when a pose is active.ColliderContainsHandJointActiveState to position a collider relative to the center eye.