Saya mencoba untuk membuat efek yang mirip dengan Mario Galaxy atau Geometry Wars 3 di mana ketika pemain berjalan di sekitar "planet" gravitasi tampaknya menyesuaikan dan mereka tidak jatuh dari tepi objek seperti yang akan mereka lakukan jika gravitasi diperbaiki dalam satu arah.
(sumber: gameskinny.com )
Saya berhasil menerapkan sesuatu yang dekat dengan apa yang saya cari menggunakan pendekatan di mana objek yang seharusnya memiliki gravitasi menarik tubuh kaku lainnya ke arah itu, tetapi dengan menggunakan mesin fisika bawaan untuk Unity, menerapkan gerakan dengan AddForce dan sejenisnya, Aku hanya tidak bisa membuat gerakan itu terasa benar. Saya tidak bisa membuat pemain bergerak cukup cepat tanpa pemain mulai terbang dari permukaan objek dan saya tidak bisa menemukan keseimbangan yang baik antara gaya dan gravitasi yang diterapkan untuk mengakomodasi hal ini. Implementasi saya saat ini adalah adaptasi dari apa yang ditemukan di sini
Saya merasa solusinya mungkin masih akan menggunakan fisika untuk membuat pemain membumi ke objek jika mereka meninggalkan permukaan, tetapi begitu pemain telah membumi akan ada cara untuk menjepit pemain ke permukaan dan mematikan fisika dan Kontrol pemain melalui cara lain tapi saya benar-benar tidak yakin.
Pendekatan apa yang harus saya ambil untuk menjepret pemain ke permukaan benda? Perhatikan bahwa solusi harus bekerja dalam ruang 3D (tidak seperti 2D) dan harus dapat diimplementasikan menggunakan versi gratis Unity.
Jawaban:
Saya berhasil mencapai apa yang saya butuhkan, terutama dengan bantuan posting blog ini untuk memecahkan teka-teki permukaan dan muncul dengan ide-ide saya sendiri untuk pergerakan pemain dan kamera.
Gertakan Pemain ke Permukaan Objek
Pengaturan dasar terdiri dari bola besar (dunia) dan bola kecil (pemain) keduanya dengan spider collider melekat padanya.
Sebagian besar pekerjaan yang dilakukan adalah dalam dua metode berikut:
Itu
Vector3 movementDirection
parameter seperti kedengarannya, arah kita akan bergerak pemain kami dalam bingkai ini, dan menghitung vektor yang, sementara berakhir relatif sederhana dalam contoh ini, agak sulit bagi saya untuk mencari tahu pada awalnya. Lebih lanjut tentang itu nanti, tetapi perlu diingat bahwa itu adalah vektor yang dinormalisasi ke arah pemain menggerakkan frame ini.Melangkah melalui, hal pertama yang kita lakukan adalah memeriksa apakah sebuah sinar, yang berasal dari posisi masa depan hipotetis diarahkan ke para pemain vektor (-transform.up) hits dunia menggunakan WorldLayerMask yang merupakan properti publik LayerMask dari skrip. Jika Anda ingin tabrakan yang lebih kompleks atau beberapa lapisan, Anda harus membuat layer mask sendiri. Jika raycast berhasil mengenai sesuatu, hitInfo digunakan untuk mengambil titik normal dan hit untuk menghitung posisi baru dan rotasi pemain yang seharusnya tepat pada objek. Mengimbangi posisi pemain mungkin diperlukan tergantung pada ukuran dan asal objek pemain yang dimaksud.
Akhirnya, ini benar-benar hanya diuji dan kemungkinan hanya berfungsi dengan baik pada objek sederhana seperti bola. Sebagai posting blog saya mendasarkan solusi saya dari menyarankan, Anda mungkin ingin melakukan beberapa raycast dan rata-rata untuk posisi dan rotasi Anda untuk mendapatkan transisi yang jauh lebih baik ketika bergerak di medan yang lebih kompleks. Mungkin juga ada jebakan lain yang belum saya pikirkan saat ini.
Kamera dan Gerakan
Setelah pemain menempel ke permukaan objek, tugas selanjutnya untuk mengatasi adalah gerakan. Saya awalnya mulai dengan gerakan relatif terhadap pemain tetapi saya mulai mengalami masalah di kutub bola di mana arah tiba-tiba berubah membuat pemain saya dengan cepat mengubah arah berulang-ulang sehingga tidak membiarkan saya melewati kutub. Apa yang akhirnya saya lakukan adalah membuat gerakan pemain saya relatif terhadap kamera.
Apa yang bekerja dengan baik untuk kebutuhan saya adalah memiliki kamera yang benar-benar mengikuti pemain hanya berdasarkan posisi pemain. Akibatnya, meskipun kamera secara teknis berputar, menekan ke atas selalu menggerakkan pemain ke atas layar, turun ke bawah, dan begitu seterusnya dengan kiri dan kanan.
Untuk melakukan ini, berikut ini dilakukan pada kamera di mana objek target adalah pemain:
Akhirnya, untuk menggerakkan pemain, kami meningkatkan transformasi dari kamera utama sehingga dengan kendali kami naik, turun turun, dll. Dan di sinilah kami memanggil UpdatePlayerTransform yang akan membuat posisi kami tersentak ke objek dunia.
Untuk menerapkan kamera yang lebih menarik tetapi kontrolnya kurang lebih sama dengan apa yang kami miliki di sini, Anda dapat dengan mudah mengimplementasikan kamera yang tidak dirender atau hanya objek tiruan lainnya untuk dijadikan dasar pergerakan dan kemudian gunakan kamera yang lebih menarik untuk merender apa Anda ingin permainan terlihat seperti. Ini akan memungkinkan transisi kamera yang bagus saat Anda berkeliling objek tanpa merusak kontrol.
sumber
Saya pikir ide ini akan berhasil:
Menyimpan salinan sisi jala planet dari CPU. Memiliki simpul jala juga berarti Anda memiliki vektor normal untuk setiap titik di planet ini. Kemudian matikan sepenuhnya gravitasi untuk semua entitas, alih-alih berikan gaya tepat pada arah yang berlawanan dari vektor normal.
Sekarang, berdasarkan pada titik mana seharusnya vektor normal planet ini dihitung?
Jawaban termudah (yang saya yakin akan bekerja dengan baik) adalah perkiraan yang mirip dengan metode Newton : Ketika objek pertama kali bertelur, Anda tahu semua posisi awal mereka di planet ini. Gunakan posisi awal itu untuk menentukan
up
vektor setiap objek . Jelas gravitasi akan berada di arah yang berlawanan (menujudown
). Dalam bingkai berikutnya, sebelum menerapkan gravitasi, melemparkan sinar dari posisi baru objek kedown
vektor lamanya . Gunakan persimpangan sinar itu dengan planet sebagai referensi baru untuk menentukanup
vektor. Kasus sinar yang jarang mengenai apa pun berarti ada yang tidak beres dan Anda harus memindahkan objek Anda kembali ke posisi sebelumnya.Juga perhatikan bahwa menggunakan metode ini, asal pemain selanjutnya dari planet ini, semakin buruk perkiraannya. Oleh karena itu lebih baik menggunakan suatu tempat di sekitar kaki masing-masing pemain sebagai asal mereka. Saya menduga, tapi saya pikir menggunakan kaki sebagai asal juga akan menghasilkan penanganan dan navigasi pemain yang lebih mudah.
Catatan terakhir: Untuk hasil yang lebih baik, Anda bahkan dapat melakukan hal berikut: melacak pergerakan pemain di setiap frame (misalnya menggunakan
current_position - last_position
). Kemudian penjepit itumovement_vector
sehingga panjang menuju objekup
adalah nol. Sebut saja vektor baru inireference_movement
. Pindahkan sebelumnyareference_point
denganreference_movement
dan gunakan titik baru ini sebagai asal tracing ray. Setelah (dan jika) sinar itu mengenai planet ini, pindahlahreference_point
ke titik hit itu. Akhirnya, hitungup
vektor baru , dari yang baru inireference_point
.Beberapa kode semu untuk meringkasnya:
sumber
Posting ini bisa membantu. Intinya adalah, Anda tidak menggunakan pengendali karakter, tetapi buat sendiri menggunakan mesin fisika. Kemudian Anda menggunakan normals yang terdeteksi di bawah pemain untuk mengarahkan mereka ke permukaan mesh.
Berikut adalah ikhtisar teknik yang bagus. Ada lebih banyak sumber daya dengan istilah pencarian web seperti "unity walk on 3d objects mario galaxy".
Ada juga proyek demo dari unity 3.x yang memiliki mesin berjalan, dengan seorang prajurit dan seekor anjing dan di salah satu adegan. Ini menunjukkan berjalan di objek 3d Galaxy- style. Ini disebut sistem penggerak oleh runevision.
sumber
Rotasi
Lihat jawaban atas pertanyaan ini di answer.unity3d.com (sebenarnya ditanyakan oleh saya sendiri). Mengutip:
Berikut adalah kode yang dia sarankan kepada saya:
Sebut itu setiap pembaruan, dan Anda harus membuatnya berfungsi. (perhatikan bahwa kodenya dalam UnityScript ).
Kode yang sama dalam C # :
Gravitasi
Untuk gravitasi, Anda dapat menggunakan "teknik fisika planet" saya, yang saya jelaskan dalam pertanyaan saya, tetapi tidak benar-benar dioptimalkan. Itu hanya sesuatu yang ada dalam pikiran saya.
Saya sarankan Anda membuat sistem Anda sendiri untuk gravitasi.
Berikut ini adalah tutorial Youtube oleh Sebastian Lague . Itu solusi yang sangat bagus.
EDIT: Dalam kesatuan, pergi ke Edit > Pengaturan Proyek > Fisika dan atur semua nilai untuk Gravity ke 0 (Atau hapus Rigidbody dari semua objek), untuk mencegah gravitasi bawaan (yang hanya menarik pemain ke bawah) untuk berkonflik dengan solusi khusus. (matikan)
sumber