Noticias

¡RECUERDA QUE SI ERES UN NUEVO USUARIO, DEBES PRESENTARTE PARA PODER PUBLICAR MENSAJES! | TENEMOS CANAL OFICIAL DE TELEGRAM: t.me/unity3dspain

Plataformas solidas por una cara

Iniciado por Ben, Agosto 12, 2016, 11:52:00 AM

Tema anterior - Siguiente tema
Buenas.
 
No se si es el foro correcto, pero es que en los demás foros parece que no tengo permiso para publicar posts, si es posible que se mueva donde este mejor.
 
Estoy intentando hacer un pequeño script para que unas plataformas en 3D (rectángulos 3D) permitan ser atravesadas por el jugador únicamente de debajo a arriba, haciendo que sean solidas y hagan rebotar al jugador de arriba a abajo.
 
El problema que tengo es que si el jugador se mueve muy rápido, en ocasiones se produce como un lijero, casi imperceptible cambio de dirección del jugador al atravesar la plataforma, como si el objeto del colisionador de la plataforma no tuviera los valores de velocidad correctamente actualizados, tengo la sensación de que el evento OnCollisionEnter() no se actualiza exactamente al entrar haciendo que aparezca este efecto, este es mi código en las plataformas:
 

    void OnCollisionEnter(Collision col)
    {
        if (col.gameObject.tag == "Player")
        {
            Rigidbody body = col.gameObject.GetComponent<Rigidbody>();
            if (Mathf.Abs(this.GetComponent<Renderer>().bounds.max.y - col.gameObject.GetComponent<Renderer>().bounds.min.y) > 0.1)
            {
                this.GetComponent<Collider>().isTrigger = true;
                body.velocity = new Vector3(col.relativeVelocity.x, col.relativeVelocity.y, col.relativeVelocity.z); // prevent block movement
            } else
            {
                this.GetComponent<Collider>().isTrigger = false;
                body.velocity = new Vector3(col.relativeVelocity.x, 10, col.relativeVelocity.z);
            }
        }
    }
    void OnTriggerExit(Collider col)
    {
        this.GetComponent<Collider>().isTrigger = false;
    }

 
No se si es la mejor forma de hacerlo o existen mejores sistemas mas precisos, o cual puede ser exactamente el problema de esa "vibración" o pequeño cambio en el movimiento.
 
Saludos.

Prueba a lanzar un raycast para detectar la collision antes de que se produzca, ten encuenta que si tu player se mueve rapido, que se yo 1 unidad en cada frame y la plataforma mide por ejemplo 0.5 unidades, es posible que de un frame a otro la atraviese y no se de cuenta o que aparezca en medio,por poner un ejemplo,lo que tienes que hacer es ir lanzando un raycast cada frame para comprobar la distancia de algun posible collider, no hace falta que lanzes el rayo muy lejos,lo que se vaya a mover el personjae
 
Puedes probar este script del Wiki
 
http://wiki.unity3d.com/index.php?title=DontGoThroughThings
 
Si no tambien puedes probar poner los rigids en continuos dynamic en el personaje y continuos donde vaya a chocar

Entonces es como me imaginaba, existe una diferencia de tiempo entre la parte que se encarga de las colisiones y la parte gráfica.
 
He intentado poner en los otros 2 modos tanto el jugador como las plataformas pero aun así me daban problemas, así que lo que he hecho es hacer algo parecido a lo del raycast pero con un collider transparente y como trigger que sea un 50% mas grande que el cubo en todas direcciones, así puedo detectar colisiones de canto / de lado contra los bordes de las plataformas, el código me ha quedado así:
 

   void OnCollisionEnter(Collision col)
    {
       
        if (col.gameObject.tag == "Player")
        {
            Rigidbody body = col.gameObject.GetComponent<Rigidbody>();
            if (Mathf.Abs(this.GetComponent<Renderer>().bounds.max.y - col.gameObject.GetComponent<Renderer>().bounds.min.y) > 0.15)
            {
            } else
            {
                body.velocity = new Vector3(col.relativeVelocity.x, this.bounceForce, col.relativeVelocity.z);
            }
        }
       
    }
    void OnTriggerEnter(Collider col)
    {
        if (col.gameObject.tag == "GroundCheck")
        {
            if ((this.GetComponent<Renderer>().bounds.max.y - col.gameObject.GetComponent<MeshCollider>().bounds.min.y) > 0.15)
            {
                this.GetComponent<Collider>().isTrigger = true;
            }
            else
            {
                this.GetComponent<Collider>().isTrigger = false;
            }
        }
    }

 
Y parece que ya no hace ningún efecto visual raro.
 
Gracias!

Etiquetas: