Noticias

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

Personaje tiembla sobre plataforma al subir

Iniciado por juanmasco, Diciembre 11, 2016, 07:10:02 PM

Tema anterior - Siguiente tema
Hola, estoy intentando algo que creo que es muy simple, pero no termino de entender porque ocurre el fallo.
 
 
 
Estoy creando una especie de ascensor, es un simple cubo con un box collider y, una animación de subir y bajar que se repite. 
 
El problema viene cuando el first person controller se sube encima y la plataforma empieza a ascender.  El personaje empieza a "temblar", no se queda quieto y hace la subida muy incomoda. Es como si estuviera empujandolo hacia arriba a tirones. Si no me entendéis muy bien puedo hacer un vídeo. Cuando baja directamente se separa y va cayendo separado de la plataforma. Fatal vamos jeje, debería de quedarse pegado a la plataforma y va a su bola. También he probado con el rigidbody controller y sigue pasando lo mismo.
 
¿Qué me está fallando?

Si el ascensor solo asciende y desciende no es necesario una animación, para dicha acción lo mejor sería hacerlo con traslación de posicion dentro de FixedUpdate y con esto vas a resolver los problemas de saltos, tambien podrás ajustar la altura de parada y de esta manera reutilizar los ascensores.

Puff, no tengo ni idea de programación. No quiero que me hagáis el trabajo, obviamente, pero... ¿algún enlace a la documentación de Unity o algún tutorial que muestre un poco ese concepto?


public float Heigth = 100;
public bool IsUse = false;
private Vector3 _startPos;
private void Start()
{
_startPos = transform.position;
}
private void FixedUpdate()
{
if(IsUse)
   transform.position = Vector3.MoveTowars(transform.position, _startPos + (Vector3.Up * Heigth), Time.fixedDeltaTime * 10);
else
   transform.position = Vector3.MoveTowars(transform.position, _startPos, Time.fixedDeltaTime * 10);
}

 
Deberia andar, pero lo escribí directamente en la WEB es algo muy simple, analizalo y trata de entender la lógica. 

Cita de: francoe1 date=1481485419

public float Heigth = 100;
public bool IsUse = false;
private Vector3 _startPos;
private void Start()
{
_startPos = transform.position;
}
private void FixedUpdate()
{
if(IsUse)
   transform.position = Vector3.MoveTowars(transform.position, _startPos + (Vector3.Up * Heigth), Time.fixedDeltaTime * 10);
else
   transform.position = Vector3.MoveTowars(transform.position, _startPos, Time.fixedDeltaTime * 10);
}

   
      Deberia andar, pero lo escribí directamente en la WEB es algo muy simple, analizalo y trata de entender la lógica. 
   


Wow, muchísimas gracias, trataré de entenderlo.
 
De verdad, gracias por molestarte en escribir el código. Lo aprecio realmente.

Eso pasa porque la plataforma se mueve y en el cuadro que sigue el controller decide acomodarse, como no tenes seguridad de quien modifico sus matrices de modelo para el transform antes (si lo hizo el player te da saltitos).
 
La logica que necesitas es la del tipico juego de plataformas, osea detectar el suelo y luego un nombre, componente o tag, si es que el controller se encuentra sobre dicho objeto lo enparentas a este, el controller queda hijo de este, y entonces sus se mueve respecto a este. Yo lo que hago es poner a "static" todo gameObject que lo sea (por este motivo y por el staticBatching), entonces la condicion para que el Player este en una plataforma es:
 
Si el objeto donde estoy parado esta en la capa "Plataforma" (por ej) y es "No estatico" enparentalo.
 
El metodo de deteccion podes elegirlo vos, si es un FPS te recomiendo el SphereCast o la BoxCollider en los pies, prefiero el spherecast asi reduzco la cantidad de objetos en el player ya que se hace en runtime con las fisicas.
 


// que se origine desde adentro del player, podes subirlo una una distancia radio
// luego lo bajas en la direcion Vector3.Down una distancia radio tambien (queda medio radio fuera)
// que la esfera tenga un radio un poco menor que el radio del controller (ponele un 90% de este)
RaycastHit rhit;
Physics.SphereCast( .... , out rhit)   //no recuerdo el orden de los argumentos, estan en la referencia
if(rhit.collider)
{
if(rhit.collider.gameObject.isStatic == false)
   trasnform.SetParent(rhit.collider.transform);
else
   trasnform.SetParent(null);
}
else
{
trasnform.SetParent(null);
}

 
 

El Emparentamiento no es una buena idea, pero si una solución simple y rápida! me había olvidado de esto.

Por que no lo es? muchos juegos sino la mayoria lo usan, depende del tipo de personaje que tengas, si son todos rigidbodies aplicas la velocidad de la plataforma y esta bien, pero si son controllers tenes que ver en que momento el player cae en la plataforma y empezar a moverlo por deltas, casi lo mismo que enparentar. Te comento porque yo trate hasta lo ultimo por no enparentar cosas, me parecia "incorrecto" este metodo. Hace poco me cambie a esto, y se solucionaron todos los problemas con las plataformas moviles 2D y 3D que antes tenia. Y aparte el codigo quedo mucho mas prolijito jaja
 
Saludos

Cita de: lightbug date=1481502644Por que no lo es? muchos juegos sino la mayoria lo usan, depende del tipo de personaje que tengas, si son todos rigidbodies aplicas la velocidad de la plataforma y esta bien, pero si son controllers tenes que ver en que momento el player cae en la plataforma y empezar a moverlo por deltas, casi lo mismo que enparentar. Te comento porque yo trate hasta lo ultimo por no enparentar cosas, me parecia "incorrecto" este metodo. Hace poco me cambie a esto, y se solucionaron todos los problemas con las plataformas moviles 2D y 3D que antes tenia. Y aparte el codigo quedo mucho mas prolijito jaja
   
   
      Saludos
   


El problema se debe a que no es totalmente genérico, yo tambien me encontre frente a estos problemas de plataformas más aún en el 2D, pero en realidad realizandolo con FixedUpdate las cosas se solucionan, lo he probado e implementado en múltiples proyectos y jamas me fallo.. 
 
Pruebalo por ti mismo, evitas emparentar algo no recomendado debido a las escalas y otros factores aplicados al Transform debido al emparentamiento.
 

public class Ascensor : MonoBehaviour
{
    public bool Use;
void FixedUpdate ()
    {
        if (Use)
        {
            transform.position = Vector3.MoveTowards(transform.position, transform.position + Vector3.up, Time.fixedDeltaTime * 5);
        }
}
}

 
 

uf si es cierto, algo que olvide totalmente era el tema de las escalas, como yo soy muy obsesionado con este tema tengo todo en 1,1,1 jamas las toco, salvo si el personaje se agacha. Tambien como mantengo el tema de las unidades bien definido (32 ppu) ya se de movida el tamaño de todo y no tengo que hacer retoques, pero es un muy buen punto.
 
Ya habia intentado con las deltas de desplazamiento y me funciono muy bien (no se porque lo modifique luego). Basicamente, detecta si esta en una plataforma movil, si esta se mueve para donde sea (caso general no solo en up) calcula el desplazamiento (delta) y se lo aplica al movimiento final del Player como un "movimiento externo" , osea en el vector final de movimiento tengo:
 
- horizontal (A y D)
 
- vertical (gravedad, salta, trepar ,etc)
 
- Mov Externo (plataforma movil, ascensor, etc)
 
Probablemente quite lo del parent y vuelva a esto.
 
Saludos
 
 
 
 
 
 
 
 

Diciembre 12, 2016, 05:34:36 AM #10 Ultima modificación: Diciembre 12, 2016, 05:34:53 AM por francoe1
Claro, en Fisica se da por sabido que un cuerpo dentro de otro bajan a la misma velocidad debido a que la gravedad afecta de igual manera a ambos. por lo que tienes que tener controlada la velocidad y la gravedad del jugador cuando se encuentra en plataformas de movimiento vertical.
 
Cuando se trata de movimientos Horizontales entra en juego el rozamiento, algo que da muchos problemas a la hora de la física simulada, en este caso lo mejor es afectar la posicion del Jugador con la velocidad de la plataforma, este es un problema aparte al de un ascensor, Por este motivo dije que el Emparentamiento era una solución simple, pero no la mejor para el caso.

Etiquetas: