Я запутался в этих двух методах в рамках Unity. И то, и другое заставляет объект игрока двигаться, останавливаться, менять направление и т. Д. Когда один из них должен быть использован поверх другого, а когда уместен?
Я запутался в этих двух методах в рамках Unity. И то, и другое заставляет объект игрока двигаться, останавливаться, менять направление и т. Д. Когда один из них должен быть использован поверх другого, а когда уместен?
Ответы:
Вы будете использовать velocity
для перемещения объекта с постоянной скоростью (например, пули) и AddForce()
добавить движение (например, движитель космического корабля). Также обратите внимание, что есть два «типа» движения; сила и импульс. Для космического корабля вы бы использовали импульс.
Хотя уже есть принятый ответ, я думаю, что есть некоторые дополнительные детали, на которые стоит обратить внимание.
Используя скорость
Когда вы устанавливаете скорость, вы перекрываете абсолютно все остальное, что может повлиять на движение этого объекта. В некоторых ситуациях это желательно, например, установить начальную скорость пули один раз в момент ее запуска, как в примере троянца. Просто будьте осторожны, потому что при использовании в неправильных ситуациях это может вызвать проблемы:
Если несколько источников / сценариев пытаются изменить одну и ту же скорость Rigidbody, установив ее напрямую (т.е. body.velocity = foo
), то, какой бы из них ни был запущен последним, выигрыши, а другие имеют нулевой эффект. Это может привести к порядку ошибок обновления, в частности, заставляя объекты зависать или падать медленно (потому что ускорение вниз из-за гравитации переопределяется, прежде чем оно может накапливаться)
Если вы устанавливаете скорость в каждом кадре, столкновения с другими объектами могут быть немного странными. Это как если бы ваш объект двигался двигателем с бесконечным крутящим моментом - независимо от того, какую скорость он теряет при ударе, он возвращается к максимальной скорости на следующем физическом шаге, и его скорость не отклоняется от удара , Это может привести к запуску объектов, с которыми вы сталкиваетесь, или к тому, что маленькие объекты могут толкать огромные гораздо легче, чем кажется, или объекты медленно скользят вдоль статических барьеров вместо того, чтобы отклоняться от них / вдоль них.
Оба этих эффекта иногда могут быть желательны. Например, когда я делаю игры для Kinect и хочу, чтобы конечности виртуального аватара игрока могли взаимодействовать со сценой физики, я обычно перемещаю эти тела, используя прямую настройку скорости. Поскольку фактическая рука игрока находится в известном месте и не замедляется от столкновения с этим виртуальным объектом, его виртуальная рука должна делать то же самое, чтобы оставаться на одной линии, поэтому в этом случае мы на самом деле хотим переопределить все другие физические эффекты, чтобы получите это там.
AddForce и Друзья
AddForce и аналогичные вспомогательные функции созданы для взаимодействия со всем, что происходит в мире физики. Если несколько источников / сценариев AddForce для Rigidbody, все эти эффекты добавляются вместе, чтобы создать чистое изменение в движении объекта (которое, в зависимости от того, как он рассчитывается, также может быть независимым от порядка). Это помогает избежать одного сценария, полностью подавляющего некоторый другой физический эффект.
AddForce поставляется в четырех вариантах с указанием необязательного параметра ForceMode , который полезен для разных целей:
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
Если вы пытаетесь смоделировать непрерывный толчок с течением времени (например, что-то, что вы применяете при каждом FixedUpdate), например, за рулем автомобиля, или за горением ракеты, или за гравитационным колодцем, вам нужна сила или ускорение. (В зависимости от того, хотите ли вы, чтобы тяжелые предметы ускорялись медленнее)
Если вы моделируете внезапное, резкое изменение движения, например, стрельбу пули, отскакивание от взрыва или отскакивание от барьера, то вам скорее всего понадобится Impulse или VelocityChange.
Использование AddForce помогает вам достичь большего физического реализма, но также может потребовать, чтобы вы тратили больше времени на обдумывание физики своего поведения. Например, если вы хотите, чтобы ваше тело имело конечное ускорение до целевой скорости, чтобы оно реагировало на столкновения более реалистично, чем устанавливая скорость в каждом кадре, вам, вероятно, понадобятся вычисления, подобные этой вспомогательной функции:
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);
}
Причина, по которой я называю все эти «вспомогательные функции», заключается в том, что технически вы могли бы достичь всех одинаковых целей:
body.velocity += suitablyCalculatedDeltaV;
( Я думаю . Возможно, физика Unity на базе PhysX / Box2D решает изменения буфера отдельно через AddForce, но я не видел очевидных последствий этого)
Итак, в конце концов, что эти функции действительно дают нам, так это ясность намерений . Когда я хочу применить постепенную силу, мне не нужно помнить, чтобы умножить мой deltaV на Time.deltaTime и разделить на массу, я просто говорю, что хочу ForceMode.Force, и он обрабатывается правильным и последовательным образом. И когда я или кто-то другой позже итерируем свой код, сразу становится ясно, что я имел в виду, без необходимости декодировать вычисления времени и массы, чтобы понять это.
В дополнение к ответу троянца , Angry Birds vs Car Racing. Два основных и разных примера этих методов ( AddForce
и velocity
соответственно). Например, в Angry Birds использование скорости немного сложнее, так как вам бы пришлось самому устанавливать траекторию снаряда, например,
Когда я использую AddForce в Angry Birds, я бы использовал,
_birdRigidbody.AddForce(new Vector2(5,5));
В то время как когда я использую скорость, то я бы обрабатывал траекторию, используя
x = v*t*Cos(theta)
y = v*t*Sin(theta) - 0.5 * g * t *t
Или как то так.
В то время как в игре Car Racing вам придется постоянно контролировать скорость, а не как Angry Birds, то есть Shoot и все такое. Так что в этом сценарии дескриптор velocity
более полезен, чем AddForce
.
Надеюсь, вы понимаете. По крайней мере, немного.
Rigidbody Velocity и Rigidbody Addforce - две запутанные функции в Unity 3D, и часто начинающие не понимают их различий. В этой статье мы собираемся обсудить разницу между RigidBody.velocity и RigidBody.addforce.
В обоих случаях, будь то Addforce или функция скорости, мы будем использовать термин «сила», чтобы объяснить их.
Когда мы используем Rigidbody.velocity, тогда в этом случае мы добавляем силу к нашему объекту, но эта сила будет перемещать объект только до тех пор, пока мы не будем продолжать применять силу.
Например
body.velocity = new Vector3 (0,0,5);
Допустим, вы добавили 5f в позиции z, и эта сила будет добавлена, когда вы нажмете клавишу W. Поэтому, когда вы нажмете клавишу «W», объект мгновенно запустится со скоростью 5. Это похоже на то же самое, если вы добавляете силу, используя эту функцию на автомобиле, эта машина будет запускаться со скоростью 5.
body.velocity = new Vector3 (0,0,200);
И если вы допустите изменение значения на 200, а затем после сохранения нажмите W. Автомобиль начнет движение со скоростью 200 с момента запуска, что невозможно в реальном мире.
Теперь, если вы говорите о Rigidbody.addforce
Продолжая наш автомобильный пример. если вы добавите силу 200 к машине
body.addforce (0,0,200);
Автомобиль не начнет двигаться со скоростью 200, если мы нажмем W, но он начнет медленно, а затем увеличит свою скорость и остановится в соответствии со значением Drag.
Rigidbody.addforce запускается медленно, а затем ускоряется, точно так же, как вы перетаскиваете тяжелый стол, сначала вы начнете толкать этот стол, стол просто немного сдвинется со своей позиции, но если вы продолжите нажимать на этот стол, он начнет двигаться и если вы покидаете этот стол, он будет покрывать некоторое расстояние в зависимости от поверхности, и это то же самое, что и для solidbody.addforce.
Вы можете использовать Rigidbody.velocity, где вы просто хотите переместить свой объект, чтобы реагировать мгновенно, как прыжок игрока, и результат этой силы исчезнет сразу после прыжка, и вы можете использовать Rigidbody.addforce, где вам нужен медленный старт, а затем непрерывное движение, как ракета. Если вы используете Rigidbody.addforce в прыжке, Player / Object некоторое время будет оставаться в космосе, а затем вернется на землю.