إحصاءات الأسلحة
جزء من قسم هندسة الألعاب في Unity في رحلة Unity على Coddy. الدرس 24 من 64.
السيف والمطرقة يفعلان الشيء نفسه: يلوّحان، وينتظران، ثم يلوّحان مجددًا. ما يميّز أحدهما عن الآخر هو الأرقام. يُلحق السيف ضررًا قدره 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);
}
}يحتوي المشروع على أصل للسيف (4، و0.5، ونسخة مسبقة من تأثير شرارة) وأصل للمطرقة (10، و1.5، ونسخة مسبقة من تأثير غبار). يحمل كلٌّ من الفارس والغول سكربت Weapon؛ ويحتوي الحقل data لدى الفارس على السيف، ولدى الغول على المطرقة. والرمح أصل آخر يُنشأ من قائمة Create، من دون تغيير أي سكربت. يمكن للأصل أن يشير إلى نسخ مسبقة وإلى أصول أخرى، كما يفعل hitEffect، لكنه لا يمكنه الإشارة إلى كائنات في مشهد: فهو موجود في المشروع، خارج كل مشهد.
أما الطرق الأخرى للحصول على أسلحة مختلفة، فتضع الأرقام في الشيفرة. يتوسع if (weaponName == "Sword") damage = 4; else if ... مع كل سلاح، كما أن إنشاء فئة فرعية Sword من Weapon لا تفعل سوى تعيين الأرقام يعني إنشاء فئة لكل أصل. الفئات الفرعية مخصصة للأسلحة التي تتصرف على نحو مختلف، مثل قوس يطلق السهام. أما السلاح الذي لا يفعل سوى إلحاق ضرر أكبر أو الضرب بسرعة أعلى، فيحتاج إلى أصل خاص به، ولا يحتاج إلى أي شيفرة.
التحدي
متوسطاجعل كل سلاح يقرأ أرقامه من أصل GunData الخاص به.
- في
Gun، أضفpublic GunData data;. - أطلق
data.bulletPrefab، وانتظرdata.fireIntervalبين الطلقات، وامنح كل رصاصةdata.damage. - احذف
gunType، وحقلي الرصاص، والنسخ الخاصة الثلاث، وStart().
اضغط على «العب» واستمر في الضغط على 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;
}
}
}
جميع دروس هندسة الألعاب في Unity
1المكوّنات، لا التسلسلات الهرمية
مكوّنات صغيرةنص برمجي أساسي للعدومكوّنات مجرّدةالمكوّنات تعمل معًامراجعة: برج معياريمراجعة: مدفع مزدوج4البيانات المُسلسلة
الأصناف القابلة للتسلسلالقوائم في Inspectorالتعدادات في Inspectorمراجعة: جدول الغنائممراجعة: اختيار الغنائم عشوائيًا2الواجهات في Unity
IDamageableالواجهات وTryGetComponentGetComponentsمراجعة: مفتاح التفاعلمراجعة: أقرب عنصر ضمن النطاق5ScriptableObjects
أصول البياناتإحصاءات الأسلحةالإعدادات المشتركةأنقذ الرياحالموجات كبياناتمراجعة: قاعدة بيانات العناصرمراجعة: الشراء من المتجرتدرّب بنفسك: Playground لـ Unity