Kapan saya harus menggunakan kecepatan versus addForce saat berhadapan dengan objek pemain?

18

Saya bingung tentang dua metode ini dalam kerangka kerja Unity. Keduanya membuat objek pemain bergerak, berhenti, mengubah arah, dll. Kapan satu harus digunakan di atas yang lain dan kapan yang tepat?

Robert
sumber
@ Byte56 kedua pertanyaan bertanya tentang hal
Robert
1
Berbeda, tetapi terkait. Itu sebabnya mereka hanya ditautkan dan bukan duplikat. Perlihatkan itu muncul di kolom tertaut di sebelah kanan.
MichaelHouse

Jawaban:

13

Anda akan menggunakan velocityuntuk memindahkan objek pada kecepatan konstan (misalnya peluru) dan AddForce()untuk menambahkan gerakan (misalnya pendorong pesawat ruang angkasa). Perhatikan juga ada dua "tipe" gerakan; kekuatan dan dorongan. Untuk pendorong pesawat ruang angkasa Anda akan menggunakan impuls.

trojanfoe
sumber
4
Bisakah Anda jelaskan mengapa Anda lebih suka impuls untuk pesawat ruang angkasa pendorong? Ini mungkin benar-benar cocok non-ideal jika Anda menerapkan akselerasi bertahap dari waktu ke waktu, daripada perubahan momentum sesaat karena hal-hal seperti dampak senjata. Diterapkan pada jendela waktu Anda biasanya menginginkan gaya (atau akselerasi jika Anda tidak ingin massa menjadi faktor) sementara secara instan Anda akan menggunakan impuls (atau,
seiring dengan itu
@ DMGregory Ya, itu tergantung pada jenis kekuatan yang ingin Anda tambahkan. Dalam contoh saya tentang pesawat ruang angkasa pendorong, yang merupakan ledakan energi sesaat maka dorongan adalah pilihan yang tepat.
trojanfoe
2
Tidak segera jelas apakah maksud Anda adalah penembakan jet sikap atau pembakaran mesin utama secara terus-menerus ("thruster" digunakan secara umum di sci-fi pada waktu tertentu), jadi saya pikir saya harus mengklarifikasi kalau-kalau seseorang mencoba menggunakan impuls untuk penguat roket. ;)
DMGregory
@DMGregory Memang; terminologi teknologi ruang angkasa saya sebagian besar didasarkan pada film :)
trojanfoe
@trojanfoe Pergi mainkan KSP. Seperti sekarang.
user253751
21

Meskipun sudah ada jawaban yang diterima, saya pikir ada beberapa detail tambahan yang layak dibahas.

Menggunakan Velocity

Saat Anda mengatur kecepatan, Anda benar-benar mengesampingkan segala hal lain yang mungkin memengaruhi pergerakan objek itu. Dalam beberapa situasi ini diinginkan, seperti mengatur kecepatan awal dari peluru sekali pada saat itu ditembakkan, seperti dalam contoh trojanfoe. Hanya berhati-hatilah, karena ketika digunakan dalam situasi yang salah dapat menyebabkan masalah:

  • Jika beberapa sumber / skrip mencoba untuk memodifikasi kecepatan Rigidbody yang sama dengan mengaturnya secara langsung (mis. body.velocity = foo), Maka yang mana yang dijalankan menang terakhir, dan yang lainnya tidak memiliki efek. Hal ini dapat menyebabkan urutan pembaruan bug, khususnya yang menyebabkan entitas melayang atau jatuh perlahan (karena akselerasi ke bawah karena gravitasi akan ditimpa sebelum dapat menumpuk)

  • Jika Anda mengatur kecepatan setiap frame, tabrakan dengan objek lain bisa sedikit aneh. Seolah-olah objek Anda sedang didorong oleh mesin dengan torsi tak terbatas - tidak peduli berapa banyak kecepatan yang hilang pada tumbukan, itu kembali ke kecepatan tertinggi pada langkah fisika berikutnya, dan kecepatannya tidak dibelokkan menjauh dari tumbukan . Hal ini dapat menyebabkan peluncuran objek yang bertabrakan dengan Anda, atau benda kecil yang mampu mendorong benda besar jauh lebih mudah dari yang seharusnya, atau benda yang meluncur perlahan di sepanjang penghalang statis alih-alih membelokkan / mengikutinya.

Kedua efek ini kadang-kadang diinginkan. Sebagai contoh, ketika saya membuat game Kinect dan saya ingin anggota avatar virtual pemain dapat berinteraksi dengan adegan fisika, saya biasanya menggerakkan tubuh-tubuh itu menggunakan pengaturan kecepatan langsung. Karena tangan pemain yang sebenarnya ada di tempat yang diketahui dan tidak melambat dari tabrakan dengan objek virtual itu, tangan virtual mereka perlu melakukan hal yang sama untuk tetap selaras, jadi dalam hal ini kami benar - benar ingin mengganti semua efek fisika lainnya menjadi dapatkan di sana

AddForce and Friends

Sebaliknya, AddForce dan fungsi pembantu serupa dibuat untuk bekerja sama dengan semua hal lain yang terjadi di dunia fisika. Jika beberapa sumber / skrip AddForce ke Rigidbody, semua efek tersebut ditambahkan bersama-sama untuk membuat perubahan bersih dalam gerakan objek (yang, tergantung pada cara penghitungannya, mungkin juga tidak tergantung pesanan). Ini membantu menghindari satu skrip yang sepenuhnya menginjak beberapa efek fisika lainnya.

AddForce hadir dalam empat rasa dengan menetapkan parameter ForceMode opsional , yang berguna untuk berbagai hal:

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

Jika Anda mencoba memodelkan dorongan terus menerus dari waktu ke waktu (mis. Sesuatu yang Anda terapkan setiap FixedUpdate), seperti mengemudi mobil atau membakar roket atau gravitasi yang menarik dengan baik, Anda menginginkan Force atau Percepatan. (Tergantung apakah Anda ingin benda berat berakselerasi lebih lambat)

Jika Anda memodelkan perubahan gerakan yang tiba-tiba dan tajam, seperti menembakkan peluru, mundur dari ledakan, atau memantul pada penghalang, maka Anda lebih mungkin menginginkan Impuls atau VelocityChange.

Menggunakan AddForce membantu Anda mencapai lebih banyak realisme fisik, tetapi juga mengharuskan Anda menghabiskan lebih banyak waktu untuk memikirkan fisika perilaku Anda. Misalnya, jika Anda ingin tubuh Anda memiliki akselerasi terbatas hingga kecepatan target, sehingga bereaksi lebih realistis terhadap tumbukan daripada mengatur kecepatan setiap frame, Anda mungkin ingin perhitungan yang mirip dengan fungsi pembantu ini:

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);
}

Alasan saya menyebut semua "fungsi pembantu" ini adalah karena secara teknis Anda bisa mencapai semua tujuan yang sama dengan:

 body.velocity += suitablyCalculatedDeltaV;

( Saya pikir . Mungkin saja pemecah fisika fisika berbasis Unity PhysX / Box2D perubahan buffer melalui AddForce secara terpisah, tapi saya belum melihat konsekuensi yang jelas dari ini)

Jadi pada akhirnya, apa fungsi ini benar-benar memberi kita kejelasan niat . Ketika saya ingin menerapkan gaya bertahap, saya tidak perlu ingat untuk melipatgandakan deltaV saya dengan Time.deltaTime dan membaginya dengan massa, saya hanya mengatakan saya ingin ForceMode.Force dan ditangani dengan cara yang benar & konsisten. Dan ketika saya atau orang lain datang untuk beralih pada kode saya nanti, segera jelas apa yang saya maksud, tanpa perlu men-decode waktu dan perhitungan massa untuk mengetahuinya.

DMGregory
sumber
6

Selain jawaban trojanfoe , Angry Birds vs Car Racing. Dua contoh utama dan berbeda dari metode ini ( AddForcedan velocitymasing - masing). Misalnya, dalam Angry Birds penggunaan kecepatan sedikit lebih sulit karena Anda harus mengatur lintasan Proyektil sendiri, seperti,

Ketika saya menggunakan AddForce di Angry Birds, saya akan menggunakan,

_birdRigidbody.AddForce(new Vector2(5,5));

Sementara ketika saya menggunakan kecepatan maka saya akan menangani lintasan menggunakan

x = v*t*Cos(theta) y = v*t*Sin(theta) - 0.5 * g * t *t

Atau sesuatu seperti ini.

Sementara di game Car Racing, Anda harus mengontrol kecepatan setiap saat, tidak seperti Angry Birds, yaitu Shoot dan semuanya. Jadi dalam menangani skenario velocityitu lebih berguna daripada AddForce.

Semoga kamu mengerti. Setidaknya sedikit.

Hamza Hasan
sumber
1
Contoh AngryBirds Anda mungkin harus menggunakan perubahan momentum secara instan (mis. Impulse atau VelocityChange) ketika katapel dilepaskan, alih-alih ForceMode default. Force yang mensimulasikan efeknya pada jendela waktu. Anda dapat menyetel angka untuk mendapatkan perilaku yang setara dari kedua pendekatan tersebut, tetapi jika Anda mengubah langkah waktu tetap Anda, solusi gaya akan memiliki output yang berbeda (karena itu mengintegrasikan gaya pada interval waktu yang lebih lama atau lebih pendek) sementara impuls tetap konsisten sebagai diinginkan, karena itu hanya mewakili saat rilis.
DMGregory
0

Rigidbody Velocity dan Rigidbody Addforce adalah dua fungsi membingungkan di Unity 3D dan seringkali pemula gagal memahami perbedaannya. Dalam Artikel ini, kita akan membahas perbedaan antara RigidBody.velocity dan RigidBody.addforce.

Dalam kedua kasus, apakah itu Addforce atau fungsi kecepatan, kita akan menggunakan istilah force untuk menjelaskannya.

Ketika kita menggunakan Rigidbody.velocity, maka, dalam hal itu, kita menambahkan gaya ke objek kita, tetapi gaya ini hanya akan memindahkan objek kecuali dan sampai kita terus menerapkan gaya.

Sebagai contoh

body.velocity = Vector3 baru (0,0,5);

Katakanlah Anda telah menambahkan 5f di posisi z dan gaya itu akan ditambahkan ketika Anda akan menekan tombol W. Jadi, ketika Anda akan menekan tombol W objek akan langsung mulai pada kecepatan 5. Ini sama seperti jika Anda menambahkan gaya menggunakan fungsi ini pada mobil, mobil itu akan mulai pada kecepatan 5.

body.velocity = Vector3 baru (0,0200);

Dan jika Anda katakan katakan ubah nilainya menjadi 200 dan kemudian setelah menyimpan tekan W. Mobil akan mulai berjalan pada kecepatan 200 dari awal yang tidak mungkin di dunia nyata.

Sekarang Jika Anda berbicara tentang Rigidbody.addforce

Dengan Melanjutkan contoh Mobil kami. jika Anda menambahkan kekuatan 200 ke mobil

body.addforce (0,0200);

Mobil tidak akan mulai bergerak pada kecepatan 200 jika kita menekan W tetapi mulai dari lambat dan kemudian meningkatkan kecepatannya dan berhenti sesuai dengan nilai Seret.

Rigidbody.addforce mulai lambat dan kemudian mempercepat, sama seperti Anda menyeret meja yang berat, pertama Anda akan mulai mendorong meja itu, tabel hanya akan bergerak sedikit dari posisinya tetapi jika Anda terus mendorong meja itu akan mulai bergerak & jika Anda meninggalkan meja itu akan menutupi jarak tergantung pada permukaan dan itu adalah benda tegar yang sama.

Anda dapat menggunakan Rigidbody.velocity di mana Anda hanya ingin memindahkan objek Anda untuk bereaksi secara instan seperti lompatan pemain & hasil dari gaya itu akan lenyap tepat setelah lompatan dan Anda dapat menggunakan Rigidbody.addforce di mana Anda memerlukan awal yang lambat dan kemudian gerakan terus menerus seperti sebuah roket. Jika Anda menggunakan Rigidbody.addforce dalam lompatan, Player / Object akan tetap berada di ruang untuk sementara waktu dan kemudian akan kembali ke tanah.

(sumber)

Numan Hamza
sumber
Anda setidaknya harus mencoba dan menyesuaikan posting Anda dengan format jawaban Stack Exchange :)
Vaillancourt