Noticias

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

Necesito ayuda con mi controladorPersonaje(Solucionado)

Iniciado por Bousing, Agosto 13, 2015, 07:12:10 PM

Tema anterior - Siguiente tema
Agosto 19, 2015, 11:43:36 AM #15 Ultima modificación: Agosto 19, 2015, 12:07:30 PM por Antonio
Hola Bousing.

Tu script del principio, está haciendo los movimientos del personaje con la función Translate
 transform.Translate (0, 0, v * speed * Time.deltaTime); //MOVER EL PERSONAJE HACIA ADELANTE
 v = v * -1; 
 transform.Translate (0, 0, v * speed * Time.deltaTime); //Mover el personaje hacia atrás.
 La función Translate, no comprueba las colisiones, lo que hace es mover el gameobject a esa posición de forma... "bruta". Es útil cuando quieres asegurarte de que un efecto u objeto pues llega a su destino, pero para personajes que tienen que comprobar si están colisionando con algo o no, pues Translate no es la manera correcta.

En tu personaje dices estar usando el Character Controller, si miras las funciones que contiene esa clase: http://docs.unity3d.com/ScriptReference/CharacterController.html">http://docs.unity3d.com/ScriptReference/CharacterController.htmlVerás 2 que sirven para ese propósito, la función Move y SimpleMove.

Move, mueve el gameObject en una dirección, y al moverlo, sí irá mirando si el collider está chocando con otros colliders, y aplicará los movimientos extras que hagan falta para que los colliders no se atraviesen.

SimpleMove, es similar a Move, pero esta ignora los movimientos del eje y, (arriba y abajo), en su lugar aplica la fuerza de gravedad de manera automática, además, devuelve un true o false que te dirá si el personaje está tocando el suelo o no. En tu código, por lo que veo, aplicas la velocidad al eje Z para mover el personaje adelante, esto podrías hacerlo también algo así:
(transform.forward * v * speed * Time.deltaTime)
En el contenido de la clase Transform : http://docs.unity3d.com/ScriptReference/Transform.html">http://docs.unity3d.com/ScriptReference/Transform.htmlVemos que tiene varias variables, up, right y forward, estas son vectores, direcciones que puedes usar, por lo que en el paréntesis, le digo que coja la dirección del frente (el eje z) y que se mueva a la velocidad que tú habías marcado. Sobre el otro código, está moviendo el personaje mediante Root animation, es algo diferente. Tú estás usando el Character Controller, pero en ese código no, lo que han hecho es aplicar un capsule collider, y añadir un Rigidbody (de modo que ese collider reacciona a las físicas), eso es por decirlo así como la alternativa al character controller, sólo que Character Controller tiene más cosas predefinidas que el Capsule+Rigidbody no. Por ello, ese Capsule+Rigidbody es más po***r, (tiene más libertad), mientras que Character Controller, pues es más fácil para empezar.

Ahora bien, el Capsule+Rigidbody, puede moverse usando las funciones de la clase Rigidbody, que también tiene funciones para mover los objetos detectando las colisones, pero eso no es lo que usa este código. Si miras en el Fixed Update, verás que el código está cogiendo los inputs vertical y horizontal, y los está mandando al Animator. En el animator del personaje, tendrá un gráfico montado de manera que dependiendo de que valor toma esas variables, pues el personaje activará una animación u otra. Y como tendrá activada la casilla de Root Motion, esas animaciones son las que mueven el objeto del personaje en sí. (Que gracias al Rigidbody, se asegura también de que el capsule collider no traspase los otros colliders).

Es otra manera de mover los personajes, el root motion que es lo que estoy usando yo, tiene la ventaja de que la velocidad del movimiento, viene definida por las animaciones, de modo que hay poca posibilidad de que el objeto aparezca "deslizando" en el suelo. Pero por otro lado, requiere que las animaciones sean hechas con los desplazamientos, no clavadas en el centro. Porque si no el personaje no se movería.  Sobre el asunto de la gravedad. Ya has visto que SimpleMove la calcula automáticamente, pero es muy posible que quieras tu también tener control sobre la misma, en tal caso, necesitas en algún lado, colocar ciertas instrucciones.

1º necesitas saber si el personaje está o no en el suelo,  (porque si está en el suelo, no vamos a seguir aplicando fuerza de gravedad, que además, si resulta ser muy fuerte, puede acabar por hacer que el personaje atraviese el suelo :S ). Para ver  eso, lanzamos un Raycast hacia abajo: http://docs.unity3d.com/ScriptReference/Physics.Raycast.html">http://docs.unity3d.com/ScriptReference/Physics.Raycast.html   (Aqui, el 2º ejemplo es sobre esto mismo).Y entonces miramos la distancia que hay del suelo, si la distancia es mayor que el valor que sea, pues entonces podemos considerar que está en el aire, (IsGround es false, o la variable que quieras usar). ¿Por qué esta comparación? Generalmente por las rampas, dependiendo del radio del collider, puede que haya momentos en que haya cierta distancia entre él y el suelo, de modo que usamos esa distancia para decir hasta que punto le dejamos estar o cuando empezamos a tirarle hacia abajo.Una imagen para que veas lo que digo:
https://leto20d.storage.yandex.net/rdisk/33d587497d1f0c53a62f6972dbde8e8bc08ca8bc2b70a417913868f21289e825/inf/m-gE4oIR_6By7KdO9yS4H3Jd8CnCBFWrahgHJo0wtUTgZlNv1kh3hrn8tQac0qot_wPzag2G8vc0aY9BMBHGXQ==?uid=0&filename=AlturasRampas.jpg&disposition=inline&hash=&limit=0&content_type=image%2Fjpeg&tknv=v2&rtoken=6bfcc032608a33254641a91bd4a78ab0&force_default=no&ycrid=na-be1ffc271bb1ef4300e1a49c7ee508a4-downloader8g">Imagen Offset de alturasComo ves aqui, si solo por tener un poco de distancia con el suelo, pusiéramos el personaje a caer, no podríamos subir rampas.
Una vez sepas si el personaje está en el suelo o no, pues ya lo siguiente es aplicar la fuerza de gravedad, Al igual que antes avanzando, pues hacemos algo aprecido con el el eje up
 
(transform.up * gravedad * -1)



Una última cosa, en tu código, por lo que ves, estarás aplicando la función Move o SimpleMove varias veces, que se ejecutarán o no dependiendo del caso que sea, no habría problema, pero hay que tener cuidado de que no se ejecute varias veces en el mismo ciclo, (no es que vaya a estallar o algo así, pero... no es óptimo). Por lo que es posible que prefieras crear una variable Vector3 que llames DireccionFinal, y entonces, en cada código, guardes el valor ahí en la variable:Que está andando, pues DireccionFinal = transform.forward * v * (speed/2) * Time.Deltatime
Que luego miramos si está cayendo... DireccionFinal = DireccionFinal + transfrom.up * gravedad * Time.deltatime;
Que resulta que estaba yendo hacia atrás DireccionFinal *= -1:

Y luego, al final, cuando ya tengas clara la direccion de moviento, pues ya aplicas el Move (DireccionFinal); En fin, a veces me vuelvo algo psicópara pero bueno son las cosas que he visto XD.
 

En el animator puedes poner varias condiciones para que se ejecute una animación, y tienen que satisfacerse todas.Así por ejemplo, para que no camine en el aire, puedes poner como condiciones que se pulse la tecla correspondiente y que además esté en isGrounded. 

Adngel, muchísimas gracias hermano. utilice el SimpleMove y funciono muy bien... Ya tengo solucionado la movilidad del jugador, también gracias por toda la explicación, ya que no conozco bien el API de Unity y no sabía como hacerlo correctamente. Muchas gracias también a todos los que respondieron. Saludos

Etiquetas: