¿Cuándo debería usar velocidad versus addForce cuando trato con objetos de jugador?


18

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?



@ Byte56 ambas preguntas son sobre cosas diferentes
Robert

1
Diferente, pero relacionado. Es por eso que solo están vinculados y no duplicados. Mostrarlo aparece en la columna vinculada a la derecha.
MichaelHouse

Respuestas:


13

Se utilizaría velocitypara 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.


44
¿Puedes describir por qué preferirías los impulsos para un propulsor espacial? En realidad, esto puede ser un ajuste no ideal si está aplicando una aceleración gradual con el tiempo, en lugar de cambios instantáneos en el impulso debido a cosas como los impactos de armas. Aplicado sobre una ventana de tiempo, generalmente querrá fuerza (o aceleración si no desea que la masa sea un factor) mientras que instantáneamente usaría impulso (o, en consecuencia, cambio de velocidad)
DMGregory

@DMGregory Sí, depende del tipo de fuerza que desee agregar. En mi ejemplo del propulsor de la nave espacial, que es una explosión momentánea de energía, entonces el impulso es la elección correcta.
trojanfoe

2
No estaba claro de inmediato si se refería a un breve disparo de un jet de actitud o al encendido continuo de un motor principal (el "propulsor" se usa un poco genéricamente en ciencia ficción a veces), así que pensé que debería aclararlo para que alguien no lo intente usando impulsos para un cohete propulsor. ;)
DMGregory

@DMGregory De hecho; mi terminología de tecnología espacial se basa principalmente en películas :)
trojanfoe

@trojanfoe Ve a jugar KSP. Como ahora mismo.
user253751

21

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.


6

Además de la respuesta de trojanfoe , Angry Birds vs Car Racing. Dos ejemplos principales y diferentes de estos métodos ( AddForcey velocityrespectivamente). 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 velocityes más útil que AddForce.

Espero que entiendas. Al menos un poquito.


1
Su ejemplo de AngryBirds probablemente debería usar un cambio instantáneo en el impulso (por ejemplo, Impulse o VelocityChange) cuando se lanza la honda, en lugar del ForceMode.Force predeterminado que simula su efecto en una ventana de tiempo. Puede ajustar los números para obtener un comportamiento equivalente de cualquiera de los enfoques, pero si cambia su paso de tiempo fijo, la solución de fuerza tendrá una salida diferente (ya que está integrando la fuerza en un intervalo de tiempo más largo o más corto) mientras el impulso permanece constante como deseado, porque representa solo el momento de lanzamiento.
DMGregory

0

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.

(fuente)


Al menos debería intentar adaptar su publicación al formato de una respuesta de Stack Exchange :)
Vaillancourt
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.