Bagaimana melakukan suatu gerakan menuju suatu titik tertentu dalam kesatuan. Memindahkan objek ke suatu titik di Unity3D

1

Saya sedang mengerjakan permainan yang akan melemparkan proyektil yang bereaksi terhadap kekuatan fisik. Saya menggunakan fisika bawaan Unity di dalam game, tetapi saya menggambar lintasan proyektil sebelum diluncurkan. Untuk melakukan ini saya menggunakan LineRenderer dan kelas fisika sederhana yang saya ciutkan untuk menghitung posisi:

SlingPhysics kelas publik ( Vector3 HalfGravity pribadi; ForceMultiplier pelampung pribadi; Init public void(Vector3 gravitasi, slingForce pelampung, massa pelampung, tarikan pelampung) ( HalfGravity = gravitasi/2.0f; ForceMultiplier = slingForce/mass/(1 + drag); ) publik Vector3 GetPosition(Vector3 awal, arah Vector3, float timeDelta) ( Vector3 pos = arah * (timeDelta * ForceMultiplier); pos.y += (HalfGravity.y * timeDelta * timeDelta); kembalikan start + pos; ) ///

/// /// Posisi awal /// /// Peningkatan waktu sampel /// /// Buffer untuk diisi dengan posisi public int GetPositions(Vector3 startPos, arah Vector3, kenaikan waktu float, float yFloor, posisi Vector3) ( int maxItems = posisi.Panjang; int i = 0; for (; i< maxItems; i++) { Vector3 pos = GetPosition(startPos, direction, timeIncrement * i); if (pos.y < yFloor) break; positions[i] = pos; } return i; } }

Ini berfungsi dengan baik dan (agak mengejutkan) sangat cocok dengan lintasan sebenarnya yang dilalui proyektil saat diluncurkan dan dikendalikan oleh mesin Unity Physics.

Namun sekarang kami memutuskan untuk memperkenalkan drag pada Rigid Body, dan lintasannya tidak lagi ideal. Saya dapat terus mencoba mengubah model fisika saya agar sesuai dengan apa yang dilakukan Unity, tetapi sepertinya itu akan sia-sia.

Apakah ada cara untuk menghitung terlebih dahulu dan merencanakan lintasan menggunakan mesin Unity Physics?

Jika tidak, bagaimana cara menyeret dan menggerakkan sudut dalam matematika Unity?

Apakah ada sumber dokumentasi implementasi fisika Unity (5.3.4)?

1

Saya mencari hal yang sama tetapi tidak dapat menemukan dokumentasi resmi. Namun, cukup mudah untuk memeriksanya sendiri. Saya tidak ingat apa yang terlintas di benak saya, tetapi saya menggunakan benda kaku dengan nilai tarikan dan satu tanpa nilai tarikan dan menulis skrip sederhana untuk mensimulasikan tarikan dan mencoba beberapa rumus khas dan ini ternyata menjadi salah satu dari yang sederhana. Maka Anda masih harus menghitung semuanya secara manual agar sesuai dengan implementasi Unity karena mereka tidak menawarkan API untuk apa yang Anda inginkan. - Xarbrough 01 Juni 16 01-06-2016 23:39:21

0

Xarbrough, terima kasih. Saya akan melacak rumus drag and drop dan mencobanya, meskipun ada saran dari programmer bijak, untuk menghindari kebodohan dalam mengejar Unity. Kode saya sangat sederhana, jadi sedikit lebih rumit tidak akan membunuh saya; Saya harap ini berakhir di sana. Dan ketika mesin fisika hebat berikutnya keluar, saya akan menyeberangi jembatan ini. - Orang ini 02 Juni 16 02-06-2016 05:37:29

  • 2 jawaban
  • Penyortiran:

    Aktivitas

2

Cara menghitung drag menurut mesin Unity adalah dengan menghitung dan melacak kecepatan di FixedUpdate lalu memperbarui kecepatan untuk Drag.

Ini sangat sederhana; Bagian kuncinya adalah ini:

Kecepatan *= Mathf.Clamp01(1f - Tarik * Waktu.fixedDeltaTime);

Kelas fisika khusus harus didesain ulang agar memerlukan penambahan waktu menjadi Time.fixedDeltaTime Unity (waktu antara panggilan FixedUpdate)

SlingPhysics kelas publik ( Gravitasi Vector3 pribadi; Gaya pelampung pribadi, Massa, Tarikan; Init kekosongan publik (Gravitasi Vektor3, gaya pelampung, massa pelampung, tarikan pelampung) ( Gravitasi = gravitasi; Gaya = gaya; Massa = massa; Tarik = tarik; ) ///

/// Menghitung array posisi objek Lintasan berdasarkan waktu. /// /// Jumlah posisi yang diisi ke dalam buffer /// Posisi awal /// Vektor arah (dan besarnya). /// Tinggi minimum, di bawahnya terpotong /// Buffer untuk diisi dengan posisi public int GetPositions(Vector3 startPos, arah Vector3, float yFloor, posisi Vector3) ( float timeIncrement = Time.fixedDeltaTime; int maxItems = posisi.Length; int i = 0; Kecepatan Vector3 = arah * Gaya/Massa; Vector3 pos = startPos; untuk(;saya< maxItems; i++) { velocity += Gravity * timeIncrement; velocity *= Mathf.Clamp01(1f - Drag * timeIncrement); pos += velocity * timeIncrement; if (pos.y < yFloor) break; positions[i] = pos; } return i; } }

5

Saya dapat terus mencoba dan mengubah model fisika saya agar sesuai dengan apa yang dilakukan Unity

Tidak, jangan lakukan ini. Setiap kali Unity diperbarui, hal-hal fisika seperti ini rusak. Misalnya, fisikawan Unity 4 dan 5 tidaklah sama. Harus banyak mengubah kode fisika Unity 4 saya agar dapat berfungsi dengan benar.

Solusi termudah untuk masalah Anda adalah Bukan jangan menghitung apa pun. Saya melakukan ini untuk menciptakan dua cangkang. Proyektil1- proyektil utama yang dapat dilihat dan ditembakkan. Proyektil2- proyektil tersembunyi itu tidak bisa diperhatikan oleh pemain.

Dalam mode drag, tembak Proyektil2(tersembunyi) dan kemudian menyimpan jalur atau posisinya (Vector3) yang dilaluinya dalam List . Gunakan jalur tersimpan ini untuk menggambar Lintasan Proyektil.

Anda hanya perlu menghapusnya Proyektil2(sembunyikan) sekali dan simpan jalannya. Jika selama mode seret, jari, mouse, atau seret Anda dipindahkan ke posisi lain, maka Anda harus melakukannya jernih Daftar, potret ulang Proyektil2(tersembunyi) lagi, simpan posisinya ke Daftar lalu perbarui lagi Lintasan Proyektil,

Katakanlah kita memiliki sebuah benda yang perlu bergerak menuju suatu titik. Tugasnya sederhana, gunakan interpolasi, misalnya. Namun bagaimana jika benda kita bisa berputar dengan sudut acak? Lalu bagaimana cara menetapkan titik interpolasi? Tentunya troli konvensional kita hanya boleh bergerak searah dengan rodanya. Dengan demikian, baik sisi belakang atau depan. Aljabar vektor akan membantu kita memecahkan masalah ini.

Teori

Kami menerima kenyataan bahwa masalah ini dapat diselesaikan dengan menggunakan aljabar vektor. Ini berarti kita perlu melakukan sesuatu dengan vektor. Tapi apa? Pertama, mari kita proyeksikan konsep vektor ke dalam soal kita. Sesuai dengan kondisi permasalahan, kita perlu menentukan titik untuk interpolasi. Artinya, titik relatif terhadap sistem koordinat global/lokal ke mana benda selanjutnya akan berpindah. Artinya ruas antara titik benda yang kita ambil untuk menentukan pergerakan dan titik akhir yang diinginkan akan menjadi vektor.

Sekarang kita tahu bahwa kita mempunyai sebuah vektor dan kita perlu mencari koordinat ujungnya. Untuk mengatasi masalah ini dengan jelas, diperlukan serangkaian parameter:

  • koordinat asal vektor;
  • panjang vektor;
  • sudut kemiringan terhadap sumbu koordinat.
Anggap saja kita mengetahui semua ini. Kemudian masalahnya direduksi menjadi rumus paling sederhana dari teorema sinus.

$sebaris$x/dosa(α) = a/dosa (90)$sebaris$
$sebaris$x = a* sin(α)$sebaris$
$sebaris$y/dosa (90 - α) = a/dosa(90)$sebaris$
$sebaris$y = a * sin (90 - α)$sebaris$

Dimana a adalah panjang vektor, adalah sudut kemiringan terhadap sumbu koordinat

Sebenarnya ilmu ini masih cukup bagi kita untuk memecahkan masalah dalam praktek.

Praktik

Jadi kita tahu:
  • dimana sisi depan dan belakang benda;
  • posisi objek saat ini;
  • sudut yang dilalui benda tersebut.
  • jarak yang harus ditempuh suatu benda.
Kami memiliki hampir semua informasi, tetapi berdasarkan kasus kami, kami mengetahui secara numerik sudut rotasi suatu benda, tetapi kami tidak mengetahui sumbu mana yang diputar. Diperlukan data tambahan. Lalu kami perkenalkan konsep seperempat. Bukan rahasia lagi bahwa dalam sistem koordinat Kartesius dua dimensi terdapat 4 kuarter, masing-masing dari 1 hingga 4. Pada setiap kuartal sumbunya mempunyai tanda yang berbeda-beda.

Dan ini juga berlaku dalam kesatuan. Pertama, kita perlu mendefinisikan bagian dalam adegan. Kita membuat kubus di titik asal, memindahkannya dan melihat koordinat mana yang negatif dan mana yang positif. Pada contoh terlihat bahwa kedua koordinatnya negatif, artinya kubus berada pada kuarter ketiga.

Sekarang Anda dapat melanjutkan langsung ke skrip. Sebagai masukan kita mengambil Transform dari objek asli setelah rotasi dan Transform dari dummy, yang selanjutnya akan kita pindahkan. Boneka tersebut awalnya memiliki koordinat objeknya. Selanjutnya, kita menentukan bagian di mana bagian depan benda itu berada. Karena lingkaran trigonometri dibatasi dari 0 hingga 360 derajat, hal ini tidak sulit. Setelah menentukan seperempatnya, kami menghitung sudut kemiringan untuk setiap koordinat. Kemudian kita periksa apakah sudut kita mempunyai tanda yang benar. Setelah ini, kami mengirimkan sudut kemiringan ke rumus akhir untuk menghitung koordinat. Dan terakhir, kami menetapkan koordinat baru untuk boneka yang akan kami interpolasi.

Void CheckingQuarterUp(Transformasi vectorAngle, ref Transform kosong) ( float zangle = 0; float xangle= 0; float zcoord = 0.0f; float xcoord = 0.0f; int normangle = Mathf.RoundToInt (vectorAngle.eulerAngles.y); if (normangle >= 0 && sudut normal<= 90) // 1-ая четверть { zangle = 90 - normangle; xangle = 0 - normangle; xangle = (xangle < 0) ? xangle * -1: xangle; zangle = (zangle < 0) ? zangle * -1: zangle; } if (normangle >270 && sudut normal<= 360) // 2-ая четверть { xangle = 360 - normangle; zangle = 270 - normangle; xangle = (xangle >0) ? xsudut * -1: xsudut; zangle = (zangle< 0) ? zangle * -1: zangle; } if (normangle >180 && sudut normal<= 270) // 3-ая четверть { xangle = 180 - normangle; zangle = 270 - normangle; xangle = (xangle >0) ? xsudut * -1: xsudut; zangle = (zangle > 0) ? zangle * -1: zangle; ) jika (normalangle > 90 && normangle<= 180) // 4-ая четверть { zangle = 90 - normangle; xangle = 180 - normangle; zangle = (zangle >0) ? zangle * -1: zangle; xsudut = (xsudut< 0) ? xangle * -1: xangle; } zcoord = path * Mathf.Sin (zangle *Mathf.PI/180); xcoord = path * Mathf.Sin (xangle * Mathf.PI/180); float newpathx = empty.position.x + xcoord; float newpathz = empty.position.z + zcoord; empty.position = new Vector3 (newpathx, empty.transform.position.y, newpathz); }

Kesimpulan

Seperti yang Anda lihat, solusinya cukup sederhana. Sebelum menggunakan metode ini, periksa apakah Anda memiliki cukup data, jika tidak, tugas tersebut jelas tidak dapat diselesaikan. Misalnya, dengan menghilangkan sudut kemiringan sumbu, luas penyelesaian menjadi lingkaran dengan jumlah titik tak terhingga.

Untuk bergerak mundur, Anda hanya perlu mengubah tanda koordinat secara diametris menurut seperempatnya. Jika Anda memutuskan untuk mendefinisikan suatu titik dalam ruang tiga dimensi, ingatlah bahwa akan ada lebih banyak “perempat” di sana.

Contoh implementasi metode dapat diambil