Menu
CoddyTech
flag Ar iconالعربيةdown icon

إحصاءات الأسلحة

جزء من قسم هندسة الألعاب في Unity في رحلة Unity على Coddy. الدرس 20 من 50.

يقوم السيف والمطرقة بالشيء نفسه: يلوّحان، وينتظران، ثم يلوّحان مجددًا. ما يميّز أحدهما عن الآخر هو الأرقام. يسبب السيف 4 نقاط ضرر ويضرب كل 0.5 ثانية، بينما تسبب المطرقة 10 نقاط ضرر كل 1.5 ثانية. لذا يكفي استخدام سكربت Weapon لكليهما، وتُخزَّن أرقام كل سلاح في أصل:

[CreateAssetMenu(menuName = "Combat/Weapon Data")]
public class WeaponData : ScriptableObject
{
    public string weaponName;
    public int damage;
    public float swingTime;
    public GameObject hitEffect;
}
public class Weapon : MonoBehaviour
{
    public WeaponData data;
    private float nextSwing;

    public void Swing(Health target)
    {
        if (Time.time < nextSwing) return;
        nextSwing = Time.time + data.swingTime;
        target.TakeDamage(data.damage);
        Instantiate(data.hitEffect, target.transform.position, Quaternion.identity);
    }
}

يحتوي المشروع على أصل Sword (4، و0.5، ومسبق الإعداد لشرارة) وأصل Hammer (10، و1.5، ومسبق الإعداد لغبار). يحمل كلٌّ من الفارس والغول سكربت Weapon؛ ويحتوي الحقل data لدى الفارس على Sword، ولدى الغول على Hammer. أما الرمح فهو أصل إضافي يُنشأ من قائمة Create، دون الحاجة إلى تعديل أي سكربت. يمكن للأصل أن يشير إلى أصول مسبقة الإعداد وإلى أصول أخرى، كما يفعل hitEffect، لكن لا يمكنه الإشارة إلى كائنات في مشهد: فهو موجود في المشروع، خارج كل مشهد.

أما الطرق الأخرى للحصول على أسلحة مختلفة، فتضع الأرقام في الشيفرة. ينمو التعبير if (weaponName == "Sword") damage = 4; else if ... مع كل سلاح، كما أن إنشاء صنف فرعي Sword من Weapon لا يفعل سوى ضبط الأرقام يعني وجود صنف لكل أصل. تُستخدم الأصناف الفرعية للأسلحة التي تتصرف بطريقة مختلفة، مثل قوس يطلق السهام. أما السلاح الذي لا يفعل سوى إحداث ضرر أكبر أو التأرجح بسرعة أعلى، فيحتاج إلى أصل خاص به، دون أي شيفرة.

challenge icon

التحدي

متوسط

يوجد في ميدان الرماية أربعة أسلحة: مسدسان وبندقية وسلاح ناسف جديد. يؤدي الضغط باستمرار على Space إلى إطلاقها جميعًا. يختار سكربت Gun الرصاصة وفترة الإطلاق والضرر باستخدام if/else اعتمادًا على gunType، والسلاح الناسف غير موجود فيه، لذا لا يطلق النار (تحقّق من وحدة التحكم).

اجعل كل سلاح يقرأ أرقامه من أصل بيانات بدلًا من ذلك. الملف GunData.cs جاهز، وقد أُنشئت منه أصول Pistol وRifle وBlaster في المشروع، ولكل منها قالب الرصاصة الخاص به.

  • أضف إلى Gun حقلًا عامًا باسم data من النوع GunData؛ يضع المفتش أصل كل سلاح فيه.
  • أطلق data.bulletPrefab، وانتظر data.fireInterval بين الطلقات، واجعل ضرر كل رصاصة data.damage.
  • أزل gunType وحقلي الرصاصة والنسخ الخاصة وعبارة if/else.

اضغط على تشغيل واستمر في الضغط على Space، ثم اضغط على تحقّق.

جرّب بنفسك

using UnityEngine;
using UnityEngine.InputSystem;

public class Gun : MonoBehaviour
{
    public string gunType = "Pistol";
    public GameObject pistolBullet;
    public GameObject rifleBullet;
    private GameObject bulletPrefab;
    private float fireInterval;
    private int damage;
    private float nextShot;

    void Start()
    {
        if (gunType == "Pistol")
        {
            bulletPrefab = pistolBullet;
            fireInterval = 0.25f;
            damage = 1;
        }
        else if (gunType == "Rifle")
        {
            bulletPrefab = rifleBullet;
            fireInterval = 0.6f;
            damage = 4;
        }
    }

    void Update()
    {
        if (Keyboard.current.spaceKey.isPressed && Time.time >= nextShot)
        {
            nextShot = Time.time + fireInterval;
            GameObject bullet = Instantiate(bulletPrefab, transform.position + transform.forward, transform.rotation);
            bullet.GetComponent<Bullet>().damage = damage;
        }
    }
}
quiz iconاختبر نفسك

يتضمن هذا الدرس اختبارًا قصيرًا. ابدأ الدرس للإجابة عليه وتتبّع تقدمك.

جميع دروس هندسة الألعاب في Unity