Коли я повинен використовувати швидкість проти addForce при роботі з об’єктами гравця?


18

Мене плутають ці два методи в рамках Unity. Обидва змушують об’єкт гравця рухатися, зупинятися, змінювати напрямок і т. Д. Коли один слід використовувати над іншим і коли один підходить?



@ Byte56 обидва питання задають різні речі
Роберт

1
Різні, але споріднені. Ось чому вони просто пов'язані, а не дублікати. Показуйте, що відображається у зв’язаному стовпці праворуч.
MichaelHouse

Відповіді:


13

Ви б використовували velocityдля переміщення об'єкта з постійною швидкістю (наприклад, куля) та AddForce()для додавання руху (наприклад, тяги космічного корабля). Також зауважте, що існує два "типи" руху; сила і порив. Для рушія космічного корабля ви використовуєте імпульс.


4
Чи можете ви описати, чому ви віддасте перевагу імпульсам для космічного корабля? Насправді це може бути не ідеально підходить, якщо ви застосовуєте поступове прискорення з часом, а не миттєві зміни імпульсу через такі речі, як удари зброї. Застосовується у часовому вікні, як правило, ви хочете сили (або прискорення, якщо ви не хочете, щоб маса була фактором), тоді як миттєво ви використовували імпульс (або, відповідно,
ChangeChange

@DMGregory Так, це залежить від того, яку силу потрібно додати. На моєму прикладі дроселя космічного корабля, який є миттєвим сплеском енергії, тоді імпульс - правильний вибір.
trojanfoe

2
Не було відразу зрозуміло, чи маєте ви на увазі короткий вистріл реактивного струменя або постійне згорання основного двигуна ("тяга" використовується трохи загально в науковій фантастиці), тому я подумав, що варто уточнити, щоб хтось не спробував використовуючи імпульси для ракетного підсилювача. ;)
DMGregory

@DMGregory Дійсно; моя космічна технологічна термінологія багато в чому заснована на фільмах :)
trojanfoe

@trojanfoe Іди грай KSP. Мовляв, прямо зараз.
користувач253751

21

Хоча відповідь вже прийнята, я думаю, що є деякі додаткові деталі, які варто висвітлити.

Використовуючи швидкість

Встановлюючи швидкість, ви змінюєте абсолютно все інше, що може вплинути на рух цього об'єкта. У деяких ситуаціях це бажано, наприклад встановити початкову швидкість кулі один раз у той момент, коли вона вистрілена, як у прикладі trojanfoe. Будьте обережні, адже при використанні в неправильних ситуаціях це може спричинити проблеми:

  • Якщо декілька джерел / скриптів намагаються змінити ту саму швидкість Жорсткого тіла, встановивши її безпосередньо (тобто 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), наприклад, за кермом автомобіля, горінням ракети або тяжким тяжкості, вам потрібна сила чи прискорення. (Залежно від того, чи хочете, щоб важкі предмети прискорювалися повільніше)

Якщо ви моделюєте раптову, різку зміну руху, як, наприклад, вистріл кулі, відхилення від вибуху чи відскакування від бар'єру, то, швидше за все, ви хочете імпульсу чи зміни швидкості.

Використання 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's PhysX / Box2D вирішують зміни буфера через AddForce окремо, але я не бачив очевидних наслідків цього)

Отже, наприкінці дня, які ці функції нас справді отримують ясність наміру . Коли я хочу застосувати поступову силу, мені не потрібно пам'ятати, щоб множити свій deltaV на Time.deltaTime і ділити на масу, я просто кажу, що хочу ForceMode.Force, і це обробляється правильно та послідовно. І коли я чи хтось інший пізніше перегляне мій код, то відразу зрозуміло, що я мав на увазі, не потрібно розшифровувати час і масові обчислення, щоб це з'ясувати.


6

Окрім trojanfoe , 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, тобто стріляти і все. Так що в цьому сценарії впоратисяvelocity корисніше, ніж AddForce.

Сподіваюся, ти зрозумієш. Принаймні трішки.


1
Ваш приклад AngryBirds, ймовірно, повинен використовувати миттєву зміну імпульсу (наприклад, Impulse або VelocityChange) при звільненні рогатки, а не ForceMode.Force, який за замовчуванням моделює його ефект за часовим вікном. Ви можете налаштувати числа, щоб отримати еквівалентну поведінку з будь-якого підходу, але якщо ви зміните свій фіксований крок часу, рішення сили матиме інший вихід (оскільки він інтегрує силу протягом більшого або коротшого проміжку часу), поки імпульс залишається послідовним, оскільки бажаного, тому що він представляє просто момент звільнення.
DMGregory

0

Rigidbody Velocity та Rigidbody Addforce - це дві заплутані функції в Unity 3D, і часто початківці не розуміють їх різниці. У цій статті ми обговоримо різницю між RigidBody.velocity та RigidBody.addforce.

В обох випадках, будь то Addforce або функція швидкості, ми будемо використовувати термін force для їх пояснення.

Коли ми використовуємо Rigidbody.velocity, тоді в цьому випадку ми додаємо силу до нашого об'єкта, але ця сила рухатиме об'єкт лише до тих пір, поки ми не продовжимо застосовувати силу.

Наприклад

body.velocity = новий Vector3 (0,0,5);

Скажімо, ви додали 5f в z положення, і ця сила буде додана, коли ви натиснете клавішу W. Отже, коли ви натиснете клавішу W, об'єкт моментально запуститься зі швидкістю 5. Це так само, якщо ви додасте силу, використовуючи цю функцію на автомобілі, цей автомобіль запуститься зі швидкістю 5.

body.velocity = новий Vector3 (0,0200);

І якщо ви скажете змінити значення на 200, а потім після збереження натисніть W. Автомобіль почне працювати зі швидкістю 200 від запуску, що в реальному світі неможливо.

Тепер якщо говорити про Rigidbody.addforce

Продовжуючи приклад нашого автомобіля. якщо до автомобіля додати силу 200

body.addforce (0,0200);

Автомобіль не почне рухатись зі швидкістю 200, якщо натиснути W, але він починається з повільного, а потім збільшує свої швидкості і зупиняється відповідно до значення Drag.

Rigidbody.addforce починається повільно, а потім прискорюється, так само, як ви перетягуєте важку таблицю, спочатку ви почнете натискати на цю таблицю, стіл просто переміститься зі свого положення, але якщо ви продовжите натискати на цю таблицю, вона почне рухатися & якщо ви залишите цю таблицю, вона покриє деяку відстань залежно від поверхні, і це те саме жорстке тіло.

Ви можете використовувати Rigidbody.velocity там, де ви просто хочете перемістити об'єкт, щоб негайно реагувати, як стрибок гравця, і результат цієї сили зникне відразу після стрибка, і ви можете використовувати Rigidbody.addforce там, де вам потрібно повільний старт, а потім безперервний рух, як ракета. Якщо ви використовуєте Rigidbody.addforce у стрибку, програвач / об’єкт залишатиметься у просторі на деякий час, а потім повернеться до основи.

(джерело)


Вам потрібно принаймні спробувати адаптувати свою публікацію до формату відповіді на обмін
стеками
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.