@@ -0,0 +1,66 @@
using UnityEngine;
using System.Collections;
using System.Collections.Generic;

public class TitleState : State<TitleController>
{
private int Selection;
private Transform SelectionTransform;
private List<Transform> MenuTransforms;
private bool _axisUsed;

public TitleState (TitleController c, Transform s, List<Transform> m) : base(c)
{
SelectionTransform = s;
MenuTransforms = m;
}

//Show the title screen
public override void Enter()
{
SelectionTransform.gameObject.SetActive (true);
MenuTransforms.ForEach(m => m.gameObject.SetActive(true));
}

public override bool Handle()
{
//Handle title choices
if(Input.GetButtonDown("Submit") || Input.GetKeyDown(KeyCode.Return))
{
switch(Selection)
{
case 0:
_client.GotoTransition();
break;
case 1:
Application.Quit();
return true;
}
}

//Handle selection switching
float y = Input.GetAxis ("Vertical");
if (y == 0)
_axisUsed = false;
else
{
//Only use vertical press once until reset
if(_axisUsed)
return true;
_axisUsed = true;
//Convert input to 1 or -1
Selection -= (int) Mathf.Sign(y);

//Wrap selection around the top and bottom
if(Selection >= MenuTransforms.Count)
Selection = 0;
if (Selection < 0)
Selection = MenuTransforms.Count - 1;
//Put the selection transform slightly behind the menu choice
SelectionTransform.position = MenuTransforms[Selection].position;
SelectionTransform.Translate(0, -0.1f, 0);
}

return true;
}
}
@@ -0,0 +1,71 @@
using UnityEngine;
using System.Collections;
using System.Collections.Generic;
using UnityStandardAssets.Characters.FirstPerson;

public class TransitionState : State<TitleController>
{
private Transform _target;
private Transform _mover;
private float _damping = 3;
private float _startDist;
private Quaternion _startRot;
public bool _started = false;

public TransitionState (TitleController c) : base(c)
{
_target = GameObject.FindGameObjectWithTag("Player").transform;
_mover = _client.transform.FindChild ("Camera");
}

public override void Enter()
{
//When transitioning, double rotation speed
_client.RotPerSecond *= 2f;
}

public override bool Handle()
{
//Before we can start, make sure the camera isn't behind the mountain
if (!_started)
{
//Between these angles is the mountain. Only start when NOT behind them.
if (_client.Angle < 94 || _client.Angle > 163)
{
_mover.SetParent (null);
_startDist = Vector3.Distance (_mover.position, _target.position);
_startRot = _mover.rotation;
_started = true;
}
return true;
}

//Until the camera is close enough, keep moving towards it
float dist = Vector3.Distance (_mover.position, _target.position);
if (dist > 0.2f)
{
//Damping is used for smooth movement, basically, it moves a set
//amount of the distance every second.
Vector3 dir = (_target.position - _mover.position) / _damping;
//Because near the end it would move very slow, a fixed amount is added
_mover.position = _mover.position + (dir + dir.normalized * 2) * Time.deltaTime;
//Smoothly rotate the camera to be looking at the same direction as the target
_mover.rotation = Quaternion.Lerp(_startRot, _target.rotation, 1 - 1 / _startDist * dist);

return true;
}

//Turn off the title objects
_mover.gameObject.SetActive (false);
_client.gameObject.SetActive (false);

//Unlock the player controller and turn on the camera
var rfpc = _target.GetComponent<RigidbodyFirstPersonController> ();
rfpc.MouseLocked = false;
rfpc.LockedInput = false;
_target.GetComponent<PlayerController> ().enabled = true;
_target.transform.FindChild ("MainCamera").gameObject.SetActive (true);

return true;
}
}
@@ -0,0 +1,96 @@
using UnityEngine;
using UnityEngine.VR;
using System.Collections;
using System.Collections.Generic;

public class TitleController : MonoBehaviour {
public GameObject RecenterText;
public Transform Logo;
public Transform Selection;
public List<Transform> Menu;
public Material FadeMaterial;
public Transform Center;
public float RotPerSecond = 7;
public float Angle;

private StateMachine<TitleController> _states;
private float DistanceToCenter;

void Start () {
//Instantiate and set all the states
_states = new StateMachine<TitleController> ();
RecenterState recenterState = new RecenterState (this, RecenterText);
TitleState titleState = new TitleState (this, Selection, Menu);
TransitionState transState = new TransitionState (this);
_states.Add (recenterState);
_states.Add (titleState);
_states.Add (transState);
_states.Set ("RecenterState");

DistanceToCenter = Vector3.Distance (transform.position, Center.position);
}

// Let the states handle the update
void Update () {
_states.GetCurState ().Handle ();
}

void FixedUpdate()
{
//Rotate around center
Angle += Time.deltaTime * RotPerSecond; //Increase the angle
Angle %= 360;
var dir = Quaternion.AngleAxis(Angle, Vector3.forward) * Vector3.right; //Get a Vector based on the angle
dir.z = dir.y;
dir.y = 0;
transform.position = Center.position + dir * DistanceToCenter;
transform.LookAt (Center);
}

//Change state to transition
public void GotoTransition()
{
//Hide the title screen
Selection.gameObject.SetActive (false);
Menu.ForEach(m => m.gameObject.SetActive(false));
Logo.gameObject.SetActive (false);
_states.Set ("TransitionState");
}

/// <summary>
/// Fade out the screen to seemlessly recenter the VR
/// </summary>
IEnumerator Recenter()
{
float stepA = 1f * (1f / 60f); //Amount of alpha to add every frame
Color c = FadeMaterial.color;

//Fade to black
while(c.a < 1f)
{
c.a += stepA;
FadeMaterial.color = c;
yield return new WaitForSeconds(1f/60f);
}

//Round off color
c.a = 1f;
FadeMaterial.color = c;

//Recenter VR
InputTracking.Recenter ();

//Change state to bring up the title
_states.Set ("TitleState");

//Remove fade
while(c.a > 0)
{
c.a -= stepA;
FadeMaterial.color = c;
yield return new WaitForSeconds(1f/60f);
}
c.a = 0f;
FadeMaterial.color = c;
}
}