Pengontrol Pemain Planetary berbasis benda kaku untuk Unity

Saat membuat pengontrol pemain, gravitasi biasanya diterapkan hanya dalam satu arah, yaitu ke bawah.

Tapi bagaimana dengan gravitasi dengan titik pusat? Ini adalah pekerjaan untuk penjelajah planet.

Planetary walker adalah jenis pengontrol yang memungkinkan pemain berjalan di atas benda berbentuk bola (seperti planet), dengan pusat gravitasi berada di tengah bola.

Langkah

Berikut langkah-langkah membuat alat bantu jalan planetary rigidbody walker, dengan titik pusat gravitasi di Unity:

  • Buka Adegan dengan level melingkar Anda (dalam kasus saya, saya memiliki model planet yang dibuat khusus dan Skybox khusus di Adegan)

  • Buat skrip baru, beri nama "SC_RigidbodyWalker" dan tempel kode di bawah ini di dalamnya:

SC_RigidbodyWalker.cs

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

[RequireComponent(typeof(Rigidbody))]
[RequireComponent(typeof(CapsuleCollider))]

public class SC_RigidbodyWalker : MonoBehaviour
{
    public float speed = 5.0f;
    public bool canJump = true;
    public float jumpHeight = 2.0f;
    public Camera playerCamera;
    public float lookSpeed = 2.0f;
    public float lookXLimit = 60.0f;

    bool grounded = false;
    Rigidbody r;
    Vector2 rotation = Vector2.zero;
    float maxVelocityChange = 10.0f;

    void Awake()
    {
        r = GetComponent<Rigidbody>();
        r.freezeRotation = true;
        r.useGravity = false;
        r.collisionDetectionMode = CollisionDetectionMode.ContinuousDynamic;
        rotation.y = transform.eulerAngles.y;

        Cursor.lockState = CursorLockMode.Locked;
        Cursor.visible = false;
    }

    void Update()
    {
        // Player and Camera rotation
        rotation.x += -Input.GetAxis("Mouse Y") * lookSpeed;
        rotation.x = Mathf.Clamp(rotation.x, -lookXLimit, lookXLimit);
        playerCamera.transform.localRotation = Quaternion.Euler(rotation.x, 0, 0);
        Quaternion localRotation = Quaternion.Euler(0f, Input.GetAxis("Mouse X") * lookSpeed, 0f);
        transform.rotation = transform.rotation * localRotation;
    }

    void FixedUpdate()
    {
        if (grounded)
        {
            // Calculate how fast we should be moving
            Vector3 forwardDir = Vector3.Cross(transform.up, -playerCamera.transform.right).normalized;
            Vector3 rightDir = Vector3.Cross(transform.up, playerCamera.transform.forward).normalized;
            Vector3 targetVelocity = (forwardDir * Input.GetAxis("Vertical") + rightDir * Input.GetAxis("Horizontal")) * speed;

            Vector3 velocity = transform.InverseTransformDirection(r.velocity);
            velocity.y = 0;
            velocity = transform.TransformDirection(velocity);
            Vector3 velocityChange = transform.InverseTransformDirection(targetVelocity - velocity);
            velocityChange.x = Mathf.Clamp(velocityChange.x, -maxVelocityChange, maxVelocityChange);
            velocityChange.z = Mathf.Clamp(velocityChange.z, -maxVelocityChange, maxVelocityChange);
            velocityChange.y = 0;
            velocityChange = transform.TransformDirection(velocityChange);

            r.AddForce(velocityChange, ForceMode.VelocityChange);

            if (Input.GetButton("Jump") && canJump)
            {
               r.AddForce(transform.up * jumpHeight, ForceMode.VelocityChange);
            }
        }

        grounded = false;
    }

    void OnCollisionStay()
    {
        grounded = true;
    }
}
  • Buat skrip baru, beri nama "SC_PlanetGravity" dan tempel kode di bawah ini di dalamnya:

SC_PlanetGravity.cs

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class SC_PlanetGravity : MonoBehaviour
{
    public Transform planet;
    public bool alignToPlanet = true;

    float gravityConstant = 9.8f;
    Rigidbody r;

    void Start()
    {
        r = GetComponent<Rigidbody>();
    }

    void FixedUpdate()
    {
        Vector3 toCenter = planet.position - transform.position;
        toCenter.Normalize();

        r.AddForce(toCenter * gravityConstant, ForceMode.Acceleration);

        if (alignToPlanet)
        {
            Quaternion q = Quaternion.FromToRotation(transform.up, -toCenter);
            q = q * transform.rotation;
            transform.rotation = Quaternion.Slerp(transform.rotation, q, 1);
        }
    }
}
  • Buat GameObject baru dan beri nama "Player"
  • Buat Capsule baru, pindahkan ke dalam objek "Player", dan ubah posisinya menjadi (0, 1, 0)
  • Lepaskan komponen Capsule Collider dari Kapsul
  • Pindahkan Kamera Utama ke dalam objek "Player" dan ubah posisinya menjadi (0, 1.64, 0)
  • Lampirkan skrip SC_RigidbodyWalker ke objek "Player" (Anda akan melihat skrip ini akan menambahkan komponen tambahan seperti Rigidbody dan Capsule Collider).
  • Ubah Tinggi Capsule Collider menjadi 2 dan Pusat menjadi (0, 1, 0)
  • Tetapkan Kamera Utama ke variabel Kamera Pemain di SC_RigidbodyWalker
  • Terakhir, attach skrip SC_PlanetGravity ke objek "Player" dan tetapkan model planet Anda ke variabel Planet

Tekan Putar dan amati Pemain sejajar dengan permukaan planet:

Sharp Coder Pemutar video

Artikel yang Disarankan
Menciptakan Pergerakan Pemain dalam Kesatuan
Pengontrol Karakter Cara Menambahkan Kemampuan untuk Mendorong Benda Kaku di Unity
Tutorial Lompat Dinding 3D dan 2D Pemain untuk Unity
Sistem Dialog untuk Persatuan
Pengontrol Karakter 2D untuk Unity
Tutorial Pengontrol Pemain Top-Down untuk Unity
Pengontrol Pemain RTS dan MOBA untuk Unity