Bộ điều khiển nhân vật 2D cho Unity

2D Platformer là một loại trò chơi trong đó người chơi nhảy giữa các nền tảng, tránh chướng ngại vật và chiến đấu với kẻ thù, tất cả đều được quan sát từ góc nhìn phụ 2D.

Sharp Coder Trình phát video

Để tạo Bộ điều khiển nhân vật nền tảng 2D trong Unity, hãy làm theo các bước bên dưới.

Bộ điều khiển sẽ dựa trên vật lý và sẽ sử dụng thành phần Rigidbody2D.

bước

  • Mở Cảnh với cấp độ 2D của bạn (đảm bảo các mô hình cấp độ có gắn bộ va chạm 2D để người chơi không bị rơi)
  • Tạo một GameObject mới và gọi nó "Player"
  • Tạo một GameObject khác, gọi nó là "player_sprite" và thêm thành phần Sprite Renderer vào nó
  • Gán sprite của bạn cho "player_sprite" và di chuyển nó vào trong Đối tượng "Player"

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

CharacterController2D.cs

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

[RequireComponent(typeof(Rigidbody2D))]
[RequireComponent(typeof(CapsuleCollider2D))]

public class CharacterController2D : MonoBehaviour
{
    // Move player in 2D space
    public float maxSpeed = 3.4f;
    public float jumpHeight = 6.5f;
    public float gravityScale = 1.5f;
    public Camera mainCamera;

    bool facingRight = true;
    float moveDirection = 0;
    bool isGrounded = false;
    Vector3 cameraPos;
    Rigidbody2D r2d;
    CapsuleCollider2D mainCollider;
    Transform t;

    // Use this for initialization
    void Start()
    {
        t = transform;
        r2d = GetComponent<Rigidbody2D>();
        mainCollider = GetComponent<CapsuleCollider2D>();
        r2d.freezeRotation = true;
        r2d.collisionDetectionMode = CollisionDetectionMode2D.Continuous;
        r2d.gravityScale = gravityScale;
        facingRight = t.localScale.x > 0;

        if (mainCamera)
        {
            cameraPos = mainCamera.transform.position;
        }
    }

    // Update is called once per frame
    void Update()
    {
        // Movement controls
        if ((Input.GetKey(KeyCode.A) || Input.GetKey(KeyCode.D)) && (isGrounded || Mathf.Abs(r2d.velocity.x) > 0.01f))
        {
            moveDirection = Input.GetKey(KeyCode.A) ? -1 : 1;
        }
        else
        {
            if (isGrounded || r2d.velocity.magnitude < 0.01f)
            {
                moveDirection = 0;
            }
        }

        // Change facing direction
        if (moveDirection != 0)
        {
            if (moveDirection > 0 && !facingRight)
            {
                facingRight = true;
                t.localScale = new Vector3(Mathf.Abs(t.localScale.x), t.localScale.y, transform.localScale.z);
            }
            if (moveDirection < 0 && facingRight)
            {
                facingRight = false;
                t.localScale = new Vector3(-Mathf.Abs(t.localScale.x), t.localScale.y, t.localScale.z);
            }
        }

        // Jumping
        if (Input.GetKeyDown(KeyCode.W) && isGrounded)
        {
            r2d.velocity = new Vector2(r2d.velocity.x, jumpHeight);
        }

        // Camera follow
        if (mainCamera)
        {
            mainCamera.transform.position = new Vector3(t.position.x, cameraPos.y, cameraPos.z);
        }
    }

    void FixedUpdate()
    {
        Bounds colliderBounds = mainCollider.bounds;
        float colliderRadius = mainCollider.size.x * 0.4f * Mathf.Abs(transform.localScale.x);
        Vector3 groundCheckPos = colliderBounds.min + new Vector3(colliderBounds.size.x * 0.5f, colliderRadius * 0.9f, 0);
        // Check if player is grounded
        Collider2D[] colliders = Physics2D.OverlapCircleAll(groundCheckPos, colliderRadius);
        //Check if any of the overlapping colliders are not player collider, if so, set isGrounded to true
        isGrounded = false;
        if (colliders.Length > 0)
        {
            for (int i = 0; i < colliders.Length; i++)
            {
                if (colliders[i] != mainCollider)
                {
                    isGrounded = true;
                    break;
                }
            }
        }

        // Apply movement velocity
        r2d.velocity = new Vector2((moveDirection) * maxSpeed, r2d.velocity.y);

        // Simple debug
        Debug.DrawLine(groundCheckPos, groundCheckPos - new Vector3(0, colliderRadius, 0), isGrounded ? Color.green : Color.red);
        Debug.DrawLine(groundCheckPos, groundCheckPos - new Vector3(colliderRadius, 0, 0), isGrounded ? Color.green : Color.red);
    }
}
  • Đính kèm tập lệnh CharacterController2D vào Đối tượng "Player" (Bạn sẽ nhận thấy nó cũng đã thêm các thành phần khác có tên Rigidbody2D và CapsuleCollider2D)
  • Tinh chỉnh kích thước CapsuleCollider2D cho đến khi chúng khớp với Sprite của người chơi
  • Đảm bảo không có máy va chạm con nào và CapsuleCollider2D là máy va chạm duy nhất được gắn vào trình phát này

Trong tập lệnh CharacterController2D có một tùy chọn để gán biến Camera chính có thể là bất kỳ Camera nào đi theo người chơi:

Bộ điều khiển nhân vật 2D hiện đã sẵn sàng!

Bài viết được đề xuất
Hướng dẫn nhảy tường 3D và 2D của người chơi cho Unity
Thêm hỗ trợ nhảy đôi vào bộ điều khiển nhân vật nền tảng 2D trong Unity
Bộ điều khiển nhân vật Cách thêm khả năng đẩy các vật cứng trong Unity
Bộ điều khiển ô tô cho Unity
Bộ điều khiển máy bay cho Unity
Hướng dẫn sử dụng đèn pin cho Unity
Hướng dẫn sử dụng bộ điều khiển Worm 3D cho Unity