وحدة تحكم الأحرف ثنائية الأبعاد للوحدة

2D Platformer هي نوع من الألعاب حيث يقفز اللاعب بين المنصات، ويتجنب العوائق، ويقاتل الأعداء، وكل ذلك يمكن ملاحظته من منظور عرض جانبي ثنائي الأبعاد.

Sharp Coder مشغل فديوهات

لإنشاء وحدة تحكم شخصيات منصة ثنائية الأبعاد في Unity، اتبع الخطوات أدناه.

ستكون وحدة التحكم قائمة على الفيزياء وستستخدم مكون Rigidbody2D.

خطوات

  • افتح المشهد بمستواك ثنائي الأبعاد (تأكد من أن النقوش المتحركة للمستوى تحتوي على مصادمات ثنائية الأبعاد، حتى لا يسقط اللاعب)
  • قم بإنشاء GameObject جديد وقم بتسميته "Player"
  • قم بإنشاء GameObject آخر، وأطلق عليه اسم "player_sprite" وأضف مكون Sprite Renderer إليه
  • قم بتعيين الكائن الخاص بك إلى "player_sprite" وحركه داخل الكائن "Player"

  • قم بإنشاء سكريبت جديد، وقم بتسميته "CharacterController2D" والصق الكود أدناه بداخله:

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);
    }
}
  • قم بإرفاق البرنامج النصي CharacterController2D بالكائن "Player" (ستلاحظ أنه أضاف أيضًا مكونات أخرى تسمى Rigidbody2D وCapsuleCollider2D)
  • قم بتعديل أبعاد CapsuleCollider2D حتى تتطابق مع اللاعب Sprite
  • تأكد من عدم وجود مصادمات فرعية وأن CapsuleCollider2D هو المصادم الوحيد الملحق بهذا المشغل

يوجد في البرنامج النصي CharacterController2D خيار لتعيين متغير الكاميرا الرئيسية والذي يمكن أن يكون أي كاميرا تتبع اللاعب:

وحدة التحكم بالأحرف ثنائية الأبعاد جاهزة الآن!