Build a Fruit Ninja Game Mechanic In Daydream VR

Daydream VR

In this tutorial we’ll build a simple Fruit Ninja style game mechanic in Daydream VR. It follows on from my previous post where we built a simple laser pointer using the the Daydream Controller API. I call this game Fruit Slicer and apart from being a very straight forward game mechanic to build it is also very much an unfinished game. Feel free to take it and turn it into something that terrifies your grandmother!

Update (01/08/17): This tutorial was originally written using a pre-release version of the Daydream Unity SDK. The code in the tut is still totally valid and works, but the linked Unity package uses an older SDK so may not run in newer 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 mechanic is basically this: we fire GameObjects in front of the player, the player then tries to hit the objects with a laser pointer before they land on the ground. GameObjects are Destroyed when they either hit the ground or are hit by the laser pointer.

To get started download the finished Unity package here, import it into a new Unity project and open the FruitSlicer scene. This package was built before native support for Daydream VR was announced, so it uses the GVR prefab. As of writing (September 2016) Daydream hasn’t been released, to get it running on a phone you’ll need a Nexus 6P and another Android phone running the controller emulator (see my previous tutorial on setting this up here).

After installing the package you’ll notice in the Resources folder I’ve created a prefab called Fruit. Attached to the Fruit prefab is a RigidBody component so that it is affected by the gravity in the scene – with the Use Gravity toggle on. I’ve also added a script on the Fruit prefab that listens for a collision with the ground and removes itself.

There are only a few additions to the code from the previous laser pointer tut. At line 32 we use an Impulse force on the RigidBody to launch the fruit from a random position along the x axis Then at line 49 in our ShootLaserFromTargetPosition method we ray cast along the length of our pointer, if it crosses a gameObject and that gameObject has the tag “FruitTag” we Destroy it.

using UnityEngine;
using System.Collections;

public class ControllerManagerScript : MonoBehaviour {

	public LineRenderer laser;
	public Transform fruit;

	private int num;
	private Vector3 launchPoint;

	void Start () {
		Vector3[] initLaserPositions = new Vector3[ 2 ] { Vector3.zero, Vector3.zero };
		laser.SetPositions( initLaserPositions );
		laser.SetWidth( 0.01f, 0.01f );

		launchPoint = new Vector3 (0.0f, 1.0f, -2.0f);

		num = 0;
	}
	
	void Update () {
		Quaternion ori = GvrController.Orientation;
		gameObject.transform.localRotation = ori;

		Vector3 v = GvrController.Orientation * Vector3.forward;

		ShootLaserFromTargetPosition( transform.position, v, 200f );
		laser.enabled = true;

		// Launch fruit
		if (num > 40) {
			launchPoint.x = Random.Range (-4.0f, 4.0f);
			GameObject fruitObj = (GameObject)Instantiate (Resources.Load ("Fruit"));
			fruitObj.transform.position = launchPoint;
			Rigidbody rb = fruitObj.GetComponent<Rigidbody>();
			rb.AddForce (0, 10, -3.0f, ForceMode.Impulse);
			num = 0;
		}
		num++;
	}

	void ShootLaserFromTargetPosition( Vector3 targetPosition, Vector3 direction, float length )
	{
		Ray ray = new Ray( targetPosition, direction );
		RaycastHit raycastHit;

		// Test if laser pointer has hit fruit
		if( Physics.Raycast( ray, out raycastHit, length ) ) {
			GameObject fruitObject = raycastHit.transform.gameObject;
			if (fruitObject.tag == "FruitTag") {
				Destroy (raycastHit.transform.gameObject);
			}
		}

		Vector3 endPosition = targetPosition + ( length * direction );
		laser.SetPosition( 0, targetPosition );
		laser.SetPosition( 1, endPosition );
	}
}

And this is the class attached to the fruit gameObject. It checks for a collision with the ground and destroys itself if true.

using UnityEngine;
using System.Collections;

public class FruitScript : MonoBehaviour {

	private void OnCollisionEnter(Collision collision)
	{
		if ( collision.gameObject.tag == "GroundTag" )
		{
			Destroy(gameObject);
		}
	}
}

Currently the Controller only has rotational movement around its origin. A fun addition to the mechanic would be to slight X,Y,Z movement on the controller based on its tilt or acceleration. Exploring an elbow joint locking mechanism would also add some more realistic movement and feel less as thought the controller is fixed in space – and splitting the fruit when hit would be a big improvement too 🙂

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.

Leave a Reply

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