Throwing Objects in Daydream VR and Unity

vrkidsfun

Have you ever walked into an antique store and been struck with an overwhelming urge to grab things off the shelves and start throwing them against the walls? Well, you’re in luck because that kind of antisocial behavior is one of the singular pleasures of being a VR developer. Smashing, breaking and destroying digital things with reckless abandon is the main reason I got into this game in the first place. In this tutorial we’re going to channel your inner juvenile delinquent by building a physics based VR throwing mechanic using a system known as the Elbow Model.

throwingelbowmodeldig

Update (01/08/17): This tutorial was originally written using a pre-release version of the Daydream Unity SDK and is therefore deprecated. The code in the tut is still totally valid, but the linked Unity package uses an older SDK so may not run in recent versions of Unity. See my updated tutorials here on setting up Daydream and here on building a working controller based app with teleportation that uses the release SDK.

The trick to throwing things in Daydream VR is a technique known as the elbow model (also referred to as the arm model). Remember that the Daydream controller is locked to a fixed position in 3DoF space (see my explanation of 3DoF v 6 DoF here) so it’s impossible to rotate the arm realistically without some trickery. In the elbow model, we offset the position of the controller equal to the forearm. We then add the controller model (or in this case the ball) as a child of the elbow, so when it rotates it follows the arc of the hand. You could do this offset and rotation programmatically but I haven’t because I’m lazy. The other part of the mechanic uses a physics impulse to shoot the ball out based on the velocity of the movement when the user releases the button

Go ahead and download the finished Unity package here, import it into a new Unity project and check out the code. You’ll see in the main scene I’ve set up a precariously balanced wall of cubes just waiting for you to pitch balls at. I’ve manually created the elbow model by placing a sphere in an empty gameObject (BallAndArm) and offsetting it on the z axis by 0.8. The code related to the throwing is in ControllerManager which is attached to an object in the shape of a Daydream controller, I’ve left this in so that you can see the rotation direction of the controller while you’re throwing the ball.

At lines 21-23 I’m getting the rotation of the controller and applying it to the ballAndArm game object, this creates the elbow model. At line 25-28 if the user presses down on the click button down we create a ball. At line 30 I’m getting the current velocity of the ball by dividing the change in distance by time. At line 34-37 if a release of the button is triggered we call the throwBall method and hide the ball spawn. Lines 41-47 we instantiate a new ball and throw it by adding an impulse force, based on the velocity of the rigid body of the ball.

using UnityEngine;
using System.Collections;
using UnityEngine.UI;

public class ControllerManagerScript : MonoBehaviour {

	public GameObject ballAndArm;
	public GameObject ballSpawn;
	public Text hudText;

	private Vector3 ballV;
	private Vector3 ballLastPosition;

	void Start () {
		Vector3[] initLaserPositions = new Vector3[ 2 ] { Vector3.zero, Vector3.zero };
		ballSpawn.SetActive(false);
		ballV = new Vector3 (1f, 1f, 1f);
	}

	void Update () {
		Quaternion ori = GvrController.Orientation;
		gameObject.transform.localRotation = ori;
		ballAndArm.transform.localRotation = ori;

		if (GvrController.ClickButtonDown) {
			// show ball as visible to start throw
			ballSpawn.SetActive(true);
		}

		ballV = (ballSpawn.transform.position - ballLastPosition) / Time.deltaTime;
		ballLastPosition = ballSpawn.transform.position;
		
		if (GvrController.ClickButtonUp) {
			ThrowBall ();
			ballSpawn.SetActive(false);
		}

	}

	void ThrowBall () {
		GameObject ballObj = (GameObject)Instantiate (Resources.Load ("Ball"));
		ballObj.transform.position = ballSpawn.transform.position;

		Rigidbody rb = ballObj.GetComponent<Rigidbody>();
		rb.AddForce (ballV.x * 2.0f, ballV.y * 2.0f, ballV.z * 2.0f, ForceMode.Impulse);
	}
}

Building a throwing elbow model is relatively simple,it just requires some creative heuristics based on the rotation of the controller. Now that you can throw balls in VR it’s time to go forth and break, smash and destroy all the things in VR!

Disclaimer: I’m a Google employee and write blog posts like this with the sole purpose of encouraging and inspiring developers to start exploring Google’s amazing Daydream VR platform. Opinions expressed in this post are my own and do not reflect those of my employer. I would never share any secret or proprietary information.

 

3 comments

  1. Hi,

    thank You for making this tutorials.They´re helping to get started in Daydream as well.I´m allready developing my first game for it.It´s not a A+++ Game, because 8i-VR is a one man show without education in developing, but its truely a good VR-experience. You can check it out there:

    https://www.youtube.com/watch?v=XO13zoXL6jg

    Its in beta status right now, so if you want to test,hit me up and i will send You the apk.
    It would be nice if you tell me what You think about it.

    Have a nice day and sorry for my bad english 🙂

    Reply

  2. Thanks for this excellent tutorial! Some questions:

    1) How would you recommend adapting this project to include the new GvrArmModel script provided in Daydream SDK v1.10?

    2) Wouldn’t it make more sense to apply a velocity instead of an impulse when you throw the object? This seems to work a lot better for me.
    I.e:
    rb.velocity = Vector3.zero;
    rb.AddForce(velocity, ForceMode.VelocityChange);

    3) Any reason why you chose FixedDeltaTime in favor of just DeltaTime? FixedDeltaTime would make more sense in a FixedUpdate() if my understanding is correct.

    Reply

    1. @SU Thanks for the kind words you truly are a gentleman and a scholar!
      1. Take a look at my recent tutorial on getting set up with the new V1.1 SDK: http://www.sdkboy.com/2016/12/building-daydream-controller-based-app-scratch/
      It shouldn’t be too hard to port this throwing concept to the new SDK. I wrote this tutorial before the 1.0 release.
      2. Yes I could use velocity here. I’ll have to try as you suggest. It’s one of those things where there are multiple ways of completing the task. I was also thinking it would also be better to get rid of the ClickButtonUp to release and just releasing the ball either based on a max velocity or every time it’s thrown past a certain point. In regards to using impulse, when I started building this I was just firing it with an impulse and it stuck (more due to laziness than anything else 🙂 ), but I’ll revisit with velocity.
      3. Good catch, fixedDeltaUpdate should be in fixedUpdate(). I frequently write these things in the late hours of the night with grand plans to come back, rewrite, fix bugs, edit etc. Then I wake up in the morning and press publish.
      Have a great day!

      Reply

Leave a Reply to SU Cancel reply

Your email address will not be published. Required fields are marked *