Jump to content
Sign in to follow this  
croviman

AYUDA! Muerte al caer de un lugar muy alto.

Recommended Posts

Hola compañeros! Quería saber si alguien me puede dar una mano en esto... Hace mas de un año que inicié mi proyecto y ya falta menos para sacar una demo, pero un problema que nunca pude subsanar es justamente este: Para que la jugabilidad de mi proyecto tenga un poco más de desafío y entretenimiento, necesito hacer que el player muera si cae desde una altura lo suficientemente elevada... El tema es que no tengo idea de como lograrlo.... Alguien me da una mano?

Share this post


Link to post
Share on other sites

Hola @croviman para calcular el daño de la caída, deberías conocer la velocidad en la que el personaje se mueve verticalmente cuando es afectado directamente con la gravedad, de ese modo podrías calcular mediante el tiempo la distancia que recorrió.

Entonces, cuando el jugador deja de tener contacto con el suelo y la velocidad en Y es a favor de la gravedad entonces empiezas a tomar el tiempo, cuando el jugador vuelve a tener contacto con el suelo puedes tener un aproximado de la distancia de caida. 

Otra forma seria, una vez que el jugador deja de tocar el suelo obtienes el valor de Y de la posición, cuando vuelve a tocar el suelo evaluas la diferencia de Y actual con el Y tomado al momento de saltar.

Share this post


Link to post
Share on other sites
4 minutes ago, francoe1 said:

Hola @croviman para calcular el daño de la caída, deberías conocer la velocidad en la que el personaje se mueve verticalmente cuando es afectado directamente con la gravedad, de ese modo podrías calcular mediante el tiempo la distancia que recorrió.

Entonces, cuando el jugador deja de tener contacto con el suelo y la velocidad en Y es a favor de la gravedad entonces empiezas a tomar el tiempo, cuando el jugador vuelve a tener contacto con el suelo puedes tener un aproximado de la distancia de caida. 

Otra forma seria, una vez que el jugador deja de tocar el suelo obtienes el valor de Y de la posición, cuando vuelve a tocar el suelo evaluas la diferencia de Y actual con el Y tomado al momento de saltar.

Son excelentes ideas GRACIAS!... pero no sabría como ejecutarlas ya que no se traducir todo eso a un script... 

Share this post


Link to post
Share on other sites
10 hours ago, croviman said:

Son excelentes ideas GRACIAS!... pero no sabría como ejecutarlas ya que no se traducir todo eso a un script... 

A continuación te dejo un pedazo de codigo que lo tenes que pegar en el script del player.

public float TiempoEnElAire;
public int ValorCaida; //Valor tope.
public bool EstaEnElAire;


public void Update ()
{
  if (EstaEnElAire == true)
  {
  TiempoEnElAire = 2 * Time.deltaTime; // Va haciendo un conteo multiplicado x2. Podes cambiar el numero para que vaya mas rapido.
  } else 
  {
    TiempoEnElAire = 0; // El valor vuelve a 0 sin deltaTime. ya que EstaEnElAire es FALSE.
  }
  
 
}

public void OnCollisionEnter2D(Collision2D collision)
{
if (collision.gameObject.tag == "Suelo") //Agregar tag al Suelo.
{
	if (EstaEnElAire == true)
    {
 if (TiempoEnElAire >= ValorCaida) //Si TiempoEnElAire es mayor o igual a ValorCaida. se ejecuta la acción.
  {
  Destroy(gameObject);
    //Aca dentro rellenas lo que queres.
  }
      EstaEnElAire = false;
    } else if (collision.gameObject.tag != "Suelo")
    {
    EstaEnElAire = true;
    }
}
  

ValorCaida es el numero para cuando empiece a dar efecto lo que queres llevar acabo.

Espero que te haya servido de referencia. 

Share this post


Link to post
Share on other sites
On 7/10/2021 at 4:04 AM, stztek said:

A continuación te dejo un pedazo de codigo que lo tenes que pegar en el script del player.


public float TiempoEnElAire;
public int ValorCaida; //Valor tope.
public bool EstaEnElAire;


public void Update ()
{
  if (EstaEnElAire == true)
  {
  TiempoEnElAire = 2 * Time.deltaTime; // Va haciendo un conteo multiplicado x2. Podes cambiar el numero para que vaya mas rapido.
  } else 
  {
    TiempoEnElAire = 0; // El valor vuelve a 0 sin deltaTime. ya que EstaEnElAire es FALSE.
  }
  
 
}

public void OnCollisionEnter2D(Collision2D collision)
{
if (collision.gameObject.tag == "Suelo") //Agregar tag al Suelo.
{
	if (EstaEnElAire == true)
    {
 if (TiempoEnElAire >= ValorCaida) //Si TiempoEnElAire es mayor o igual a ValorCaida. se ejecuta la acción.
  {
  Destroy(gameObject);
    //Aca dentro rellenas lo que queres.
  }
      EstaEnElAire = false;
    } else if (collision.gameObject.tag != "Suelo")
    {
    EstaEnElAire = true;
    }
}
  

ValorCaida es el numero para cuando empiece a dar efecto lo que queres llevar acabo.

Espero que te haya servido de referencia. 

Que grande! Un abrazo fuerte!! Muchas gracias!! Cuando disponga de tiempo lo voy a probar y te cuento. 

Share this post


Link to post
Share on other sites

el  bool ["EstaEnElAire"]  va en el Animator en la parte de parametros por las dudas te aviso., obvio que va en la animacion de salto nose como tenes compuesto las animaciones pero si tenes las animaciones en 3 estado que son EJ: fuerza de salto o impulso, salto, Aterrisaje., lo tenes que poner en salto.

  • Like 1

Share this post


Link to post
Share on other sites
3 hours ago, Fabri15544 said:

el  bool ["EstaEnElAire"]  va en el Animator en la parte de parametros por las dudas te aviso., obvio que va en la animacion de salto nose como tenes compuesto las animaciones pero si tenes las animaciones en 3 estado que son EJ: fuerza de salto o impulso, salto, Aterrisaje., lo tenes que poner en salto.

Por eso agregué el bool directamente al script ya que no sabia si lo tenia armado el sistema de animación 😛 gracias por aclararlo.

  • Like 1

Share this post


Link to post
Share on other sites
On 7/12/2021 at 2:29 PM, stztek said:

Por eso agregué el bool directamente al script ya que no sabia si lo tenia armado el sistema de animación 😛 gracias por aclararlo.

Hola! He estado probando el script y me da el siguiente error rojo en la consola: Assets\Scripts\MuerteCaida.cs(39,2): error CS1513: } expected

Lo creé como un script independiente y pensaba ponerlo en el FPS Controller  bautizado como "MuerteCaida"... Pero no me lo permite...

No entiendo bien si debería ponerlo dentro del script que maneja los movimientos del jugador y tampoco comprendo que es eso de el "bool va en el animador" (mi juego es en primera persona y ni idea si usa animaciones.... creo que no...)

Disculpen mi nivel tan lamentable... lo mío es lo artístico y estoy intentando crear una experiencia inmersiva de arte interactivo un tanto surrealista... Vengo de Entidad 3D tratando de adaptarme a Unity y dispongo de poco tiempo libre... 

Aquí dejo el script que maneja al player por si les sirve de algo:

Spoiler

 

No es mucho... pero toda colaboración irá en los créditos del juego. Poco a poco con su ayuda esto va tomando forma! GRACIAS!!!!

Share this post


Link to post
Share on other sites
On 7/14/2021 at 12:11 AM, croviman said:

Hola! He estado probando el script y me da el siguiente error rojo en la consola: Assets\Scripts\MuerteCaida.cs(39,2): error CS1513: } expected

Lo creé como un script independiente y pensaba ponerlo en el FPS Controller  bautizado como "MuerteCaida"... Pero no me lo permite...

No entiendo bien si debería ponerlo dentro del script que maneja los movimientos del jugador y tampoco comprendo que es eso de el "bool va en el animador" (mi juego es en primera persona y ni idea si usa animaciones.... creo que no...)

Disculpen mi nivel tan lamentable... lo mío es lo artístico y estoy intentando crear una experiencia inmersiva de arte interactivo un tanto surrealista... Vengo de Entidad 3D tratando de adaptarme a Unity y dispongo de poco tiempo libre... 

Aquí dejo el script que maneja al player por si les sirve de algo:

Spoiler

 

No es mucho... pero toda colaboración irá en los créditos del juego. Poco a poco con su ayuda esto va tomando forma! GRACIAS!!!!

Creo que se me olvido agregar un "}" al final de OnCollisionEnter2D() JAJAJA

 

yo te diria que lo agregues al mismo script, tene una copia de seguridad para no perder lo que ya esta hecho.

ademas asi te olvidas del bool "estaenelaire", en ese caso utilizarias "m_Jumping"

Share this post


Link to post
Share on other sites
On 7/14/2021 at 10:28 AM, stztek said:

Creo que se me olvido agregar un "}" al final de OnCollisionEnter2D() JAJAJA

 

yo te diria que lo agregues al mismo script, tene una copia de seguridad para no perder lo que ya esta hecho.

ademas asi te olvidas del bool "estaenelaire", en ese caso utilizarias "m_Jumping" 

Perdón mi incompetencia, pero no logro hacer que el error desaparezca. Exactamente donde va el "}"?

Otra consulta... se pueden agregar diversos TAGs para el piso? Porque tengo un sistema de sonidos de pasos que utilizan muchos TAGs diferentes segun la superficie que el jugador pisa. En caso afirmativo: Que debería poner en el código para que funcione con varios TAGs?

Edited by croviman

Share this post


Link to post
Share on other sites
23 minutes ago, croviman said:

Perdón mi incompetencia, pero no logro hacer que el error desaparezca. Exactamente donde va el "}"?

Otra consulta... se pueden agregar diversos TAGs para el piso? Porque tengo un sistema de sonidos de pasos que utilizan muchos TAGs diferentes segun la superficie que el jugador pisa. En caso afirmativo: Que debería poner en el código para que funcione con varios TAGs?

abajo de 

  EstaEnElAire = true;

(Como se te dijo antes, reemplaza el Booleano EstaEnElAire por el que usas para detectar CUANDO el player esta en el aire)

 

Respecto a los Tags, yo te recomendaria reemplazarlo por enum. vas agregando una "lista".. ej:

public enum MaterialPiso
{
Tierra, Pasto, Madera, Metal.
}
MaterialPiso MatePiso;


// Formas de llamarlo

public void PisoTierra()
{
MatePiso = MaterialPiso.Tierra;
}

 

Realmente nose como ayudarte de ahora en mas, ya que no se en que entorno se basa el juego.. 3d o 2d? Como funciona el sistema de sonido que decis?

 

Share this post


Link to post
Share on other sites
23 hours ago, stztek said:

abajo de 


  EstaEnElAire = true;

(Como se te dijo antes, reemplaza el Booleano EstaEnElAire por el que usas para detectar CUANDO el player esta en el aire)

 

Respecto a los Tags, yo te recomendaria reemplazarlo por enum. vas agregando una "lista".. ej:


public enum MaterialPiso
{
Tierra, Pasto, Madera, Metal.
}
MaterialPiso MatePiso;


// Formas de llamarlo

public void PisoTierra()
{
MatePiso = MaterialPiso.Tierra;
}

 

Realmente nose como ayudarte de ahora en mas, ya que no se en que entorno se basa el juego.. 3d o 2d? Como funciona el sistema de sonido que decis?

 

Gracias!!! Mi proyecto es un juego en 3D, primera persona que lo único que necesita en cuanto a código es lo básico: Movimientos (resuelto) Ahogarse si estas mucho tiempo en el agua y se termina el aire (resuelto), cambiar de nivel en determinado lugar (resuelto) y la frutilla de la torta.... Morir al caer desde la altura....

El sistema de pasos está asociado a los diferentes TAG de cada superficie que pisa el player...

using UnityEngine;
using System.Collections;

public class FootStep : MonoBehaviour {
	
	public AudioClip[] SonidoMetal;
	public AudioClip[] SonidoArena;
	public AudioClip[] SonidoChapa;
	public AudioClip[] SonidoAgua;
	public AudioClip[] SonidoAguabaja;
	public AudioClip[] SonidoPiedras;
	public AudioClip[] SonidoMadera;
	public AudioClip[] SonidoConcreto;
	public AudioClip[] SonidoTerreno;
	private CharacterController controller;
	private float delayTime;
	private float NextPlay;
	
	void PlayFootStepSound()
	{
		RaycastHit OnTriggerStay;
		if (Physics.Raycast (transform.position, -Vector3.up, out OnTriggerStay, 10f) & Time.time > NextPlay)
		{
			NextPlay = delayTime + Time.time;
			delayTime = Random.Range(0.5f, 0.6f);
			switch (OnTriggerStay.collider.tag)
			{
			case "metal":
				GetComponent<AudioSource>().clip = SonidoMetal[Random.Range (0, SonidoMetal.Length)];
				GetComponent<AudioSource>().Play();
				break;
			case "arena":
				GetComponent<AudioSource>().clip = SonidoArena[Random.Range (0, SonidoArena.Length)];
				GetComponent<AudioSource>().Play();
				break;
			case "chapa":
				GetComponent<AudioSource>().clip = SonidoChapa[Random.Range (0, SonidoChapa.Length)];
				GetComponent<AudioSource>().Play();
				break;
			case "agua":
				GetComponent<AudioSource>().clip = SonidoAgua[Random.Range (0, SonidoAgua.Length)];
				GetComponent<AudioSource>().Play();
				break;
			case "aguabaja":
				GetComponent<AudioSource>().clip = SonidoAguabaja[Random.Range (0, SonidoAguabaja.Length)];
				GetComponent<AudioSource>().Play();
				break;
			case "piedras":
				GetComponent<AudioSource>().clip = SonidoPiedras[Random.Range (0, SonidoPiedras.Length)];
				GetComponent<AudioSource>().Play();
				break;
			case "madera":
				GetComponent<AudioSource>().clip = SonidoMadera[Random.Range(0, SonidoMadera.Length)];
				GetComponent<AudioSource>().Play ();
				break;
			case "concreto":
				GetComponent<AudioSource>().clip = SonidoConcreto[Random.Range(0, SonidoConcreto.Length)];
				GetComponent<AudioSource>().Play();
				break;
			default:
				GetComponent<AudioSource>().clip = SonidoTerreno[Random.Range (0, SonidoTerreno.Length)];
				GetComponent<AudioSource>().Play();
				break;
			}
		}
	}
	
	// Funcion start para inicializar el juego
	void Start () {
		controller = GetComponent<CharacterController>();
	}
	
	// Funcion update para determinar frame por frame y mandar llamar objetos establecidos en el constructor
	void Update () 
	{
		if (controller.isGrounded & controller.velocity.magnitude > 0.5)
		{
			PlayFootStepSound();
		}
	}
}

Creo que ahora puse bien la llave faltante de tu script pero por desgracia sigo con problemas... Ahora me sale error CS0116: A namespace cannot directly contain members such as fields or methods

Agradezco mucho tu ayuda y comprendo perfectamente si ya te aburrí con tantos problemas. Un abrazo!!!
 

Share this post


Link to post
Share on other sites
10 hours ago, croviman said:

Gracias!!! Mi proyecto es un juego en 3D, primera persona que lo único que necesita en cuanto a código es lo básico: Movimientos (resuelto) Ahogarse si estas mucho tiempo en el agua y se termina el aire (resuelto), cambiar de nivel en determinado lugar (resuelto) y la frutilla de la torta.... Morir al caer desde la altura....

El sistema de pasos está asociado a los diferentes TAG de cada superficie que pisa el player...


using UnityEngine;
using System.Collections;

public class FootStep : MonoBehaviour {
	
	public AudioClip[] SonidoMetal;
	public AudioClip[] SonidoArena;
	public AudioClip[] SonidoChapa;
	public AudioClip[] SonidoAgua;
	public AudioClip[] SonidoAguabaja;
	public AudioClip[] SonidoPiedras;
	public AudioClip[] SonidoMadera;
	public AudioClip[] SonidoConcreto;
	public AudioClip[] SonidoTerreno;
	private CharacterController controller;
	private float delayTime;
	private float NextPlay;
	
	void PlayFootStepSound()
	{
		RaycastHit OnTriggerStay;
		if (Physics.Raycast (transform.position, -Vector3.up, out OnTriggerStay, 10f) & Time.time > NextPlay)
		{
			NextPlay = delayTime + Time.time;
			delayTime = Random.Range(0.5f, 0.6f);
			switch (OnTriggerStay.collider.tag)
			{
			case "metal":
				GetComponent<AudioSource>().clip = SonidoMetal[Random.Range (0, SonidoMetal.Length)];
				GetComponent<AudioSource>().Play();
				break;
			case "arena":
				GetComponent<AudioSource>().clip = SonidoArena[Random.Range (0, SonidoArena.Length)];
				GetComponent<AudioSource>().Play();
				break;
			case "chapa":
				GetComponent<AudioSource>().clip = SonidoChapa[Random.Range (0, SonidoChapa.Length)];
				GetComponent<AudioSource>().Play();
				break;
			case "agua":
				GetComponent<AudioSource>().clip = SonidoAgua[Random.Range (0, SonidoAgua.Length)];
				GetComponent<AudioSource>().Play();
				break;
			case "aguabaja":
				GetComponent<AudioSource>().clip = SonidoAguabaja[Random.Range (0, SonidoAguabaja.Length)];
				GetComponent<AudioSource>().Play();
				break;
			case "piedras":
				GetComponent<AudioSource>().clip = SonidoPiedras[Random.Range (0, SonidoPiedras.Length)];
				GetComponent<AudioSource>().Play();
				break;
			case "madera":
				GetComponent<AudioSource>().clip = SonidoMadera[Random.Range(0, SonidoMadera.Length)];
				GetComponent<AudioSource>().Play ();
				break;
			case "concreto":
				GetComponent<AudioSource>().clip = SonidoConcreto[Random.Range(0, SonidoConcreto.Length)];
				GetComponent<AudioSource>().Play();
				break;
			default:
				GetComponent<AudioSource>().clip = SonidoTerreno[Random.Range (0, SonidoTerreno.Length)];
				GetComponent<AudioSource>().Play();
				break;
			}
		}
	}
	
	// Funcion start para inicializar el juego
	void Start () {
		controller = GetComponent<CharacterController>();
	}
	
	// Funcion update para determinar frame por frame y mandar llamar objetos establecidos en el constructor
	void Update () 
	{
		if (controller.isGrounded & controller.velocity.magnitude > 0.5)
		{
			PlayFootStepSound();
		}
	}
}

Creo que ahora puse bien la llave faltante de tu script pero por desgracia sigo con problemas... Ahora me sale error CS0116: A namespace cannot directly contain members such as fields or methods

Agradezco mucho tu ayuda y comprendo perfectamente si ya te aburrí con tantos problemas. Un abrazo!!!
 

en que linea aparece el error? por lo general ese error se manifiesta cuando agregas una variable dentro de un metodo.

 

ej: 

 

public void update()

{

public int fulanitoPoint; //la variable debe ir fuera de los metodos

}

Edited by stztek

Share this post


Link to post
Share on other sites
On 7/19/2021 at 11:14 AM, stztek said:

en que linea aparece el error? por lo general ese error se manifiesta cuando agregas una variable dentro de un metodo.

 

ej: 

 

public void update()

{

public int fulanitoPoint; //la variable debe ir fuera de los metodos

}

Hola! Para testear el script lo estoy trabajando como si fuera independiente.

Quedando así:

using UnityEngine;
using System.Collections;

public float TiempoEnElAire;
public int ValorCaida; //Valor tope.
public bool EstaEnElAire;
public class cae  : MonoBehaviour {

  public int ValorCaida; //Valor tope.
  public bool EstaEnElAire;


  public void Update ()
  {
   if (EstaEnElAire == true)
   {
    TiempoEnElAire = 2 * Time.deltaTime; // Va haciendo un conteo multiplicado x2. Podes cambiar el numero para que vaya mas rapido.
   } else 
   {
      TiempoEnElAire = 0; // El valor vuelve a 0 sin deltaTime. ya que EstaEnElAire es FALSE.
   }
  }

  public void OnCollisionEnter2D(Collision2D collision)
  {
    if (collision.gameObject.tag == "Suelo") //Agregar tag al Suelo.
    {
     if (EstaEnElAire == true)
     {
      if (TiempoEnElAire >= ValorCaida) //Si TiempoEnElAire es mayor o igual a ValorCaida. se ejecuta la acción.
      {
        Destroy(gameObject);
        //Aca dentro rellenas lo que queres.
      }
       EstaEnElAire = false;
     } else if (collision.gameObject.tag != "Suelo")
     {
         EstaEnElAire = true;
     }
    }
  } 
}

Y estos son los errores que me da:

Assets\Scripts\cae.cs(4,14): error CS0116: A namespace cannot directly contain members such as fields or methods

Assets\Scripts\cae.cs(5,12): error CS0116: A namespace cannot directly contain members such as fields or methods

Assets\Scripts\cae.cs(6,13): error CS0116: A namespace cannot directly contain members such as fields or methods

 

Como siempre Muchas gracias y perdón la demora, es que estoy en período de parciales en la facultad....

Share this post


Link to post
Share on other sites
10 hours ago, croviman said:

Hola! Para testear el script lo estoy trabajando como si fuera independiente.

Quedando así:


using UnityEngine;
using System.Collections;

public float TiempoEnElAire;
public int ValorCaida; //Valor tope.
public bool EstaEnElAire;
public class cae  : MonoBehaviour {

  public int ValorCaida; //Valor tope.
  public bool EstaEnElAire;


  public void Update ()
  {
   if (EstaEnElAire == true)
   {
    TiempoEnElAire = 2 * Time.deltaTime; // Va haciendo un conteo multiplicado x2. Podes cambiar el numero para que vaya mas rapido.
   } else 
   {
      TiempoEnElAire = 0; // El valor vuelve a 0 sin deltaTime. ya que EstaEnElAire es FALSE.
   }
  }

  public void OnCollisionEnter2D(Collision2D collision)
  {
    if (collision.gameObject.tag == "Suelo") //Agregar tag al Suelo.
    {
     if (EstaEnElAire == true)
     {
      if (TiempoEnElAire >= ValorCaida) //Si TiempoEnElAire es mayor o igual a ValorCaida. se ejecuta la acción.
      {
        Destroy(gameObject);
        //Aca dentro rellenas lo que queres.
      }
       EstaEnElAire = false;
     } else if (collision.gameObject.tag != "Suelo")
     {
         EstaEnElAire = true;
     }
    }
  } 
}

Y estos son los errores que me da:

Assets\Scripts\cae.cs(4,14): error CS0116: A namespace cannot directly contain members such as fields or methods

Assets\Scripts\cae.cs(5,12): error CS0116: A namespace cannot directly contain members such as fields or methods

Assets\Scripts\cae.cs(6,13): error CS0116: A namespace cannot directly contain members such as fields or methods

 

Como siempre Muchas gracias y perdón la demora, es que estoy en período de parciales en la facultad....

Super facil el error jajaja

 

fijate que 

Quote

public float TiempoEnElAire;
public int ValorCaida; //Valor tope.
public bool EstaEnElAire;

tiene que estar dentro de public class cae : MonoBehaivor

Share this post


Link to post
Share on other sites
Sign in to follow this  

×
×
  • Create New...