Estoy confundido acerca de estos dos métodos en el marco de Unity. Ambos hacen que el objeto del jugador se mueva, pare, cambie de dirección, etc. ¿Cuándo se debe usar uno sobre el otro y cuándo es apropiado?
Estoy confundido acerca de estos dos métodos en el marco de Unity. Ambos hacen que el objeto del jugador se mueva, pare, cambie de dirección, etc. ¿Cuándo se debe usar uno sobre el otro y cuándo es apropiado?
Respuestas:
Se utilizaría velocity
para mover el objeto a una velocidad constante (por ejemplo, una bala) y AddForce()
para agregar movimiento (por ejemplo, un propulsor de nave espacial). También tenga en cuenta que hay dos "tipos" de movimiento; fuerza e impulso. Para un propulsor de nave espacial usarías el impulso.
Aunque ya hay una respuesta aceptada, creo que hay algunos detalles adicionales que vale la pena cubrir.
Usando velocidad
Cuando configura la velocidad, está anulando absolutamente todo lo demás que pueda afectar el movimiento de ese objeto. En algunas situaciones, esto es deseable, como establecer la velocidad inicial de una bala una vez en el momento en que se dispara, como en el ejemplo de Trojanfoe. Solo tenga cuidado, porque cuando se usa en situaciones incorrectas puede causar problemas:
Si múltiples fuentes / scripts intentan modificar la misma velocidad de Rigidbody configurándola directamente (es decir body.velocity = foo
), entonces el que se ejecute en último lugar gana, y los otros tienen efecto cero. Esto puede llevar a un orden de errores de actualización, en particular provocando que las entidades floten o caigan lentamente (porque la aceleración hacia abajo debido a la gravedad se anula antes de que pueda acumularse)
Si está configurando la velocidad en cada cuadro, las colisiones con otros objetos pueden ser un poco extrañas. Es como si su objeto fuera impulsado por un motor con un par infinito: no importa cuánta velocidad pierda en un impacto, vuelve a la velocidad máxima en el siguiente paso de física, y su velocidad no se desvía del impacto . Esto puede provocar el lanzamiento de objetos con los que colisionas, o que los objetos pequeños puedan empujar a los enormes con mucha más facilidad de lo que parece, o que los objetos se deslicen lentamente a lo largo de las barreras estáticas en lugar de desviarse hacia ellos.
Ambos efectos pueden desearse a veces. Por ejemplo, cuando estoy haciendo juegos de Kinect y quiero que las extremidades del avatar virtual del jugador puedan interactuar con la escena física, generalmente muevo esos cuerpos usando la configuración de velocidad directa. Debido a que la mano real del jugador está en un lugar conocido y no disminuyó la velocidad de la colisión con ese objeto virtual, su mano virtual debe hacer lo mismo para mantenerse alineado, por lo que en este caso realmente queremos anular todos los demás efectos físicos para consíguelo ahí.
AddForce y amigos
AddForce y funciones auxiliares similares, por el contrario, están hechas para cooperar con todo lo que sucede en el mundo de la física. Si múltiples fuentes / scripts agregan fuerza a un cuerpo rígido, todos esos efectos se suman para crear un cambio neto en el movimiento del objeto (que, dependiendo de cómo se calcule, también puede ser independiente del orden). Esto ayuda a evitar que un script pise por completo algún otro efecto físico.
AddForce viene en cuatro tipos al especificar el parámetro ForceMode opcional , que son útiles para diferentes cosas:
ForceMode | Use
-----------------------------------------------------------------------
Force (default) | Accelerate an object over 1 time step, based on its mass.
| Units: Newtons = kg * m/s^2
|
Acceleration | Accelerate an object over 1 time step, ignoring its mass. (like gravity)
| Units: m/s^2
|
Impulse | Instantaneously propel an object, based on its mass
| Units: N * s = kg * m/s
|
VelocityChange | Instantaneously propel an object, ignoring its mass
| (like body.velocity = foo, except multiple scripts can stack)
| Units: m/s
Si está tratando de modelar un empuje continuo a lo largo del tiempo (por ejemplo, algo que está aplicando en cada actualización fija), como la conducción de un automóvil o la quema de un cohete o el arrastre de un pozo de gravedad, quiere Fuerza o Aceleración. (Dependiendo de si desea que los objetos pesados aceleren más lentamente)
Si está modelando un cambio repentino y brusco en el movimiento, como disparar una bala, retroceder ante una explosión o rebotar en una barrera, lo más probable es que desee Impulse o VelocityChange.
El uso de AddForce te ayuda a lograr más realismo físico, pero también puede requerir que pases más tiempo pensando en la física de tu comportamiento. Por ejemplo, si desea que su cuerpo tenga una aceleración finita hasta una velocidad objetivo, para que reaccione de manera más realista a las colisiones que establecer la velocidad en cada cuadro, es probable que desee un cálculo similar a esta función auxiliar:
public static void AccelerateTo(this Rigidbody body, Vector3 targetVelocity, float maxAccel)
{
Vector3 deltaV = targetVelocity - body.velocity;
Vector3 accel = deltaV/Time.deltaTime;
if(accel.sqrMagnitude > maxAccel * maxAccel)
accel = accel.normalized * maxAccel;
body.AddForce(accel, ForceMode.Acceleration);
}
La razón por la que llamo a todas estas "funciones auxiliares" es que técnicamente podría lograr los mismos fines con:
body.velocity += suitablyCalculatedDeltaV;
( Creo . Es posible que los cambios del búfer de solución física basados en PhysX / Box2D de Unity cambien a través de AddForce por separado, pero no he visto consecuencias obvias de esto)
Entonces, al final del día, lo que realmente nos consiguen estas funciones es claridad de intención . Cuando quiero aplicar una fuerza gradual, no necesito recordar multiplicar mi deltaV por Time.deltaTime y dividirlo por masa, solo digo que quiero ForceMode.Force y se maneja de manera correcta y consistente. Y cuando yo u otra persona vengan a repetir mi código más tarde, queda inmediatamente claro lo que quise decir, sin necesidad de decodificar el tiempo y los cálculos en masa para resolverlo.
Además de la respuesta de trojanfoe , Angry Birds vs Car Racing. Dos ejemplos principales y diferentes de estos métodos ( AddForce
y velocity
respectivamente). Por ejemplo, en Angry Birds el uso de la velocidad es un poco más difícil, ya que tendría que establecer la trayectoria del proyectil por su cuenta, como,
Cuando uso AddForce en Angry Birds, usaría,
_birdRigidbody.AddForce(new Vector2(5,5));
Mientras que cuando uso la velocidad, manejaría la trayectoria usando
x = v*t*Cos(theta)
y = v*t*Sin(theta) - 0.5 * g * t *t
O algo como esto.
Mientras que en el juego Car Racing deberías controlar la velocidad todo el tiempo, no como Angry Birds, es decir, Shoot y todo. Entonces, en ese escenario, manejar velocity
es más útil que AddForce
.
Espero que entiendas. Al menos un poquito.
Rigidbody Velocity y Rigidbody Addforce son dos funciones confusas en Unity 3D y, a menudo, los principiantes no entienden su diferencia. En este artículo, vamos a discutir la diferencia entre RigidBody.velocity y RigidBody.addforce.
En ambos casos, ya sea Addforce o función de velocidad, vamos a utilizar el término fuerza para explicarlos.
Cuando estamos usando Rigidbody.velocity, entonces, en ese caso, estamos agregando fuerza a nuestro objeto, pero esta fuerza solo moverá el objeto a menos y hasta que sigamos aplicando fuerza.
Por ejemplo
body.velocity = nuevo Vector3 (0,0,5);
Digamos que ha agregado 5f en la posición z y esa fuerza se agregará cuando presione la tecla W. Entonces, cuando presione la tecla W, el objeto comenzará instantáneamente a la velocidad de 5. Es igual que si agrega fuerza usando esta función en un automóvil, ese automóvil comenzará a la velocidad de 5.
body.velocity = new Vector3 (0,0,200);
Y si deja de decir, cambie el valor a 200 y luego, después de guardar, presione W. El automóvil comenzará a funcionar a una velocidad de 200 desde el inicio, lo que no es posible en el mundo real.
Ahora si hablas de Rigidbody.addforce
Continuando con nuestro ejemplo de automóvil. si agrega la fuerza de 200 al automóvil
body.addforce (0,0,200);
El automóvil no comenzará a moverse a una velocidad de 200 si presionamos W, pero comienza desde lento y luego aumenta su velocidad y se detiene de acuerdo con el valor de Arrastrar.
Rigidbody.addforce comienza lento y luego acelera, al igual que arrastrando una mesa pesada, primero comenzará a empujar esa mesa, la mesa solo se moverá un poco desde su posición, pero si continúa empujando esa mesa, comenzará a moverse. si abandonas esa mesa, cubrirá cierta distancia dependiendo de la superficie y ese es el mismo cuerpo rígido.
Puede usar Rigidbody.velocity donde solo quiere mover su objeto para reaccionar instantáneamente como el salto del jugador y el resultado de esa fuerza se desvanecerá justo después del salto y puede usar Rigidbody.addforce donde necesita un inicio lento y luego el movimiento continuo como un cohete. Si usas Rigidbody.addforce en salto, el jugador / objeto permanecerá en el espacio por un tiempo y luego volverá a la tierra.