//Script para controlar el movimiento del Player.
//Necesita que el objeto tenga el script ControlAcelerometro.js
//para bloquearlo en el salto y cambiarle la cuerda sobre la que rotar.
@script RequireComponent(ControlAcelerometro);
//Variables con las rutas de salto y movimiento.
public var cuboAvanzarDerecha : Transform;
public var cuboAvanzarCentro : Transform;
public var cuboAvanzarIzquierda : Transform;
public var cuboCentroIzquierda : Transform;
public var cuboCentroDerecha : Transform;
public var cuboCaidaIzquierda : Transform;
public var cuboCaidaCentroIzquierda : Transform;
public var cuboCaidaDerecha : Transform;
public var cuboCaidaCentroDerecha : Transform;
//Clips de las Animaciones.
public var animacionIdle : AnimationClip;
public var animacionAvanzar : AnimationClip;
public var animacionAvanzarDerecha : AnimationClip;
public var animacionAvanzarIzquierda : AnimationClip;
public var animacionEmpezarSalto : AnimationClip;
public var animacionAcabarSalto : AnimationClip;
public var animacionCaer : AnimationClip;
public var animacionCelebrar : AnimationClip;
//Variable con el Animation del Player.
private var animacion : Animation;
//Velocidades de las Animaciones.
public var velocidadAnimacionAvanzar : float = 1f;
public var velocidadAnimacionesPerderEquilibrio : float = 2f;
public var velocidadAnimacionEmpezarSalto : float = 2f;
//Boleana para saber si estamos acabando el salto.
private var acabandoSalto : boolean = false;
//Variable con la precision del movimiento que tendrá.
private var precisionMovimiento : float = 1f;
//Enums y Clases Globales comentadas, estarán en el Script correspondiente.
//Creamos un enum con las posibles cuerdas en la escena.
//enum Cuerdas
//{
// Ninguna = 0,
// Central = 1,
// Derecha = 2,
// Izquierda = 3
//}
//Creamos una variable del enum Cuerdas para marcar en que cuerda estamos en cada momento.
private var cuerdaActual : Cuerdas = Cuerdas.Central;
private var cuerdaObstaculoVirtual : Cuerdas = Cuerdas.Ninguna;
//Creamos un enum con las posibles caidas con las que se encontrará el Player.
//enum TiposCaida
//{
// Ninguna = 0,
// Fisica = 1,
// Virtual = 2
//}
private var tipoCaida : TiposCaida = TiposCaida.Ninguna;
//Creamos un enum con los posibles estados que tendrá el player.
enum EstadosPlayer{
Idle = 0,
Avanzando = 1,
EmpezandoSaltoDerecha = 2,
SaltandoDerecha = 3,
AcabandoSaltoDerecha = 4,
EmpezandoSaltoIzquierda = 5,
SaltandoIzquierda = 6,
AcabandoSaltoIzquierda = 7,
Cayendo = 8,
Celebrando = 9
}
//Creamos la variable con el estado del Player en cada momento.
private var estadoPlayer : EstadosPlayer = EstadosPlayer.Idle;
//Velocidad de movimiento del Player.
public var velocidadPlayer : float = 1f;
//Incremento que se aplicará a la velocidad cuando estemos en el aire.
public var incrementoVelocidadAire : float = 2f;
//Variable con los fx del player.
public var fxCaida : AudioClip;
public var fxCelebracion : AudioClip;
public var fxSalto : AudioClip;
//Variable con el script del fx manager.
public var scriptFxManager : FxManager;
//Variable para saber si ya hemos lanzado un fx.
private var fxLanzado : boolean = false;
//Variable para saber si hemos lanzado el fx de salto.
private var fxSaltoLanzado : boolean = false;
//Velocidad final de movimiento.
private var velocidadFinal : float = 0f;
//Punto de destino actual.
private var puntoDestino : Vector3 = Vector3.zero;
//Vector con el calculo del Avance en cada momento.
private var vectorAvanzar : Vector3 = Vector3.zero;
//Variable con la espera calculada antes de moverse tras lanzar la animación de saltar.
private var tiempoEspera : float = 0f;
//Variable con el control del acelerometro.
private var controlAcel : ControlAcelerometro;
function Awake (){
//Al iniciar guardamos el componente del acelerometro en una variable.
controlAcel = this.GetComponent("ControlAcelerometro");
//Inicializamos la cuerda, sobre la que rotar, en la cuerda central.
controlAcel.setCuerda(cuboAvanzarCentro);
//Variable con el Animation del Player.
animacion = this.animation;
}
function Update (){
//Actualizamos el puntoDestino cuando haga falta.
ActualizarDestino();
//Actualizamos la velocidad a la que nos desplazamos en cada caso.
ActualizarVelocidades();
//Lanzamos la animación correspondiente en cada caso.
LanzarAnimaciones();
//Aplicamos el movimiento al Player.
this.transform.position += vectorAvanzar * velocidadFinal * Time.deltaTime;
}
//Función para actualizar el punto de destino del Player.
function ActualizarDestino(){
//Valoramos en que estado esta el Player para saber que actualización aplicar.
switch(estadoPlayer){
//Si tenemos que avanzar por una cuerda
case EstadosPlayer.Avanzando:
//Si no tenemos punto al que ir
if(puntoDestino == Vector3.zero){
//Cambiamos el punto al que ir según la cuerda en la que estemos.
switch(cuerdaActual){
case Cuerdas.Central:
puntoDestino = cuboAvanzarCentro.position;
break;
case Cuerdas.Derecha:
puntoDestino = cuboAvanzarDerecha.position;
break;
case Cuerdas.Izquierda:
puntoDestino = cuboAvanzarIzquierda.position;
break;
}
}
//Si ya tenemos un punto al que ir y hemos llegado, vaciamos el punto de destino para el siguiente Update.
else if(Vector3.Distance(puntoDestino, this.transform.position) <= precisionMovimiento){
puntoDestino = Vector3.zero;
}
break;
case EstadosPlayer.EmpezandoSaltoDerecha:
//Si no tenemos punto al que ir
if(puntoDestino == Vector3.zero){
//Cambiamos el punto al que ir según la cuerda en la que estemos.
switch(cuerdaActual){
case Cuerdas.Central:
puntoDestino = cuboAvanzarCentro.position;
break;
case Cuerdas.Derecha:
puntoDestino = cuboAvanzarDerecha.position;
break;
case Cuerdas.Izquierda:
puntoDestino = cuboAvanzarIzquierda.position;
break;
}
}
//Si ya tenemos un punto al que ir y hemos llegado, vaciamos el punto de destino para el siguiente Update.
else if(Vector3.Distance(puntoDestino, this.transform.position) <= precisionMovimiento){
puntoDestino = Vector3.zero;
}
//Si no tenemos un tiempo de espera, lo inicializamos a lo que toque.
if(tiempoEspera == 0){
animacion.Rewind(animacionEmpezarSalto.name);
tiempoEspera = Time.time + animacion[animacionEmpezarSalto.name].length/velocidadAnimacionEmpezarSalto;
}
//Si tenemos tiempo de espera y ha pasado, cambiamos el estado a saltando y reinicializamos el tiempo.
else if(tiempoEspera < Time.time){
this.SetEstado(EstadosPlayer.SaltandoDerecha);
tiempoEspera = 0f;
}
break;
case EstadosPlayer.SaltandoDerecha:
//Si no tenemos punto al que ir
if(puntoDestino == Vector3.zero){
//Cambiamos el punto al que ir según la cuerda en la que estemos.
switch(cuerdaActual){
case Cuerdas.Central:
puntoDestino = cuboCentroDerecha.position;
break;
case Cuerdas.Izquierda:
puntoDestino = cuboCentroIzquierda.position;
break;
}
}
//Si ya tenemos un punto al que ir y hemos llegado, vaciamos el punto de destino para el siguiente Update.
else if(Vector3.Distance(puntoDestino, this.transform.position) <= precisionMovimiento){
puntoDestino = Vector3.zero;
estadoPlayer = EstadosPlayer.AcabandoSaltoDerecha;
}
break;
case EstadosPlayer.AcabandoSaltoDerecha:
//Si no tenemos punto al que ir
if(puntoDestino == Vector3.zero){
//Cambiamos el punto al que ir según la cuerda en la que estemos.
switch(cuerdaActual){
case Cuerdas.Central:
puntoDestino = cuboAvanzarDerecha.position;
break;
case Cuerdas.Izquierda:
puntoDestino = cuboAvanzarCentro.position;
break;
}
}
//Si ya tenemos un punto al que ir y hemos llegado.
else if(Vector3.Distance(puntoDestino, this.transform.position) <= precisionMovimiento){
//Cambiamos la cuerda en la que estamos.
switch(cuerdaActual){
case Cuerdas.Central:
cuerdaActual = Cuerdas.Derecha;
controlAcel.setCuerda(cuboAvanzarDerecha);
break;
case Cuerdas.Izquierda:
cuerdaActual = Cuerdas.Central;
controlAcel.setCuerda(cuboAvanzarCentro);
break;
}
//Cambiamos el estado a Avanzando y le ponemos el punto a 0 para
//que en la próxima vuelta reconozca a que punto ir.
puntoDestino = Vector3.zero;
estadoPlayer = EstadosPlayer.Avanzando;
acabandoSalto = true;
}
break;
case EstadosPlayer.EmpezandoSaltoIzquierda:
//Si no tenemos punto al que ir
if(puntoDestino == Vector3.zero){
//Cambiamos el punto al que ir según la cuerda en la que estemos.
switch(cuerdaActual){
case Cuerdas.Central:
puntoDestino = cuboAvanzarCentro.position;
break;
case Cuerdas.Derecha:
puntoDestino = cuboAvanzarDerecha.position;
break;
case Cuerdas.Izquierda:
puntoDestino = cuboAvanzarIzquierda.position;
break;
}
}
//Si ya tenemos un punto al que ir y hemos llegado, vaciamos el punto de destino para el siguiente Update.
else if(Vector3.Distance(puntoDestino, this.transform.position) <= precisionMovimiento){
puntoDestino = Vector3.zero;
}
//Si no tenemos un tiempo de espera, lo inicializamos a lo que toque.
if(tiempoEspera == 0){
animacion.Rewind(animacionEmpezarSalto.name);
tiempoEspera = Time.time + animacion[animacionEmpezarSalto.name].length/velocidadAnimacionEmpezarSalto;
}
//Si tenemos tiempo de espera y ha pasado, cambiamos el estado a saltando y reinicializamos el tiempo.
else if(tiempoEspera < Time.time){
this.SetEstado(EstadosPlayer.SaltandoIzquierda);
tiempoEspera = 0f;
}
break;
case EstadosPlayer.SaltandoIzquierda :
//Si no tenemos punto al que ir
if(puntoDestino == Vector3.zero){
//Cambiamos el punto al que ir según la cuerda en la que estemos.
switch(cuerdaActual){
case Cuerdas.Central:
puntoDestino = cuboCentroIzquierda.position;
break;
case Cuerdas.Derecha:
puntoDestino = cuboCentroDerecha.position;
break;
}
}
//Si ya tenemos un punto al que ir y hemos llegado, vaciamos el punto de destino para el siguiente Update.
else if(Vector3.Distance(puntoDestino, this.transform.position) <= precisionMovimiento){
puntoDestino = Vector3.zero;
estadoPlayer = EstadosPlayer.AcabandoSaltoIzquierda;
}
break;
case EstadosPlayer.AcabandoSaltoIzquierda:
//Si no tenemos punto al que ir
if(puntoDestino == Vector3.zero){
//Cambiamos el punto al que ir según la cuerda en la que estemos.
switch(cuerdaActual){
case Cuerdas.Central:
puntoDestino = cuboAvanzarIzquierda.position;
break;
case Cuerdas.Derecha:
puntoDestino = cuboAvanzarCentro.position;
break;
}
}
//Si ya tenemos un punto al que ir y hemos llegado.
else if(Vector3.Distance(puntoDestino, this.transform.position) <= precisionMovimiento){
//Cambiamos la cuerda en la que estamos.
switch(cuerdaActual){
case Cuerdas.Central:
cuerdaActual = Cuerdas.Izquierda;
controlAcel.setCuerda(cuboAvanzarIzquierda);
break;
case Cuerdas.Derecha:
cuerdaActual = Cuerdas.Central;
controlAcel.setCuerda(cuboAvanzarCentro);
break;
}
//Cambiamos el estado a Avanzando y le ponemos el punto a 0 para
//que en la próxima vuelta reconozca a que punto ir.
puntoDestino = Vector3.zero;
estadoPlayer = EstadosPlayer.Avanzando;
acabandoSalto = true;
}
break;
case EstadosPlayer.Cayendo:
//Si no tenemos punto al que ir
if(puntoDestino == Vector3.zero){
switch(tipoCaida){
case TiposCaida.Fisica:
//Calculamos cual es la distancia más corta que hay entre el Player y alguno de los Cubos de caída.
var distanciaMinima : float = Mathf.Min(
Vector3.Distance(cuboCaidaCentroDerecha.position, this.transform.position),
Vector3.Distance(cuboCaidaCentroIzquierda.position, this.transform.position)
);
//Comprobamos a que cubo corresponde dicha distancia.
switch(distanciaMinima){
case Vector3.Distance(cuboCaidaCentroDerecha.position, this.transform.position):
puntoDestino = cuboCaidaCentroDerecha.position;
break;
case Vector3.Distance(cuboCaidaCentroIzquierda.position, this.transform.position):
puntoDestino = cuboCaidaCentroIzquierda.position;
break;
}
//Si estamos en una de las cuerdas de los laterales y el Player
//esta inclinado hacia fuera, caemos por los laterales exteriores.
if(this.transform.eulerAngles.z > 180 && cuerdaActual == Cuerdas.Derecha){
puntoDestino = cuboCaidaDerecha.position;
}
else if(this.transform.eulerAngles.z < 180 && cuerdaActual == Cuerdas.Izquierda){
puntoDestino = cuboCaidaIzquierda.position;
}
break;
case TiposCaida.Virtual:
//Si la caida es virtual y estamos en la misma cuerda del obstaculo
//caemos hacia delante.
if(cuerdaActual == cuerdaObstaculoVirtual){
puntoDestino.z = this.transform.position.z + 30;
}
else{
//Si la cuerda es distinta a la que estamos.
switch(cuerdaActual){
//En caso de que partamos de la cuerda central.
case Cuerdas.Central:
//Si vamos a la derecha caeremos por el límite derecho.
if(cuerdaObstaculoVirtual == Cuerdas.Derecha){
puntoDestino = cuboCaidaDerecha.position;
}
//Si vamos a la izquierda caeremos por el límite izquierdo.
else{
puntoDestino = cuboCaidaIzquierda.position;
}
break;
//Si partimos de cualquier otra cuerda la de destino será la central.
default:
//Calculamos cual es la distancia más larga que hay entre el Player y alguno de los Cubos de caída para que de el efecto de continuar el salto pasandose de largo.
var distanciaMaxima : float = Mathf.Max(
Vector3.Distance(cuboCaidaDerecha.position, this.transform.position),
Vector3.Distance(cuboCaidaIzquierda.position, this.transform.position)
);
//Comprobamos a que cubo corresponde dicha distancia.
switch(distanciaMaxima){
case Vector3.Distance(cuboCaidaDerecha.position, this.transform.position):
puntoDestino = cuboCaidaDerecha.position;
break;
case Vector3.Distance(cuboCaidaIzquierda.position, this.transform.position):
puntoDestino = cuboCaidaIzquierda.position;
break;
}
break;
}
}
break;
}
}
break;
}
}
//Función para actualizar la velocidad que llevará el Player.
function ActualizarVelocidades(){
//Si tenemos un punto de destino.
if(puntoDestino != Vector3.zero){
//Calculamos el vector con el que avanzar y lo normalizamos.
vectorAvanzar = puntoDestino - this.transform.position;
vectorAvanzar.Normalize();
//Hacemos que la velocidad final sea la velocidad del Player.
velocidadFinal = velocidadPlayer;
//Comprobamos si necesitamos cambiar la velocidad en función del estado en el que este el Player.
switch(estadoPlayer){
case EstadosPlayer.SaltandoDerecha:
case EstadosPlayer.SaltandoIzquierda:
//Probando valores para suavizar el salto con 4 y 5 buenos resultados.
//Al avanzar más rápida la Y de lo normal provocamos que, con las correcciones del normalizado al punto de destino,
//se cree una parábola en los saltos.
vectorAvanzar.y *= 4;
//Velocidad Incrementada en salto
velocidadFinal += incrementoVelocidadAire;
break;
case EstadosPlayer.AcabandoSaltoDerecha:
case EstadosPlayer.AcabandoSaltoIzquierda:
//Volvemos a velocidad normal de caida, para más naturalidad,
//al reducir la distancia en X al punto de destino.
if(Mathf.Abs(vectorAvanzar.x) > 0.7){
//Probando valores para suavizar la caida con 1/4 o 1/3 buenos resultados.
//Al avanzar más lenta la Y de lo normal provocamos que, con las correcciones del normalizado al punto de destino,
//cree una parábola en las caidas.
//vectorAvanzar.y *= 0.33;
vectorAvanzar.y *= 0.25;
}
//Velocidad Incrementada en caida
velocidadFinal += incrementoVelocidadAire;
break;
case EstadosPlayer.Cayendo:
//Velocidad Incrementada en caida
velocidadFinal += incrementoVelocidadAire;
break;
}
}
else{
vectorAvanzar = Vector3.zero;
velocidadFinal = 0f;
}
}
//Función para lanzar la animación que toque en cada caso.
function LanzarAnimaciones(){
//Valoramos en que estado esta el Player para saber que animación lanzar.
switch(estadoPlayer){
case EstadosPlayer.Idle:
animacion.CrossFade(animacionIdle.name);
break;
case EstadosPlayer.Avanzando:
fxSaltoLanzado = false;
if(acabandoSalto){
acabandoSalto = false;
animacion[animacionAcabarSalto.name].layer = 1;
animacion.CrossFade(animacionAcabarSalto.name);
}
else{
var anguloMaximo : float = controlAcel.GetAnguloMaximo();
if(this.transform.eulerAngles.z > anguloMaximo/2 && this.transform.eulerAngles.z < anguloMaximo){
animacion[animacionAvanzarIzquierda.name].speed = velocidadAnimacionesPerderEquilibrio;
animacion.CrossFade(animacionAvanzarIzquierda.name);
}
else if(this.transform.eulerAngles.z < 360 - anguloMaximo/2 && this.transform.eulerAngles.z > 360 - anguloMaximo){
animacion[animacionAvanzarDerecha.name].speed = velocidadAnimacionesPerderEquilibrio;
animacion.CrossFade(animacionAvanzarDerecha.name);
}
else{
animacion[animacionAvanzar.name].speed = velocidadAnimacionAvanzar;
animacion.CrossFade(animacionAvanzar.name);
}
}
break;
case EstadosPlayer.Cayendo:
//Si aun no hemos lanzado el fx, lo lanzamos.
if(!fxLanzado){
//Lanzamos el sonido de la caida al caernos.
scriptFxManager.ActivarFX(fxCaida);
//Cambiamos la booleana a sonido lanzado.
fxLanzado = true;
}
animacion.CrossFade(animacionCaer.name);
break;
case EstadosPlayer.EmpezandoSaltoDerecha:
case EstadosPlayer.SaltandoDerecha:
case EstadosPlayer.EmpezandoSaltoIzquierda:
case EstadosPlayer.SaltandoIzquierda:
animacion[animacionEmpezarSalto.name].speed = velocidadAnimacionEmpezarSalto;
animacion.CrossFade(animacionEmpezarSalto.name);
//Si aun no hemos lanzado el fx, lo lanzamos.
if(!fxSaltoLanzado){
//Lanzamos el sonido de la celebración al llegar al final.
scriptFxManager.ActivarFX(fxSalto);
//Cambiamos la booleana a sonido lanzado.
fxSaltoLanzado = true;
}
break;
case EstadosPlayer.Celebrando:
//Si aun no hemos lanzado el fx, lo lanzamos.
if(!fxLanzado){
//Lanzamos el sonido de la celebración al llegar al final.
scriptFxManager.ActivarFX(fxCelebracion);
//Cambiamos la booleana a sonido lanzado.
fxLanzado = true;
}
animacion.CrossFade(animacionCelebrar.name);
break;
}
}
//----- Sets ---------
//Cambiamos el estado del Player y reseteamos su punto de destino.
public function SetEstado( nuevoEstado : EstadosPlayer){
estadoPlayer = nuevoEstado;
puntoDestino = Vector3.zero;
}
//Marca al player en caída con identificador para objeto físico o virtual.
public function SetCaida( caida : TiposCaida){
this.SetEstado(EstadosPlayer.Cayendo);
tipoCaida = caida;
}
//Sobrecarga para que cuando sea virtual marquemos en que cuerda esta el obstaculo.
public function SetCaida( caida : TiposCaida, cuerda : Cuerdas){
this.SetEstado(EstadosPlayer.Cayendo);
tipoCaida = caida;
cuerdaObstaculoVirtual = cuerda;
}
//------ Gets ---------
//Enviamos el estado del Player.
public function GetEstado() : EstadosPlayer
{
return estadoPlayer;
}
//Enviamos la Cuerda Actual en la que estamos.
public function GetCuerda() : Cuerdas
{
return cuerdaActual;
}