Bộ điều khiển trình phát hành tinh dựa trên thân cứng cho Unity

Khi tạo bộ điều khiển trình phát, trọng lực thường chỉ được áp dụng theo một hướng hướng xuống.

Nhưng còn trọng lực với một điểm trung tâm thì sao? Đây là công việc dành cho người đi bộ trên hành tinh.

Máy tập đi hành tinh là một loại bộ điều khiển cho phép người chơi đi trên một vật thể hình cầu (giống như các hành tinh), với trọng tâm nằm ở tâm quả cầu.

bước

Dưới đây là các bước để chế tạo khung tập đi có vật rắn hành tinh, với trọng tâm ở Unity:

  • Mở Cảnh với cấp độ tròn của bạn (trong trường hợp của tôi, tôi có mô hình hành tinh được tạo tùy chỉnh và Skybox tùy chỉnh trong Cảnh)

  • Tạo một tập lệnh mới, gọi nó là "SC_RigidbodyWalker" và dán mã bên dưới vào bên trong nó:

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;
    }
}
  • Tạo một tập lệnh mới, gọi nó là "SC_PlanetGravity" và dán đoạn mã bên dưới vào bên trong nó:

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);
        }
    }
}
  • Tạo một GameObject mới và gọi nó "Player"
  • Tạo một Capsule mới, di chuyển nó vào trong đối tượng "Player" và thay đổi vị trí của nó thành (0, 1, 0)
  • Loại bỏ thành phần Capsule Collider khỏi Capsule
  • Di chuyển Camera chính bên trong đối tượng "Player" và thay đổi vị trí của nó thành (0, 1.64, 0)
  • Đính kèm tập lệnh SC_RigidbodyWalker vào đối tượng "Player" (bạn sẽ nhận thấy nó sẽ thêm các thành phần bổ sung như Rigidbody và Capsule Collider).
  • Thay đổi Chiều cao máy va chạm viên nang thành 2 và Trung tâm thành (0, 1, 0)
  • Gán biến Camera chính cho biến Camera của người chơi trong SC_RigidbodyWalker
  • Cuối cùng, attach tập lệnh SC_PlanetGravity cho đối tượng "Player" và gán mô hình hành tinh của bạn cho biến Planet

Nhấn Play và quan sát Người chơi căn chỉnh với bề mặt hành tinh:

Sharp Coder Trình phát video