Mengapa OnCollisionEnter dari Unity tidak memberi saya normals permukaan, dan apa cara yang paling dapat diandalkan untuk mendapatkannya?

11

Unity's on collision event memberi Anda objek Collision yang memberi Anda beberapa informasi tentang collision yang terjadi (termasuk daftar ContactPoints dengan hit normals).

Tapi yang tidak Anda dapatkan adalah permukaan normal untuk collider yang Anda pukul. Berikut screenshot untuk diilustrasikan. Garis merah berasal dari ContactPoint.normaldan garis biru dari RaycastHit.normal.

masukkan deskripsi gambar di sini

Apakah ini merupakan contoh dari persembunyian informasi untuk menyediakan API yang disederhanakan? Atau apakah teknik deteksi tabrakan realtime 3D standar tidak mengumpulkan informasi ini?

Dan untuk bagian kedua dari pertanyaan, apa cara yang pasti dan relatif efisien untuk mendapatkan permukaan yang normal untuk tabrakan?

Saya tahu bahwa raycasting memberi Anda normals permukaan, tetapi sepertinya saya perlu melakukan beberapa raycast untuk mencapai ini untuk semua skenario (mungkin kombinasi titik kontak / normal melewatkan collider pada pemeran pertama, atau mungkin Anda perlu melakukan rata-rata semua normal poin kontak 'untuk mendapatkan hasil terbaik).

Metode saya saat ini:

  1. Cadangkan Collision.contacts[0].pointsepanjang hitnya normal

  2. Raycast ke hit normal dinegasikan untuk float.MaxValue, padaCollision.collider

  3. Jika itu gagal, ulangi langkah 1 dan 2 dengan yang tidak dinegasikan normal

  4. Jika gagal, coba langkah 1 hingga 3 dengan Collision.contacts[1]

  5. Ulangi 4 hingga berhasil atau sampai semua titik kontak habis.

  6. Menyerahlah, kembali Vector3.zero.

Ini sepertinya menangkap semuanya, tetapi semua raycast itu membuat saya mual, dan saya tidak yakin bagaimana menguji apakah ini bekerja untuk cukup banyak kasus. Apakah ada cara yang lebih baik?

EDIT Jika ini memang benar-benar keadaannya dengan tabrakan 3D, tinjauan umum mengapa dalam kasus umum akan sama disambut sebagai sesuatu yang spesifik untuk Unity.

michael.bartnett
sumber
Apakah ini hanya untuk rasa ingin tahu, atau Anda mencoba melakukan sesuatu dan terjebak? Artinya, mengapa Anda pikir Anda perlu permukaan yang normal? Ajukan pertanyaan tentang efek apa yang ingin Anda capai, daripada bagaimana "memperbaiki" solusi untuk masalah yang tidak ditentukan, dan seseorang mungkin dapat membantu Anda menyelesaikannya. :)
Sean Middleditch
@SeanMiddleditch Saya tidak setuju. Pertanyaannya diajukan dengan baik dan persis seperti yang saya cari. Pertanyaan ini dan jawabannya membantu saya memperbaiki beberapa hal yang saya lakukan salah.
SteakOverflow

Jawaban:

12

Ini benar-benar seperti keadaan dengan tabrakan. Tidak hanya 3D, tetapi juga 2D. Ambil contoh berikut:

Tumpang tindih AABB

AABB hijau dan merah bertabrakan, dan manifold kontak adalah area biru. Titik kontak akan berada di area biru di suatu tempat (di mana tepatnya dapat bervariasi dengan algoritma, tetapi sudut tempat bertemu biru / merah / hijau adalah ideal-ish).

Permukaan normal apa yang harus dikembalikan? Tepi atas AABB merah atau tepi kiri? Jika kotak hijau jatuh, mungkin kita bisa menebak tepi atas. jika bergerak ke kanan, mungkin kita bisa menebak sisi kiri. Bagaimana jika itu bergerak ke bawah dan ke kanan? Apakah kita mengambil poros penetrasi paling sedikit? Sumbu kecepatan kecepatan terbesar? Beberapa heuristik dari keduanya? Bagaimana jika kotak-kotak itu akan bertabrakan persis di sudut-sudut?

Perluas ini ke permukaan 3D kompleks yang berpotensi terdiri dari 100-an tris / wajah. Anda masih hanya akan memiliki sejumlah kecil titik kontak ideal-ish. Permukaan normal apa yang harus dikembalikan? Permukaan rata-rata normal di seluruh tri-mesh (yang tidak masuk akal untuk sebagian besar objek)? Poin langsung "di bawah" sudut kotak bertabrakan (yang tidak didefinisikan dengan baik untuk sebagian besar bentuk lainnya)? Apakah Anda mencoba menemukan wajah terdekat dengan titik kontak yang dihasilkan (yang akan memerlukan lintasan kedua, karena titik kontak tidak dihitung secara langsung dari permukaan jala mana saja)? Jika Anda menemukan wajah terdekat, apakah Anda mengambil wajah normal atau apakah Anda menyisipkan simpul wajah pada titik kontak untuk mendapatkan normal yang benar untuk objek "halus"?

Sungguh, masalah utama adalah bahwa titik kontak tidak semua titik kontak. Dalam banyak kasus, itu akan menjadi set poin yang tak terbatas. Mereka hanya beberapa titik yang terdistribusi dengan baik yang membuatnya layak untuk memperkirakan reaksi fisik dengan menerapkan gaya pada titik-titik tersebut untuk mendorong benda bertabrakan di sekitar dengan cara reaslitic-ish. Poin / lokasi spesifik dari kontak objek aktual disarikan jauh di belakang model matematika yang disederhanakan. Oleh karena itu, gagasan permukaan kontak normal tidak masuk akal dalam kasus umum.

Tentu saja, dengan batasan dan batasan yang lebih spesifik pada objek, dunia, dan gerakan Anda, Anda dapat membuat algoritma tabrakan alternatif yang dapat memberi tahu Anda tentang permukaan normal. Dalam kasus 2D di atas, jika kita mengasumsikan bahwa kotak tidak pernah berputar dan kita tahu kecepatan relatif dan posisi terakhir masing-masing, akan dapat menggunakan deteksi tabrakan terus menerus untuk mencari tahu kapan mereka akan bertabrakan dan fitur yang bertabrakan, memasok kita dengan fitur yang tepat di mana tabrakan terjadi, yang kemudian dapat digunakan sebagai kontak / tabrakan / permukaan normal. Game platformer dibangun sepenuhnya berdasarkan asumsi dan trik khusus (Itulah sebabnya menggunakan perpustakaan fisika umum seperti Box2D atau Havok atau cahaya tidak pernah menghasilkan jenis kontrol yang ketat dan presisi yang Anda temukan di platformer klasik seperti Mario atau Sonic; Saya tidak akan melakukannya. ingin mengatakannya '

Perpustakaan fisika Newtonian umum, seperti yang digunakan di Unity3D, tidak dapat membuat semacam penyederhanaan dan asumsi. Karenanya, Anda tidak mendapatkan tabrakan permukaan normal, Anda mendapatkan manifold kontak, umumnya disederhanakan ke titik kontak, dan hanya itu.

Sean Middleditch
sumber
Ini jawaban yang fantastis, dan persis apa yang saya cari, terima kasih. Masalah khusus adalah mendapatkan vektor refleksi yang meyakinkan pada benda tegar kinematik pada tabrakan. Apakah pendekatan yang biasa jika Anda ingin informasi semacam ini untuk memilih apakah Anda ingin raycast atau ambil 3 titik kontak (jika tersedia) dan mengambil produk silang?
michael.bartnett