24. CLASE RIGIDBODY (y VIII)










Sleep:

Function Sleep () : void


Fuerza al rigidbody a dormir al menos un frame. Un uso común es llamar esta función al principio del juego para que el rigidbody no consuma recursos hasta que sea activado.



IsSleeping:

Function IsSleeping () : Boolean


Booleano que devuelve true si el rigidbody está durmiendo.


WakeUp:

Function WakeUp () : void


Fuerza al rigidbody a despertarse.


SweepTest:

Function SweepTest (direction : Vector3, hitInfo : RaycastHit, distance : float = Mathf.Infinity) : Boolean


Devuelve true cuando un barrido del rigidbody intercepta algún collider. Esto funciona de la siguiente manera: nuestro rigidbody lanza en una dirección (parámetro direction de tipo Vector3) un rayo (pensemos hasta que no estudiemos la clase RaycastHit en una especie de láser o sonar de presencia, con la salvedad de que en este caso el rayo devolverá información de aquéllo con lo que ha chocado) hasta una determinada distancia (distance, de tipo float, que por defecto es infinito) y si el rayo tropieza con un collider, la función devuelve true.

Obviamente, esto es de gran utilidad para, por ejemplo, que nuestro personaje tenga información para evitar colisiones.

Veamos un pequeño ejemplo:

var rayo : RaycastHit;

function Update () {
if (rigidbody.SweepTest (-transform.right, rayo, 10)) {
Debug.Log("Hay un obstaculo a " + rayo.distance + " metros a la izquierda");
}
}


El script funciona como sigue: primero declaramos una variable de tipo RaycastHit para que recoja toda la información del collider que nuestra función pueda detectar en su barrido. Acto seguido lanzamos a través de la función SweepTest un rayo en dirección izquierda (-transform.right) hasta una distancia de diez metros. Caso de topar con un collider, distinta información del mismo será almacenada en la variable rayo y la función devolverá true, con lo cual se imprimirá la información tecleada, indicando la distancia del collider hallado.

Si le damos al play, observamos que nuestra función ha hallado un collider a la izquierda de nuestro cubo.


SweepTestAll:

Function SweepTestAll (direction : Vector3, distance : float = Mathf.Infinity) : RaycastHit[]

Es parecida a la anterior, pero devolviendo un array de tipo RaycastHit con toda la información de todos los colliders hallados en el camino


Además de las funciones tradicionales contenidas en la clase Rigidbody, ésta también tiene un tipo de función específica, que se disparan cuando acontece un evento. Unity las trata como "mensajes que envía la clase". Son tres:

OnCollisionEnter:

function OnCollisionEnter (collisionInfo : Collision) : void


OnCollisionEnter es llamada cuando nuestro rigidbody/collider toca otro rigidbody/collider.

En contraste con la función OnTriggerEnter, a OnCollisionEnter se le pasa como parámetro una instancia de la clase Collision, la cual contiene información sobre puntos de contacto, velocidad de impacto, etc.



OnCollisionExit:

function OnCollisionExit (collisionInfo : Collision) : void


OnCollisionExit es llamada cuando nuestro collider/rigidbody deja de tocar otro rigidbody/collider.


OnCollisionStay:

function OnCollisionStay (collisionInfo : Collision) : void


OnCollisionStay es llamada una vez cada frame para cada collider/rigidbody que esté tocando nuestro rigidbody/collider.


Y con esto acabamos la clase Rigidbody.

POSTED BY UnityScripts
POSTED IN
DISCUSSION 1 Comment

23. CLASE RIGIDBODY (VII)










AddTorque:

function AddTorque (torque : Vector3, mode : ForceMode = ForceMode.Force) : void

function AddTorque (x : float, y : float, z : float, mode : ForceMode = ForceMode.Force) : void


Esta función añade una torsión (no he podido encontrar una traducción mejor para torque) al rigidbody. Como resultado el rigidbody empezará a girar alrededor del eje de torsión.

Así, si al eje Y de rotación de nuestro cubo le reintegramos su valor de 0 y luego modificamos de la siguiente manera nuestro script del último ejemplo...


rigidbody.centerOfMass = Vector3(0,-0.3,0);

function FixedUpdate(){
rigidbody.AddTorque (Vector3.right * 15);
}


...vemos que efectivamente se le ha añadido a nuestro cubo una fuerza de torsión/rotación sobre el eje X. Recordemos que cuando hablamos de rotación, hemos de considerar a cada eje como si se tratara de una línea rígida alrededor de la cual nuestro objeto gira. Esto es, si quisiéramos que el cubo se moviera como una peonza, tendriamos que hacerlo rotar sobre su eje Y. Probad a cambiar "Vector.right * 15" por "Vector.up * 25". (Y si queremos que rote en dirección opuesta, le anteponemos un signo - al Vector.)


AddRelativeTorque:

function AddRelativeTorque (torque : Vector3, mode : ForceMode = ForceMode.Force) : void

function AddRelativeTorque (x : float, y : float, z : float, mode : ForceMode = ForceMode.Force) : void


Como podréis suponer, esta función añade una fuerza de torsión relativa a las coordenadas locales/propias del rigidbody. Es a AddTorque lo mismo que AddRelativeForce a AddForce.


AddForceAtPosition:

Function AddForceAtPosition (force : Vector3, position : Vector3, mode : ForceMode = ForceMode.Force) : void


Aplica fuerza a un rigidbody en una posición determinada.


AddExplosionForce:

Function AddExplosionForce (explosionForce : float, explosionPosition : Vector3, explosionRadius : float, upwardsModifier : float = 0.0F, mode : ForceMode = ForceMode.Force) : void


Aplica una fuerza al rigidbody que simula el efecto de una explosión. La fuerza de la explosión decaerá de manera lineal con la distancia del rigidbody.

Esta función también funciona bien con objetos inertes. Si el radio es 0, la fuerza plena será aplicada sin importar cuan lejos se produzda la explosión del rigidbody. UpwardsModifier aplica la fuerza como si fuera aplicada desde debajo del objeto.


MovePosition:

Function MovePosition (position : Vector3) : void


Mueve el rigidbody de posición. Por ejemplo:


private var velocidad : Vector3 = Vector3 (3, 0, 0);
function FixedUpdate () {
rigidbody.MovePosition(rigidbody.position + velocidad * Time.deltaTime);
}


En este script declaramos primero una variable de tipo Vector3. Le anteponemos la palabra clave "private", que implica que dicha variable no será accesible desde el inspector (no quedará expuesta). Se declara como privada una variable que no queremos que se modifique desde la interface.

El resto del script no merece mucha explicación. Se suma el Vector3 con la velociadd a la posición del rigidbody, y para que el desplazamiento se produzca en segundos y no en porciones de frames, lo multiplicamos por Time.deltaTime.


MoveRotation:

function MoveRotation (rot : Quaternion) : void

Rota el rididbody.

Si observamos el prototipo de la función, vemos que hemos de pasarle a la misma un parámetro de tipo Quaternion. Ya hemos dicho en otras ocasiones que resulta bastante complejo para los humanos trabajar con cuaterniones, razón por la cual por norma general trabajaremos en grados Euler se los pasaremos a la función convenientemente traducidos.

Un ejemplo:

private var velocidadEnAngulos : Vector3 = Vector3 (0, 100, 0);

function FixedUpdate () {
var velocidadEnCuaternionesPorTiempo : Quaternion =
Quaternion.Euler(velocidadEnAngulos * Time.deltaTime);

rigidbody.MoveRotation(rigidbody.rotation * velocidadEnCuaternionesPorTiempo);
}


Como podemos comprobar, meramente tenemos que usar la función Quaternion.Euler, que recibe grados euler como parámetro y devuelve cuaterniones. El resto es sencillo.


Y aquí hacemos una parada.

POSTED BY UnityScripts
POSTED IN
DISCUSSION 0 Comments

22. CLASE RIGIDBODY (VI)









FUNCIONES:

SetDensity:

Function SetDensity (density : float) : void


Nos permite asignar una masa en base al collider vinculado, lo cual es útil para asignar una masa en unos valores acordes al tamaño de los colliders.

Podemos aplicar un ejemplo similar al que realizamos con la variable mass. Abrimos nuestro script habitual y tecleamos:


function FixedUpdate () {
if (Input.GetButtonDown ("Horizontal")) {
rigidbody.velocity = Vector3(6,0,0);
rigidbody.SetDensity(6.0);
}
}


Salvamos. Play. Presionamos la flecha de desplazamiento horizontal y comprobamos que la masa de la esfera le permite literalmente arrastrar al cubo.


AddForce:

function AddForce (force : Vector3, mode : ForceMode = ForceMode.Force) : void


Esta función (una de las más importantes de la API de Unity) añade una fuerza al rigidbody. Como resultado de esto el rigidbody comenzará a moverse.

El primer parámetro es un Vector3, que nos servirá para indicar la potencia y dirección de la fuerza que aplicamos. Por ejemplo, podemos teclear en nuestro script de cabecera:


function FixedUpdate () {
rigidbody.AddForce (Vector3.up * 10);
}


Y al darle al play nuestra esfera ascenderá, fruto de una fuerza constante (aplicada en cada actualización de la función FixedUpdate). Obviamente, la velocidad de movimiento dependerá -además de la fuerza aplicada - de la masa del rigidbody y de la resistencia, esto es, varios rigidbodies diferentes tendrán reaccione diferentes cuando les es aplicada la misma fuerza.

function AddForce (x : float, y : float, z : float, mode : ForceMode = ForceMode.Force) : void

Este segundo prototipo de la función, como ya viene siendo habitual, meramente sustituye el parámetro de tipo Vector3 por 3 de tipo float.


//Equivale al script anterior
function FixedUpdate () {
rigidbody.AddForce (0, 10, 0);
}



El segundo parámetro observamos que es de tipo ForceMode, que como posiblemente sospechéis es una nueva enumeración made in Unity, que tiene los siguientes valores:

Force Añade una fuerza contínua al rigidbody, dependiendo de su masa. Es
el valor por defecto y que obtiene resultados más realistas, ya que
como decíamos costará más esfuerzo mover objetos más pesados que
más livianos.
Acceleration Añade una aceleración contínua al rigidbody, ignorando su masa. A
diferencia de ForceMode.Force, Acceleration moverá cualquier
rigidbody de la misma forma sin tener en cuenta su masa, lo que es
útil si sólo queremos controlar la aceleración de un objeto sin
preocuparnos de la fuerza que debíeramos aplicarle para obtenerla
teniendo en cuenta su masa y resistencia.
Impulse Añade un impulso puntual de fuerza al rigidbody, teniendo en cuenta
su masa. Hay que tener la precaución de no incluir este modo dentro
de una función que se actualice a menudo (como FixedUpdate). Este
modo es útil para aplicar fuerzas que acontecen de repente, como
explosiones o colisiones.
VelocityChange Añade un cambio de velocidad instantáneo al rigidbody, ignorando su
masa. Con esa salvedad (una misma fuerza tendrá los mismos
resultados con rigidbodies de diferente masa), le es aplicable lo
mismo que al modo precedente.


Podemos ver la diferencia entre fuerzas aplicadas en el mismo script de arriba. Lo modificamos para que quede así:


function FixedUpdate () {
rigidbody.AddForce (Vector3.up * 10, ForceMode.Impulse);
}


Podéis ver que la esfera sale disparada. No retorna porque como la tenemos dentro de la función FixedUpdate está recibiendo un impulso periódico. Vamos a liberarla:


rigidbody.AddForce (Vector3.up * 10, ForceMode.Impulse);


Supongo que queda demostrada la diferencia entre fuerza constante e impulso.


AddRelativeForce

function AddRelativeForce (force : Vector3, mode : ForceMode = ForceMode.Force) : void


Añade una fuerza al rigidbody relativa al sistema local de coordenadas de dicho rigidbody.

Para explicar qué quiere decir esto, vamos a preparar un ejemplo que requerirá varias fases: Para empezar, eliminamos el script que tenemos vinculado a la esfera. Nos colocamos en la vista vertical en la ventana Scene, haciendo click en la Y del gizmo. En Proyecto hacemos doble click en MiPrimer Script para abrir el editor, y tecleamos:


function FixedUpdate(){
rigidbody.AddForce (Vector3.right * 15);
}


Salvamos, arrastramos el script al cubo y le damos al play. Tal como era de esperar, se aplica una fuerza lateral al cubo, pero éste da demasiadas vueltas sobre sí como para hacer una demostración respecto a las coordenadas de desplazamiento, así que vamos a completar el script con una de esas variables que cuando uno las estudia cree que no las usará nunca.


rigidbody.centerOfMass = Vector3(0,-0.3,0);
function FixedUpdate(){
rigidbody.AddForce (Vector3.right * 15);
}


Exacto. Le bajamos el centro de gravedad al cubo y en principio deberíamos ahora poderlo arrastrar como un mueble. Probemos si esto funciona en la práctica.

Lo suficiente para poder realizar la explicación. Ahora giremos en el inspector el cubo 35 grados sobre el eje Y. Volvamos a darle al play.

Vemos que la fuerza que aplica la función AddForce lo es en relación a las coordenadas globales, y no a las del objeto.

Sustituimos en el script AddForce por AddRelativeForce y probemos de nuevo.

Ahora la fuerza no es aplicada a la derecha del mundo, sino a la derecha relativa del cubo.

Seguiremos.

Bye.

POSTED BY UnityScripts
POSTED IN
DISCUSSION 3 Comments
Con la tecnología de Blogger.