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

3 Responses to : 22. CLASE RIGIDBODY (VI)

  1. Slaptones says:

    Hola,

    estoy haciendo un jueguecillo tipo R-type. Es decir, naves espaciales con scroll lateral constante(la nave si no se le aplica movimiento en realidad se mueve quedando en el mismo punto del plano).

    Esto lo empecé a hacer hace tiempo sin saber mucho e implementé la nave con CharacterController. Cosa que a priori facilitaba mucho el arranque del proyecto, pero cuando he podido ir añadiendole funcionalidad me he dado cuenta que no era lo más óptimo.

    El primer problema ha sido el choque contra las paredes y tal, con ese objeto es imposible manejarlo bien.

    He ido haciendo la implementación con un rigidbody y su collider, he cambiado la forma de hacer que la nave tenga la velocidad constante metiendo la nave como objeto hijo de la cámara, esto es importante que sea así porque me he creado un optimizador de objetos en pantalla, si te interesa te lo enseño.

    Total, que me enrollo, mi problema actual es cuando la nave roza un objeto, o una explosión de un enemigo se le aplica una pequeña fuerza en dirección y potencia desconocida. Produciendo que la nave paulatinamente se vaya moviendo sin que pulsemos los botones de movimiento.

    Sabes alguna forma de anular toda fuerza? Recuerda que desconozco en que sentido y potencia se le aplica.

    Gracias

  2. en C# sería:

    public class ProbandoRigidBody: MonoBehaviour {

    void Start () {
    rigidbody.velocity = new Vector3 (6f, 0f, 0f);
    rigidbody.centerOfMass = new Vector3 (0f, -0.3f, 0f);
    rigidbody.SetDensity(1.0f);
    }

    void Update () {}

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

  3. Kmii says:

    Hola! disculpa te moleste pero estoy haciendo un juego en Unity tipo Hole in the Wall y quiero hacer que mis paredes se muevan hacia delante, mis paredes están hechas con X numero de cubos en una coroutine la cual invoco repetidas veces con InvokeRepeat. mi idea es generar una pared y que se mueva, pero no estoy logrando hacer que se muevan. estoy intentando usar rigidbody.addforce para esto pero nada... ayuda pls :C

Leave a Reply

Con la tecnología de Blogger.