The VR Menu navigation
			
			
 Resistance Arena is a VR game where the user attacks by performing upper body exercises with VR controllers instead of pressing buttons. A machine learning algorithm determines if you have performed a given exercise, and gives a score based on how correct the form was.
								
								
									The VR Menu navigation
								
								
									The arm and ray-cast pointer used to interact with the menu
								
								
									The "Fireball" attack cast by performing a bicep curl with one hand
								
								
									The "Fireball" attack colliding with a target practice crate
								
								
									The "Rock Throw" attack cast by performing an overhead press with both hands
								
								
									The "Rock Throw" attack hitting the ground and producing an AOE attack
									
float trigger_left = Input.GetAxis("LeftControllerTrigger");
float trigger_right = Input.GetAxis("RightControllerTrigger");
GameObject hmd = GameObject.Find("VR Camera");
Vector3 hmd_p = hmd.transform.position;
Quaternion hmd_q = hmd.transform.rotation;
// If the user presses either controller's trigger, we start a new gesture.
if (trigger_pressed_left == false && trigger_left > 0.9)
{
	// Controller trigger pressed.
	trigger_pressed_left = true;
	gc.startStroke(Side_Left, hmd_p, hmd_q);
	gesture_started = true;
}
if (trigger_pressed_right == false && trigger_right > 0.9)
{
	// Controller trigger pressed.
	trigger_pressed_right = true;
	gc.startStroke(Side_Right, hmd_p, hmd_q);
	gesture_started = true;
}
if (gesture_started == false)
{
	// nothing to do.
	return;
}
// If we arrive here, the user is currently dragging with one of the controllers.
if (trigger_pressed_left == true)
{
	if (trigger_left < 0.85)
	{
		// User let go of a trigger and held controller still
		gc.endStroke(Side_Left);
		trigger_pressed_left = false;
	}
	else
	{
		// User still dragging or still moving after trigger pressed
		GameObject left_hand = GameObject.Find("Left Hand");
		gc.contdStrokeQ(Side_Left, left_hand.transform.position, left_hand.transform.rotation);
		// Show the stroke by instatiating new objects
		GameObject left_hand_pointer = GameObject.FindGameObjectWithTag("Left Pointer");
	}
}
if (trigger_pressed_right == true)
{
	if (trigger_right < 0.85)
	{
		// User let go of a trigger and held controller still
		gc.endStroke(Side_Right);
		trigger_pressed_right = false;
	}
	else
	{
		// User still dragging or still moving after trigger pressed
		GameObject right_hand = GameObject.Find("Right Hand");
		gc.contdStrokeQ(Side_Right, right_hand.transform.position, right_hand.transform.rotation);
		// Show the stroke by instatiating new objects
		GameObject right_hand_pointer = GameObject.FindGameObjectWithTag("Right Pointer");
	}
}
if (trigger_pressed_left || trigger_pressed_right)
{
	// User still dragging with either hand
	return;
}
// else: if we arrive here, the user let go of both triggers, ending the gesture.
gesture_started = false;
double similarity = -1.0;
int gestureId = gc.identifyGestureCombination(ref similarity);
if (gestureId < 0)
{
	HUDText.text = "Failed to identify gesture";
	return; // something went wrong
}
string gestureName = gc.getGestureCombinationName(gestureId);
if (similarity < /*0.46*/0.3)
{
	HUDText.text = "Gesture not fully recognized\nWere you trying to perform a(n): " + gestureName + "?\nAccuracy Score: " + similarity;
}
else
{
	if (gestureName.Contains("bc"))
	{
		if (gestureName.Contains("left"))
		{
			HUDText.text = "You performed a left-handed bicep curl!";
		}
		else
		{
			HUDText.text = "You performed a right-handed bicep curl!";
		}
		bcStrike.transform.position = new Vector3
			(
				hmd_p.x + (hmd.transform.forward.x * 1.5f),
				hmd_p.y + (hmd.transform.forward.y * 1.5f),
				hmd_p.z + (hmd.transform.forward.z * 1.5f)
			);
		bcStrike.transform.rotation = hmd_q;
		bcStrike.GetComponent().velocity = hmd.transform.forward * 6.5f;
		bcStrike.GetComponent().angularVelocity = new Vector3();
	}
	if (gestureName.Contains("ohp"))
	{
		HUDText.text = "You performed an overhead press!";
		ohpAttack.GetComponent().constraints = RigidbodyConstraints.None;
		ohpAttack.transform.position = new Vector3
			(
				hmd_p.x + (hmd.transform.forward.x * 1.5f),
				hmd_p.y + (hmd.transform.forward.y * 1.5f),
				hmd_p.z + (hmd.transform.forward.z * 1.5f)
			);
		ohpAttack.transform.rotation = hmd_q;
		ohpAttack.GetComponent().velocity = new Vector3
			(
				hmd.transform.forward.x * 4.5f,
				(hmd.transform.forward.y + 5f) * 2f,
				hmd.transform.forward.z * 4.5f
			);
		ohpAttack.GetComponent().angularVelocity = new Vector3(1.5f, 1f, 0f);
	}
}
									     
								
							
									
public class BCStrike : MonoBehaviour
{
	public GameObject explosion;
	void OnCollisionEnter(Collision collision)
	{
		// Place explosion Prefab on impact
		var expl = Instantiate(explosion, gameObject.transform.position, new Quaternion());
		Destroy(expl, 1.0f);
		// Reset the strike's position
		gameObject.transform.rotation = new Quaternion();
		gameObject.transform.position = new Vector3(0, -100f, 0);
		gameObject.GetComponent().velocity = new Vector3(0, 0, 0);
	}
}
									 
								
							
									
public class OHPAttack : MonoBehaviour
{
	public GameObject shockWave;
	public GameObject shockWaveHitBox;
	void OnCollisionEnter(Collision collision)
	{
		// Only handle collisions at ground level AND don't handle collisions with the hitbox
		if (gameObject.transform.position.y < 0.8 && !collision.gameObject.name.Equals("ShockwaveCollision(Clone)"))
		{
			// Place impact effects
			var swPos = new Vector3
				(
					gameObject.transform.position.x,
					0.0f,
					gameObject.transform.position.z
				);
			var sw = Instantiate(shockWave, swPos, new Quaternion());
			Destroy(sw, 1.0f);
			var swHit = Instantiate(shockWaveHitBox, swPos, new Quaternion());
			Destroy(swHit, 1.0f);
			// Freeze rock in place to simulate "landing"
			gameObject.GetComponent().constraints = RigidbodyConstraints.FreezeAll;
		}
	}
}