Thorne Brandt

VR Wand Training

Harry Potter and the Cursed Child Release Night Installation

Download wand_training.exe

I created a site specific VR installation for the midnight release of Harry Potter. The app was site specific in that it spatially lined up with the back room of the book store during Harry Potter and the Party that Dare Not Speak It's Name, and was meant to be presented only by a professional wand instructor (me) that would command the interface and pull a few gags. There were a few other activities that the attendees had to particiapte in before they were allowed to try to beat the high score and win tokens that could be redeemed for prizes in other stations.

Here's how the script went. I turned away anyone who had not built a wand at the wand building station. Once they came back, wand in hand, I would attach their wand inside the motion controller. I explained the presence of the equipment, such as the VR helmet and motion controllers, as necessary safety devices, since magic can be quite treacherous.

I then asked them to test out their "Levioso" (levitation) incatation to bring me a book from across the room. Since their would only create fireballs, they would promptly make a mess, and I'd huff and puff for a while and they would apologize profusely. After calming down, tell them to channel that energy by testing their "Lacarnum Inflamari" (fireball) accuracy on a basic carnival ring toss game.

When you're dealing with a new tech such as VR, you automatically become an ambassador for it. What I wasn't prepared for were the repeat customers. There are few things more fulfilling than witnessing unbridled joy from users of your application. Another unexpected inspiration was witnessing kids design their own variation of the game. Realworld multiplayer in VR has to overcome the challenge of the asymmetry of the vastly different perspectives. An obvious solution is to draw from games that involve blindfolds ("Pin the Tail on the Donkey.") What emerged from "Wand Training" was coined "Catch the Magic Wand" by the child game designers. The game is basically just "Keepaway," but surprisingly dynamic and entertaining when all the player sees is a floating magic wand. Thankfully, no one was injured, because I'm not sure if the bookstore's insurace covered magic tricks gone wrong.

The tech was remarkably simple and the entire project took about two days. The first step was to create a wand that would replace the standard vive motion controller model.

Wand to replace vive controller model created in Maya

Hand painted normal map meant to elicit worn down carvings near base that have been smoothed by magic use

A fireball GameObject, represented by a series of particle effects and models, is instantiated on the tip of the model when the vive trigger is pressed via a joint, so we can take advantage of Unity's physics. When the trigger is released, the joint is deleted, and we collect the current angular velocity from the controller.

public GameObject fireball;
public Rigidbody attachPoint;
public float throwVelocity = 1;
SteamVR_TrackedObject trackedObj;
FixedJoint joint;

void Awake(){
	trackedObj = GetComponent();

void FixedUpdate(){
	var device = SteamVR_Controller.Input((int)trackedObj.index);
	if (joint == null && device.GetTouchDown(SteamVR_Controller.ButtonMask.Trigger)){
		var fb = GameObject.Instantiate(fireball);
		fb.transform.position = attachPoint.transform.position;
		joint = go.AddComponent();
		joint.connectedBody = attachPoint;
	} else if (joint != null && device.GetTouchUp(SteamVR_Controller.ButtonMask.Trigger)){
		GameObject joint_object = joint.gameObject;
		RigidBody rigidbody = joint_object.GetComponent();
		joint = null;
		var origin = trackedObj.origin ? trackedObj.origin : trackedObj.transform.parent;
		if(origin != null){
			rigidbody.velocity = origin.TransformVector(device.velocity * throwVelocity);
			rigidbody.angularVelocity = origin.TransformVector(device.angularVelocity);
			rigidbody.velocity = device.velocity;
			rigidbody.angularVelocity = device.angularVelocity;
		rigidbody.maxAngularVelocity = rigidbody.angularVelocity.magnitude;


The above script is attached to one of the SteamVR motion controller gameObjects, and then you can just drop in any kind of fireball you want.

Download wand_training.exe