tl;dr: download and run the (Godot XR Tools demo](https://github.com/GodotVR/godot-xr-tools) to learn how it works. it’s the only way.
if you’re reading this, you probably already know that Godot is a powerful tool for indie game development. i think it’s less well known how great Godot is for working with VR. there’s some great tools out there, but the documentation for a lot of them can be patchy. so i’m writing up some of what i’ve learned in the hopes that it saves someone else some time and headache. much of this will be broad “here’s some things to look into on your own”-type advice, but some will be detailed technical information.
dramatis personae
first, Godot rarely refers to its “VR” capabilities. the more common term is “XR”, which is an umbrella term including both VR and AR. i’ve never experimented with the AR side of things, but i’ll stick to the more generic “XR” term to keep parity.
second, i’m going to be talking primarily about the Godot XR Tools plugin. the tool is open source, and primarily maintained by Bastiaan Olij and Malcolm Nixon. Bastiaan has a ton of tutorials related to XR Tools specifically and Godot XR generally, and over all seems to be the more public-facing member of the team. for that reason, i’ll be referencing him frequently. don’t take that to mean that i think he’s the sole author of this beautiful software!
first principles
out of the box, Godot has basic XR functionality. the basics are covered in the official Godot documentation. with very little setup, you can track your controllers and headset in physical space, get controller inputs, and send the rendered output of your game to your headset. there are many XR games that could be made with no further XR functionality.
for example, the War Thunder / Elite: Dangerous approach. use the flatscreen input scheme (keyboard and mouse, joystick, whatever the game already uses) but all the while immersing the player in the game by simply letting them look around.
in fact, technically, any XR game can be made with no further XR functionality. but there exist a number of common challenges shared by most XR games. for example, let’s say you have a door, and a puzzle to unlock the door (a la Portal). in a flatscreen game, you enable collisions on the player and on the door, and now the player has to solve the puzzle to open the door. in VR, nothing stops the player from physically walking (with their legs) until they phase through the door and can advance to the next area, bypassing your puzzle. this is one example, and it’s far from impossible to solve on your own, but it’s one of many problems with a set of common solutions. solving these problems in novel ways can be fun, can address issues not helped by the established solutions, and is necessary to a certain extent to keep the industry from stagnating. but for the majority of games, you just don’t want the player to walk through the door.
this is where we introduce the 3rd party plugin “Godot XR Tools”.
XR Tools intro
Godot XR Tools is developed by many of the same people who developed Godot’s core XR capabilities, and features many of those standard, accepted solutions to XR tasks. for the example door-player collision challenge, XR Tools provides you with a new Player Body node that simply resolves that issues out of the box. add it as a child of your XR Origin node, and the player can no longer walk through static colliders.
XR Tools has a documentation page, and it’s a decent place to start. reading through the tabs there will explain key concepts like the different physics layers, the fact that lots of functionality (the ability to pick up items, move/rotate/teleport with the joystick, etc.) can be added to the player by adding the relevant node as a child of a controller, and the many drop-in movement options available (seriously, you can start climbing walls ~2 minutes after installing XR Tools!).
Bastiaan’s tutorials
but if you really want to learn how to use XR Tools, you’ve got to watch Bastiaan Olij’s tutorial series. here’s the first of (at time of writing) four videos. they’re a little out of date, but they are incredibly helpful in understanding how this all actually works. the focus of the series is on all the ways you can pick up objects, and all the ways in which “picking up objects” can be combined with itself to create engaging mechanics. the culmination of the series is a fully-integrated pistol, where the player can load a magazine, rack the slide, fire the gun until empty, release the magazine, ad infinitum. it’s got all the tactile interactions a player might want in a semi-serious gun simulation, and the lessons learned in that project can just as easily be applied to non-gun complicated hand interactions in VR.
also he has many other great Godot / XR videos, but that tutorial series is most relevant to this post.
the missing link
if you followed along with Bastiaan’s tutorial series, you might have noticed some strange features of XR Tools that go unaddressed in the videos: what’s the difference between a collision hand and a physics hand? what’s an interactable slider? wait there’s also an interactable joystick? and a hinge, and a handle, and an area button?
intrigued, you may have consulted the XR Tools documentation page. sadly, there’s no mention of any of these topics. no fear, the plugin is well commented. take a look and:
XRTools Collision Hand Container Script This script implements logic for collision hands. Specifically it tracks its ancestor [XRController3D], and can act as a container for hand models and pickup functions.
maybe that makes sense to you. certainly, it’s all true. and once you know how collision hands work, that makes sense. but for me, it was no help in understanding what this node actually did, or how to configure it. even more challenging were the interaction slides/joysticks/hingest/etc.
but then i was watching more of Bastiaan’s videos and saw all these strange nodes on display in his XR Tools Demo showcase. it turns out that the Godot XR Tools github repo has the demo built in. if you download it and open it in Godot, you can kick it off right now. until recently it was very unstable for me. some recent commits have updated it to be compatable with Godot 4.4, and i’ve experienced no demo crashes since then. your mileage may vary, depending on when you read this.
so if you really want to learn to use XR Tools, you’ve got to download the demo, mess around with it, and inspect its node architecture. if you hop into the pickable demo scene, you’ll notice that you hands can push the blocks around through regular physics collisions, with no need to actually pick them up. and you might also notice that your hands collide with the table and don’t pass through. this all lays bare how each of the un(der)documented features work. it’s the only advice you really need.
ars technica
okay so everything i know about this plugin can be learned from poking around in the demo and in the source code. but to spare you some time, dear reader, here’s a few of my key nugets of wisdom:
collision hands
without a doubt, the most revolutionary undocumented feature i’ve experimented with have to be collision hands. they turn your hands from controller-guided unstoppable forces, able to phase through walls and unable to push objects, into physics objects driven by the controller positions. ordinarily you wouldn’t notice a difference, but you can go ahead and nudge a box out of your way while you’re looting. and your hands can’t pass through that wall. it’s a one-click boost to immersion.
to use them, add a “Collision Hands” node as a child of each controller node. then you can, as the comment says, reparent all of your hand models, movement / pickup function nodes, etc. to the collision hand node.
what should you use as your hand model? well if you’re making a full game then you should probably make or buy your own models. but you can use the ones that ship with the plugin just fine. they can be found in ‘addons/godot-xr-tools/hands/scenes/’, then either the ‘lowpoly’ or ‘highpoly’ folder. i personally just use ‘left_hand_low’ and ‘right_hand_low’ for my experiments.