Di chuyển người chơi nâng cao trong Unity

Trong hướng dẫn này, chúng ta sẽ khám phá cơ chế di chuyển nâng cao của người chơi trong Unity, bao gồm chạy nước rút, cúi người và hệ thống camera mượt mà. Các tính năng này tăng thêm chiều sâu và độ bóng bẩy cho các điều khiển của người chơi, nâng cao trải nghiệm chơi trò chơi tổng thể. Chúng ta sẽ sử dụng hệ thống vật lý của Unity để di chuyển và tương tác thực tế.

Thiết lập bối cảnh

Trước khi đi sâu vào mã hóa, chúng ta hãy thiết lập một cảnh cơ bản với một đối tượng người chơi và một camera:

  1. Tạo một dự án Unity mới.
  2. Trong Hierarchy, tạo một khối lập phương 3D, đổi tên thành Player và điều chỉnh tỷ lệ cho giống với một nhân vật (ví dụ: X: 1, Y: 2, Z: 1).
  3. Thêm thành phần Rigidbody vào Player và đặt thuộc tính Interpolate thành Interpolate để có hiệu ứng vật lý mượt mà.
  4. Thêm thành phần Capsule Collider, điều chỉnh chiều cao và bán kính cho phù hợp với mô hình người chơi.
  5. Tạo một GameObject rỗng, đặt tên là CameraRig và gắn Camera vào đó. Đặt camera ở phía sau và hơi cao hơn người chơi.
  6. Biến CameraRig thành đối tượng con của đối tượng Player để theo dõi chuyển động của đối tượng đó.

Triển khai chuyển động của người chơi nâng cao

Chúng tôi sẽ triển khai một tập lệnh xử lý các chuyển động cơ bản, chạy nước rút, cúi người và xoay camera mượt mà.

Tập lệnh PlayerMovement

using UnityEngine;

public class PlayerMovement : MonoBehaviour
{
    public float walkSpeed = 5f;
    public float sprintSpeed = 10f;
    public float crouchSpeed = 2.5f;
    public float jumpForce = 5f;
    public float gravity = 20f;

    public Transform cameraTransform;
    public float lookSensitivity = 2f;
    public float maxLookAngle = 80f;

    private Rigidbody rb;
    private float currentSpeed;
    private bool isCrouching = false;
    private bool isGrounded = false;

    private void Start()
    {
        rb = GetComponent();
        rb.freezeRotation = true; // Prevent the Rigidbody from rotating
    }

    private void Update()
    {
        HandleMovement();
        HandleJumping();
        HandleCrouching();
        HandleCameraRotation();
    }

    private void HandleMovement()
    {
        float moveHorizontal = Input.GetAxis("Horizontal");
        float moveVertical = Input.GetAxis("Vertical");

        Vector3 move = transform.right * moveHorizontal + transform.forward * moveVertical;
        move = move.normalized * currentSpeed * Time.deltaTime;

        Vector3 velocity = rb.velocity;
        velocity.x = move.x;
        velocity.z = move.z;
        rb.velocity = velocity;
    }

    private void HandleJumping()
    {
        if (Input.GetButtonDown("Jump") && isGrounded)
        {
            rb.velocity = new Vector3(rb.velocity.x, jumpForce, rb.velocity.z);
        }
    }

    private void HandleCrouching()
    {
        if (Input.GetKeyDown(KeyCode.LeftControl))
        {
            isCrouching = !isCrouching;
            currentSpeed = isCrouching ? crouchSpeed : walkSpeed;
            transform.localScale = new Vector3(1, isCrouching ? 0.5f : 1, 1);
        }

        if (Input.GetKey(KeyCode.LeftShift) && !isCrouching)
        {
            currentSpeed = sprintSpeed;
        }
        else if (!isCrouching)
        {
            currentSpeed = walkSpeed;
        }
    }

    private void HandleCameraRotation()
    {
        float mouseX = Input.GetAxis("Mouse X") * lookSensitivity;
        float mouseY = Input.GetAxis("Mouse Y") * lookSensitivity;

        Vector3 rotation = cameraTransform.localEulerAngles;
        rotation.y += mouseX;
        rotation.x -= mouseY;
        rotation.x = Mathf.Clamp(rotation.x, -maxLookAngle, maxLookAngle);

        cameraTransform.localEulerAngles = rotation;
    }

    private void OnCollisionStay(Collision collision)
    {
        if (collision.gameObject.CompareTag("Ground"))
        {
            isGrounded = true;
        }
    }

    private void OnCollisionExit(Collision collision)
    {
        if (collision.gameObject.CompareTag("Ground"))
        {
            isGrounded = false;
        }
    }
}

Các tính năng chính và giải thích

Kiểm soát chuyển động và tốc độ

Tập lệnh sử dụng Rigidbody của Unity để di chuyển người chơi, cho phép tương tác dựa trên vật lý. Tốc độ thay đổi tùy thuộc vào việc người chơi đang đi bộ, chạy nước rút hay cúi người. Ngả người được chuyển đổi bằng phím LeftControl và chạy nước rút diễn ra khi giữ phím LeftShift.

Nhảy

Phương pháp HandleJumping áp dụng lực hướng lên trên khi người chơi nhấn nút nhảy (mặc định: phím cách), với điều kiện là người chơi đang ở trên mặt đất. Phát hiện mặt đất được xử lý bằng cách kiểm tra va chạm với các vật thể được gắn thẻ "Ground".

Điều khiển máy ảnh

Độ xoay của camera được điều khiển bằng chuột, cung cấp góc nhìn thứ nhất hoặc thứ ba dựa trên vị trí của camera. Góc nhìn được cố định để tránh nghiêng quá mức, có thể khiến người chơi mất phương hướng.

Phần kết luận

Hướng dẫn này cung cấp nền tảng cho chuyển động nâng cao của người chơi trong Unity, bao gồm nhiều khía cạnh như điều khiển dựa trên vật lý, chạy nước rút, cúi người và quản lý camera. Các kỹ thuật này có thể được tùy chỉnh và mở rộng thêm để phù hợp với các thể loại và phong cách trò chơi khác nhau, nâng cao trải nghiệm của người chơi với các điều khiển phản hồi và chân thực.

Hãy nhớ rằng, chuyển động của người chơi là một khía cạnh quan trọng của trò chơi và cần được điều chỉnh cẩn thận để đảm bảo trải nghiệm của người chơi được thỏa mãn. Hãy thử nghiệm với các giá trị và tính năng khác nhau để tìm ra thiết lập tốt nhất cho dự án của bạn.