Grabbables are one of ViRSE primary systems of user-environment interaction. They allow GameObjects to be picked up, moved and manipulated by players
Grabbables come in three types
- FreeGrabbables: Allows objects to be picked up and moved freely
- ConstrainedGrabbables: Allows grabbables to be given translation or rotation constraints, allowing you to make doors, drawers, pendulums, etc
- Adjustables: Similar to Activatables, these can be adjusted to the user and will emit a float value that you can pass to your plugin code. Unlike other grabbables, these have no physics!
All Grabbables share some common functionality
- OnGrabbed/OnDropped events: You can use the grabbable’s inspector to assign references to functions you want to invoke when these events are triggered
- AttachPoints: This is the point at which the grab is centered. If your GameObject has a “handle” (e.g, the hilt of a sword, the doorknob on a door, the handle of a lever), this handle should be set as the attachpoint
- Note: AttachPoints must have an active, non-trigger collider!
- GrabPoints: This is where the user must aim to actually grab the GameObject. Can either be the root GameObject that the grabbable component sits on, or the attachpoint
- Imagine our GameObject is a sword, with a hilt that’s been set as the attachpoint. If the GrabPoint is set to “Attach Point Only”, then the user must aim specifically at the hilt to grab the sword. If the GrabPoint is set to “This GameObject”, the user may grab the sword anywhere, although, while grabbed, the user will still hold the sword by its AttachPoint
Receiving grabs and drops
//Link this function to the OnGrabbed event in the Grabbable's inspector
public void OnGrabbableGrabbed(string playerID)
{
Debug.Log($"Player with ID {playerID} grabbed the grabbable!");
}
Triggering behaviors through code
//Expose reference to GameObject in inspector
[SerializeField] private GameObject gameObjectWithVirseComponent;
//Reference to the component's interface, in this case, IGrabbable
private IGrabbable virseComponent => gameObjectWithVirseComponent.GetComponent<IGrabbable>();
//An example of programmatically forcing the local user to drop the grabbable
private void ForceLocalUserDrop()
{
if (virseComponent.IsGrabbedByLocalUser())
virseComponent.ForceLocalUserDrop();
}
FreeGrabbables and ConstrainedGrabbables share further functionality
- DropSetting: Allows you to configure what happens when the grabbable is dropped
- Inherit Velocity From Hand: If the Rigidbody is set to non-kinematic, the grabbable will inherit velocity from the hand and be thrown in the direction it was moving when dropped
- Cancel Velocity: The grabbable will not inherit any momentum from the hand. If its RigidBody has gravity set to false, it will freeze and float in the air
- Return to Original Position: The grabbable will return to the position it was in at the start of the scene