Bagaimana cara membuat objek yang dapat diseret yang masuk ke rintangan di jalan?

8

Saya membawa pertanyaan lain-seret-dengan-mouse (saya menggunakan Unity dengan C #), tetapi dengan detail khusus yang kurang umum: adanya hambatan di tengah cara palung yang menyeret terjadi (ruang 3D, bukan 2D) .

Biarkan saya jelaskan. Misalkan saya memiliki pesawat yang ingin saya seret kubus yang disebut "obj". Itu mudah. Berikut ini adalah implementasi sederhana saya untuk itu:

void Update () {
  Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
  RaycastHit hit;
  if(Physics.Raycast(ray, out hit, 1000000))
  obj.transform.position = new Vector3(hit.point.x,0.25F,hit.point.z);
}

Berhasil. Namun, anggaplah saya juga memiliki beberapa kubus lain di atas pesawat, yang merupakan kendala. Jelas, ketika pemain bergerak "keberatan" di atas pesawat, gerakan seperti itu harus diblokir oleh rintangan. Dan kemudian, saat bertabrakan dengan rintangan, "obj" harus bergerak hanya terpotong ke sisi hambatan itu. Jika mouse digerakkan dan "obj" berhenti bertabrakan dengan rintangan, gerakan gaya menyeret bebas dilanjutkan kembali.

objek diseret ke arah rintangan dan berhenti di ujungnya, lalu melanjutkan kembali ketika tarik melewati rintangan

Untuk membuat tantangan lebih sulit, saya berusaha keras untuk mencapainya tanpa menggunakan komponen RigidBody pada rintangan (objek yang diseret dapat memilikinya). Adakah ide tentang cara paling efisien untuk mencapai hal itu? Terimakasih banyak!

EDIT: Komentator telah menarik perhatian saya bahwa saya harus menyebutkan bahwa benda-benda dibiarkan berputar ketika memotret.

EDIT 2: Mempertimbangkan sulitnya formulasi asli, saya mengubah pertanyaan yang memungkinkan penggunaan komponen-komponen Rigidbody pada objek yang diseret. Solusinya tidak bisa menggunakan komponen Rigidbody di rintangan.

Dan
sumber
Apakah Anda bergerak bentuk cembung acak - apakah mereka selalu empat sisi? Apakah mereka selalu 2D?
Steven
Bolehkah saya tahu alasan mengapa Anda tidak akan menggunakan Rigidbodies? Mereka adalah cara termudah untuk melakukan apa yang Anda inginkan tanpa harus menerapkan kembali kode yang sudah tersedia di Unity.
EvilTak
@ EvilTak Saya lebih suka belajar bagaimana berurusan dengan geometri yang terlibat dalam tugas dan karena alasan kinerja, saya tidak suka menggunakan Rigidbodies kecuali benar-benar tidak dapat dihindari. Dalam kasus khusus ini, saya akan memiliki ribuan objek yang berperilaku sebagai penghalang
Tanggal
Btw, terima kasih kepada @Anko (atau kepada siapa pun yang melakukannya) karena menyertakan gambar animasi itu untuk menggambarkan masalahnya! Saya masih memikirkan cara terbaik untuk melakukannya.
Tanggal
1
@Steven dan EvilTak: objek boleh dibiarkan berputar, hambatannya seharusnya tidak. Cara biasa mendeteksi tabrakan tampaknya tidak cukup: objek utama terus masuk ke dalam objek.
Mand

Jawaban:

2

Sulit untuk mendeteksi tabrakan tanpa melibatkan benda keras, tetapi karena Anda menggunakan kubus, Anda mungkin dapat menggunakan Bounds.Intersect . Setiap pembaruan, periksa apakah batas objek yang diseret berpotongan dengan batas penghalang. Jika ya, maka Anda dapat mencoba ini:

  1. Nonaktifkan Mesh Renderer untuk objek yang diseret agar tidak terlihat (tapi terus seret).
  2. Jatuhkan objek yang terlihat dan identik dengan yang diseret di posisi terakhir sebelum batas persimpangan (sekarang terlihat seperti objek berhenti, tetapi sebenarnya Anda masih menyeret yang asli).
  3. Setiap pembaruan, periksa untuk melihat apakah batas-batas objek yang masih Anda seret berpotongan dengan batas rintangan.
  4. Ketika batas objek yang diseret tidak lagi bersinggungan dengan kendala, hapus / nonaktifkan objek placeholder dan aktifkan kembali Mesh Renderer untuk objek yang diseret agar terlihat lagi.

Anda tidak pernah berhenti menyeret blok; itu hanya muncul kepada pengguna bahwa blok telah berhenti menyeret sementara itu akan bersinggungan dengan rintangan.

Evan
sumber
Berdasarkan komentar sebelumnya dan pada balasan Anda, saya mengedit pertanyaan untuk membuatnya lebih mudah untuk diselesaikan: sekarang katakanlah bahwa Rigidbody dapat digunakan untuk objek yang dapat diseret atau penampungnya. Benda tegar tidak bisa digunakan untuk rintangan.
Juli
1

Tanpa melakukannya sendiri, inilah yang akan saya coba:

  1. Putuskan seberapa tinggi beberapa hambatan pada pesawat untuk memblokir objek yang Anda seret (di mana "tinggi" berarti dihilangkan di sepanjang sumbu mana pun yang sesuai — saya menganggap salah satu yang mengarah ke kamera).
  2. Setiap pembaruan, simpan posisi hit raycast Anda.
  3. Setiap pembaruan, sebelum menyimpan posisi hit raycast saat ini, periksa posisi hit raycast saat ini terhadap posisi hit raycast sebelumnya.
  4. Jika perbedaan> = tinggi pemblokiran, hentikan objek bergerak Anda pada posisi hit raycast sebelumnya.

Tampak bagi saya bahwa jika Anda ingin objek Anda menyeret sepanjang bidang miring hambatan, Anda harus hanya memiliki transformasi terus mengikuti posisi hit raycast terbaru.

Evan
sumber
Terima kasih atas jawaban Anda, @Evan. Namun, solusi itu tidak akurat. Misalkan RayCast akan ditembakkan dari pusat kotak berlari objek yang dapat ditarik. Bagaimana jika penghalang menghalangi hanya sebagian dari objek yang dapat diseret yang ada di sebelah kiri atau kanan sinar yang dilemparkan? Sekalipun kita menambah jumlah sinar yang dilemparkan (apa yang bisa menjadi tinggi secara eksponensial jika objek yang dapat diseret dapat diseret ke arah 360º dalam dimensi X, Z), tergantung pada seberapa kecil penghalang dalam kaitannya dengan objek yang dapat diseret, masih bisa berada di antara sinar yang dilemparkan - dan karenanya tidak akan terdeteksi
Tanggal
Baiklah, saya pikir saya mengerti maksud Anda.
Evan