Interactable
Last updated
Last updated
Interactable is base component that marks an object it is attached to as interactable in some way. Interactions are initiated by an . It is an abstract class and is meant to be derived from in order to create specific types of Interactables. It holds the following state:
Specifications - List of InteractableSpecification-derived object types. These are mainly used by various InteractionControllers - each specific type of InteractionController in OctoXR can have its own specific InteractableSpecification defined which can be added to this list. It is used by the corresponding InteractionController to store certain properties associated with the Interactable and may be required by the controller to drive the behavior of the object when it interacts with an Interactor. More on specific InteractableSpecifications can be found in section.
Similar to Interactor, Interactable offers various events that are triggered when its hovering/interacting state changes:
On Start Being Hovered - Triggered when Interactable starts being hovered by an Interactor, but only when it wasn't being already hovered by any Interactor, i.e. triggered on first hover start.
On Start Being Hovering By Interactor (Interactor) - Triggered when an Interactor starts hovering the Interactable. Interactor that initiated hovering is passed to event handlers as event argument. This is triggered for each distinct Interactor that starts hovering the Interactable. This event will fire immediately after On Start Being Hovered if the Interactor is the only Interactor that is currently hovering the Interactable.
On Start Being Interacted With - Triggered when Interactable starts interacting with any Interactor, but only when it wasn't already interacting with any Interactor, i.e. triggered on first interaction start.
On Start Being Interacted With By Interactor (Interactor) - Triggered when Interactor starts interacting with the Interactable. Interactor that initiated interaction is passed to event handlers as event argument. This is triggered for each distinct Interactor the Interactable starts interacting with. This event will fire immediately after On Start Interacting if the Interactor is the only Interactor that is currently interacting with the Interactable.
On End Being Interacted With By Interactor (Interactor) - Triggered when an Interactor stops interacting with the Interactable. Interactor that stopped interacting is passed to event handlers as event argument. This is triggered for each distinct Interactor the Interactable stops interacting with.
On End being Interacted With - Triggered when Interactable stops interacting with the last Interactor it was interacting with.
On End Being Hovered By Interactor (Interactor) - Triggered when an Interactor stops hovering over the Interactable. Interactor that stopped hovering is passed to event handlers as event argument.This is triggered for each distinct Interactor that stops hovering the Interactable.
On End Being Hovered - Triggered when Interactable stops being hovered by the last Interactor that was hovering the Interactable.
Interactable defines several public methods that can mainly be used to obtain the hovering and interacting state of the Interactable as well as Interactors that are currently hovering and/or interacting with the Interactable. Similar to Interactor, there are also methods for explicitly stopping the hovering and/or interactions that are currently in progress over Interactable.
Specific type of Interactables are required to implement following methods:
protected abstract InteractionMode GetInteractionMode() - Returns the interaction mode of the Interactable. There are 3 predefined modes:
SIngleHoverAndInteraction - In this mode Interactable can be hovered by only one Interactor and also interacted with by one Interactor at any given time. Once the Interactable starts interacting with an Interactor, it can no longer be hovered by any other Interactor.
MultipleHoversSingleInteraction - In this mode Interactable can be hovered by any number of Interactors at any given time, but it can interact with only one Interactor. Once an Interactor starts interacting with the Interactable, Interactable can no longer be hovered by any other Interactor. This is the usual default mode for Interactables used throughout OctoXR.
MultipleHoversAndInteractions - In this mode Interactable can always be hovered and interacted with by any number of Interactors simultaneously. This can be practical for certain advanced interactions.
public abstract InteractionController GetInteractionController() - This method should return InteractionController associated with the Interactable. It is required by interaction system for every Interactable to have a single associated InteractionController, otherwise hovers and interactions with the Interactable will not be possible.
There are also two methods the specific types of Interactables can override in order to have finer control over when and if they can be hovered and interacted with:
protected virtual bool CanStartOrContinueBeingHoveredByInteractorCore(Interactor interactor) - Indicates to the interaction system whether the Interactable can be hovered by a specific Interactor.
protected virtual bool CanStartOrContinueBeingInteractedWithByInteractorCore(Interactor interactor) - Indicates to the interaction system whether the Interactable can interact with a specific Interactor.
Both methods return true in their base implementations.
GrabInteractable is an Interactable that is meant to be used for grab type of interactions. It contains several properties on top of the ones inherited from Interactable:
Interaction Mode - Interaction mode for the Interactable, possible values and effects are described in the text above.
Interaction Controller - InteractionController associated with the Interactable. GrabInteractable uses a more specific type of InteractionController - GrabInteractionController. This has to be assigned. GrabInteractable will, by default, find the InteractionController from the same object it is attached to or from a parent object up the GrabInteractable's transform hierarchy, but this is performed only inside Unity editor when the GrabInteractable is reset (either explicitly or when initially attached to a GameObject).
Grab Points - A list of InteractableGrabPoint objects. These specify the hand poses that the interacting hand should assume when interacting with the GrabInteractable.
Require Grab Point For Interaction - Indicates whether the GrabInteractable must have at least one grab point in its Grab Points list in order for an Interactor to be able to interact with the GrabInteractable.
There are several public methods defined by GrabInteractable, they only consist of functionality for adding and removing grab points.
Target Wrist Pose - This is an object of IGrabPointWristPoseSource type. Interaction system uses IGrabPointWristPoseSource.TryGetHandWristAbsolutePose method on the assigned object to retrieve the pose that the interacting hand's root joint (wrist) should assume when grabbing the GrabInteractable. This property appears in the Unity editor as a drop-down that allows the user to select the exact implementing type to use for instantiating object instance value. Currently OctoXR offers one type - FromTransformGrabPointWristPoseSource (listed in the drop-down as From Transform). When selected, reference to a Transform component is exposed, it can be used to assign a Transform component whose world space pose will serve as the target pose for the interacting hand's wrist. OctoXR users can implement their own IGrabPointWristPoseSources - they will appear in the drop-down and can then be selected. Note that the implementing types must be regular C# classes, Unity Object-derived classes cannot be used.
Target Finger Bone Poses - Object of IGrabPointFingerBonePosesSource type. Interaction system uses IGrabPointFingerBonePosesSource.TryGetHandFingerBoneRelativePoses method on the assigned object to retrieve the pose that the interacting hand's finger joints should assume when grabbing the GrabInteractable. It appears and functions the same as the previously described Target Wrist Pose property in the Unity editor. One option is currently available - FromPoseAssetGrabPointFingerBonePosesSource (listed in the drop-down as From Pose Asset). When selected, it exposes a reference to a HandSkeletonPose object reference, this can be assigned to any HandSkeletonPose asset. Finger bone poses that the interacting hand should assume will then be read from the assigned asset. OctoXR users can implement their own additional IGrabPointFingerBonePosesSources, same rules for IGrabPointWristPoseSources apply here - only non-Unity Object derived classes are listed in the drop-down.
Hand Type - This property specifies whether the grab point should activate for left hand only or right hand only.
Max Grab Distance - Maximum allowed distance between interacting hand's wrist and grab point's target wrist position in order to activate grab point.
Max Grab Angle - Maximum allowed difference in angle of rotation between interacting hand's wrist and grab point's target wrist rotation in order to activate grab point, specified in degrees.
Grab points are used by GrabInteractables as a way to specify poses that interacting virtual hand should assume when interacting with GrabInteractable, i.e when it grabs an object in the scene. Grab points are implemented as InteractableGrabPoint class, object instances of this class can be added to GrabInteractable. In OctoXR, grab points of a GrabInteractable work in tandem with GrabPointInteractionTracker (described in page). GrabPointInteractionTracker is an IInteractionActivityIndicator that requires an Interactor attached to the same object it's attached to and should also be added as an Interaction Start Indicator to that Interactor. It tracks the hovering and interacting state of the Interactor associated with it and, if configured properly, makes the interacting hand assume a pose that is specified by a grab point on a GrabInteractable that the associated Interactor hovers and interacts with. In order to specify the pose that the interacting hand should assume, it uses the following properties: