DistanceGrab Sample Scene

The Unity DistanceGrab sample scene demonstrates how you can implement custom hands that can point at distant objects and have them zoom into their hands when the grip trigger is pulled. If an object is close enough to the hand to be grabbed normally, without zooming, it is grabbed in the same way as in the AvatarGrab sample scene. The user can also move around using the thumbsticks to demonstrate targeting range.

See the CustomHands, CustomControllers, and AvatarGrab sample scenes for more demonstrations of hand usage in VR.

The goal of this topic is to introduce you to the prefabs, Game Objects, components, and properties that make this functionality work. You can also use this sample scene as a starting point for your own application.

Scene Walkthrough

Unity Sample Framework Distance Grab Example

Here are brief descriptions of the key prefabs and other Game Objects that make the core distance grabbing functionality in this scene work. These are all described in further detail later in this topic.

  • OVRPlayerController Prefab – Prefab that allows the user to move around the scene. In this scene, this prefab essentially represents the user. Note that there is a child DetectGrabRange Game Object added to the prefab that is not normally there.
  • DetectGrabRange Game Object – Child object of OVRPlayerController that notifies grabbable objects when they are within grabbing range, at which point they become outlined in a color (or show a target) to indicate they are grabbable. The grabbing range itself is defined by a Sphere Collider component (as trigger) on this object. Developers can use this Game Object as a guide when creating an object with similar functionality.
  • DistanceGrabHandLeft and DistanceGrabHandRight Prefabs – Prefabs that contain the custom hands along with the necessary components and scripts to grab distant and nearby objects.
  • Grabbable Game Objects (DistanceGrabWoodBlockPf) - Objects in the scene that have been configured to be grabbed from nearby or a distance.

OVRPlayerController Prefab

The OVRPlayerController prefab includes components and child objects necessary for 3D control in a VR environment. It also contains a child OVRCameraRig to serve as the user’s VR camera and provide access to OVRManager.

Select OVRPlayerController in the Hierarchy and look at it in the Inspector window. Notable components include the following:

CharacterController

This standard Unity component is a capsule-shaped collider that can be directed to move around while being affected by collisions. Combined with the OVRPlayerController (Script) component, it provides for first-person 3D movement with a decent variety of options.

OVRPlayerController (Script)

Implements a basic first-person controller for VR. The controller will interact properly with a Unity scene, provided the scene has collision detection assigned to it. OVRPlayerController (Script) contains a few variables attached to sliders that change the physics properties of the controller. For more information on OVRPlayerController, see Oculus Utilities for Unity.

OVRSampleSceneController

Allows you to experiment with certain sample scene settings, such as Speed Rotation Increment, which controls how quickly speed and rotation change based on input.

OVRDebugInfo

Component that shows debug information in a HUD when the Space Bar is pressed while the scene is running.

DetectGrabRange Game Object

This child object of the OVRPlayerController notifies grabbable objects when they are in grabbing range. As the user moves around the scene, grabbable objects will move into and out of grabbing range.

Select OVRPlayerController in the Hierarchy and look at it in the Inspector window. Notable components include the following:

Grab Manager

Notifies objects with a DistanceGrabbable component within the Sphere Collider’s Radius that they are in grabbing range.

Sphere Collider

The Radius property component is used to establish the grabbing range around the OVRPlayerController.

As the user moves around, colored outlines (or targets) appear and disappear on grabbable objects as they pass into and out of range. When an object is within range, one of two colors will outline the object. One color (in this sample, white) indicates that an object is in grabbing range. Another color (blue), indicates that an object is being actively targeted by the user and can be grabbed by pressing the grip trigger.

DistanceGrabHandLeft and DistanceGrabHandRight Prefabs

These prefabs contain the custom hands as well as the components and child objects necessary to grab distant and nearby objects.

Select either of these prefabs in the Hierarchy and look in the Inspector window. Notable components include the following:

RigidBody

A standard Unity component that allows physics to be applied to an object. It is required to allow physical interaction with other objects in the scene.

Use Gravity is disabled to prevent gravity from affecting the hands. Is Kinematic is enabled to prevent hand movement from being affected by events such as collisions while still preserving their ability to physically interact with certain objects.

Hand

This component enables usage of a custom hand. The prefabs have default custom hands attached.

DistanceGrabber

This component enables the hands to grab distant and nearby objects that have been configured with a DistanceGrabbable component. This component is key to the main functionality of this sample scene, and its properties are as follows:

  • Grab Begin and Grab End – These define the grip trigger threshold for grabbing and releasing objects. For Grab Begin, the closer to 1, the further you must pull in the grip trigger to grab an object. For Grab End, the closer to 0, the more you must release the trigger to drop or throw an object.
  • Parent Held Object – Makes the grabbed object a child of the grabber. Enabling this works in this sample scene, but it can create issues in certain physics simulations.
  • Grip Transform – An attached child transform that indicates where to snap grabbed objects to. This transform is also used to rank objects for grabbing when there are multiple options.
  • Grab Volumes – Attached child collider objects that detect grabbable object candidates. These child collider objects must have Is Trigger enabled so they can successfully trigger grabbing events. This also prevents the colliders from being affected by physics.
  • Controller – Indicates the controller that the grabber is tied to.
  • Parent Transform – Transform of the parent object. You do not have to do anything with this property, but it can be used to attach the grabber to objects other than your Oculus Avatar.
  • Focus Color – Color used to highlight targeted grabbable objects.
  • Spherecast Radius – Sphere radius when using spherecasting to find target grabbable objects.
  • No Snap Threshhold – Objects below this distance will not zoom to the hand, but will be grabbed as if nearby. In other words, objects below this are considered nearby.
  • Use Spherecast – Enables use of spherecasting (rather than the default Grab Volumes) to find target grabbable objects.
  • Prevent Grab Through Walls – Prevents distant and nearby objects from being grabbed through walls.
  • Object Pull Velocity – Speed at which objects are pulled toward the hand.
  • Max Grab Distance – Maximum distance from which distant objects could be grabbed. This should be at least equal to (or slightly greater than) the DetectGrabRangeSphere Collider’s radius.
  • Grab Objects in Layer – Only objects from this layer can be grabbed.
  • Obstruction Layer – Layer that obstructs objects from being targeted and grabbed.
  • Player – Indicates the OVRPlayerController that the hand is attached to.

Grabbable Game Objects

This section looks at one of the many grabbable objects in the scene in detail, but the information applies to all of them, regardless of shape or size.

In the Hierarchy, go to Environment > Dynamic > WoodBlocks > DistanceGrabWoodBlockPf and look at the Game Object in the Inspector window.

In addition to mesh-related components present on all models, grabbable objects need to be configured with the following components to work properly:

Box Collider

A standard Unity component used to define the shape of an object for physical collision and interaction. This is what DistanceGrabber is looking at when it tries to grab an object. Some objects in the scene use Sphere Colliders when the shape of the object is appropriate.

RigidBody

A standard Unity component that allows physics to be applied to an object. It is required to allow physical interaction with other objects in the scene.

Although RigidBody is also used when making grabbers, its settings differ here. For grabbable objects, Use Gravity is enabled to allow for realistic throws and collisions with other interactive objects. Is Kinematic is disabled to allow physics to have full effect over the object.

DistanceGrabbable

This key component enables the object to be grabbed by avatar hands that have been configured with an DistanceGrabber component. This component is key to the main functionality of this sample scene, and its properties are as follows:

  • Allow Offhand Grab – When enabled, allows an object to be grabbed.
  • Snap Position – When enabled, the grabbed object’s position will snap to match the transform in Snap Offset.
  • Snap Orientation - When enabled, the grabbed object’s orientation (rotation) will snap to match the transform in Snap Offset.
  • Snap Offset – A transform that is an offset relative to the DistanceGrabber that the grabbed object’s position and/or orientation can snap to.
  • Grab Points – When several objects are used to make one larger object, the collider for each object is placed in Grab Point’s elements, allowing the objects to behave as a single object.
  • Material Color Field - This is the string that indicates the shader property for outline color to map to, enabling the highlighted outline effect for grabbable objects in range.

Using in Your Own Apps

The DistanceGrabHandLeft and DistanceGrabHandRight prefabs can easily be dropped into your own app to help get you started in implementing distance grabbing functionality in your own app. These prefabs include custom hands, but you can remove the Hand component from each prefab in order to make them suitable for use with Oculus Avatars. See the AvatarGrabber sample to see how (non-distance) grabbing hands work with avatars to get an idea of how distance grabbers would work with avatars.

Grabbable objects must be configured with DistanceGrabbable, RigidBody, and an appropriate collider in addition to standard mesh-related components.

There is no prefab for DetectGrabRange. You can make your own by adding a Game Object to the OVRPlayerController and adding the Oculus Grab Manager component to it along with a Sphere Collider.

Grabbing Range and Targeting

An important implementation consideration for distance grabbing is the range at which objects can be grabbed. To change the grabbing range of your hands, you must change three values:

  • The value of the Radius property on DetectGrabRange’s Sphere Collider component.
  • The values of the Max Grab Range properties on DistanceGrabHandLeft’s and DistanceGrabHandRight’s DistanceGrabber component.

The Radius property of DetectGrabRange’s Sphere Collider creates an area around the OVRPlayerController that informs objects with a DistanceGrabbable component that they are in grabbing range and available as a target to objects with a DistanceGrabber component. In short, DetectGrabRange determines the range of what can be grabbed.

However, it’s DistanceGrabHandLeft’s’ and DistanceGrabHandRight’s’ DistanceGrabber components that determine what is being actively targeted. The DistanceGrabbers’ Max Grab Distances must at least match the Radius of the Sphere Collider. It’s recommended that the Max Grab Distance be slightly larger than the radius to compensate for unpredictable real-world hand/body positioning.