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:
private void UpdatePlayerTransform(Vector3 movementDirection)
{
RaycastHit hitInfo;
if (GetRaycastDownAtNewPosition(movementDirection, out hitInfo))
{
Quaternion targetRotation = Quaternion.FromToRotation(Vector3.up, hitInfo.normal);
Quaternion finalRotation = Quaternion.RotateTowards(transform.rotation, targetRotation, float.PositiveInfinity);
transform.rotation = finalRotation;
transform.position = hitInfo.point + hitInfo.normal * .5f;
}
}
private bool GetRaycastDownAtNewPosition(Vector3 movementDirection, out RaycastHit hitInfo)
{
Vector3 newPosition = transform.position;
Ray ray = new Ray(transform.position + movementDirection * Speed, -transform.up);
if (Physics.Raycast(ray, out hitInfo, float.PositiveInfinity, WorldLayerMask))
{
return true;
}
return false;
}
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:
private void FixedUpdate()
{
// Calculate and set camera position
Vector3 desiredPosition = this.target.TransformPoint(0, this.height, -this.distance);
this.transform.position = Vector3.Lerp(this.transform.position, desiredPosition, Time.deltaTime * this.damping);
// Calculate and set camera rotation
Quaternion desiredRotation = Quaternion.LookRotation(this.target.position - this.transform.position, this.target.up);
this.transform.rotation = Quaternion.Slerp(this.transform.rotation, desiredRotation, Time.deltaTime * this.rotationDamping);
}
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.
void Update ()
{
Vector3 movementDirection = Vector3.zero;
if (Input.GetAxisRaw("Vertical") > 0)
{
movementDirection += cameraTransform.up;
}
else if (Input.GetAxisRaw("Vertical") < 0)
{
movementDirection += -cameraTransform.up;
}
if (Input.GetAxisRaw("Horizontal") > 0)
{
movementDirection += cameraTransform.right;
}
else if (Input.GetAxisRaw("Horizontal") < 0)
{
movementDirection += -cameraTransform.right;
}
movementDirection.Normalize();
UpdatePlayerTransform(movementDirection);
}
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.