Skip to content

PickupAndThrow

Bastiaan Olij edited this page Jul 25, 2021 · 3 revisions

Implementing picking up and throwing objects

Introduction

One of the greatest things VR has to offer that no traditional game can match up to is the ability to physically interact with your environment. While we're not yet to the point of having fully functional haptic gloves the current generation of VR controllers are a decent enough facsimile that allow us to manipulate objects in space.

Here we are going to look at the functionality in the XR toolkit that allows you to pick up, drop and throw objects.

While we'll cover what can be done with these components out of the box they open up the door to many more interactions with a little bit of extra code.

Setup

This functionality is split into two objects that work together. We have an script (and scene) that implements the logic for that scene to be picked up, and we have a function script that implements the logic that allows a controller to pick up those objects.

Pickable Object

This scene can be inherited to create an object the player can pick up. From the Scene menu select New Inherited Scene and select res://addons/godot-xr-tools/objects/Object_pickable.tscn.

At minimum we need to do atleast two things:

  • Add a mesh for the object
  • Add a collision shape to the CollisionShape node

Optionally we can also place the pickup point, this is the location on the object where we hold it. It is also advisable to check the properties of the RigidBody we're inheriting, especially setting the objects mass to something sensible.

Note the ability to change the layer the object is in while it is being held by the player. This allows you to have the object interact with other objects while in possesion of the player. You can have some real fun with this last one, for instance if you have different ammo types in your game you can place a magazine in a layer specific to that ammo type when it is picked up by a player and then use that layer to detect when the player holds the magazine in the right place for that type of weapon for it to reload.

Pickup function

This is a function script that adds functionality to a controller that enables picking up objects with that controller. Just like the other functions you add it as a child node to the controller. Often it makes sense to add this to both hands.

Configuration

Pickable Object

Property Description
Press To Hold If set the player needs to hold the button pressed
Reset Transform On Pickup If set the object will snap to the players controller when picked up using the PickupCenter child nodes location as the snap point
Highlight Mesh Instance Select a MeshInstance node that you want highlighted when the controller comes near enough for the user to pick up that object*
Picked Up Layer This layer mask is set to the object when the object is picked up
  • Highlighting the object when it can be picked up is implemented by replacing all materials on this mesh with a highlight material. Implement your own _update_highlight function to customise this.

There are a number of public functions on our object that work together with the pickup function. The functions that are available for game logic are:

Function Description
is_picked_up Returns true if this object is currently picked up
drop_and_free Drops the object and frees it

You can also implement a function called action that will be called when the user presses the action button on the controller currently holding your object.

Pickup function

Property Description
Pickup Range The distance up to which we check of objects that can be picked up
Impulse Factor When an object is throw this can be used to give an extra boost
Pickup Button Id The button on the controller that must be pressed to grab/let go of an object
Action Button Id If this button is pressed while holding an object that has an action function implemented, that function is called
Max Samples When throwing an object we smooth the linear and angular velocity of the controller by this number of samples
Clone this wiki locally