Menu
CoddyTech

תגמולים

שיעור 10 מתוך 18 בקורס משחק Unity: הגנת מגדלים של Coddy.

כל אויב שמגדל מחסל מעניק את ה־reward שלו. ה־Enemy מדווח על החיסול כפי שהוא מדווח על הגעה לבסיס, באמצעות אירוע סטטי, Killed, וה־GameManager מאזין לו ומוסיף את הכסף.

חיסול חייב להעניק תגמול פעם אחת. Destroy לא מסיר אובייקט מיד: הוא מוסר אותו בסוף הפריים, ועד אז הוא עדיין במשחק. שתי יריות יכולות לפגוע באותו פריים, והשנייה מוצאת אויב עם 0 בריאות שעדיין נמצא שם. אם TakeDamage מדווח על חיסול בכל פעם שהבריאות היא 0 או פחות, הירייה השנייה מעניקה תגמול שוב. במשחק בלונים עם חיצים יש אותה מלכודת, ומשתנה bool פותר אותה:

public void Pop()
{
    if (popped)
    {
        return;
    }

    popped = true;
    Popped?.Invoke(this);
    Destroy(gameObject);
}

האויב לא צריך משתנה bool נוסף, מפני שהבריאות שלו כבר מציינת אם הוא מת: ל־TakeDamage שמוצא שהבריאות היא 0 או פחות אין עוד מה לעשות.

challenge icon

אתגר

בינוני
  1. ב־Enemy, הכריזו על אירוע סטטי ציבורי בשם Killed (Action<Enemy>). הפעילו אותו עם האויב כאשר TakeDamage מוריד את הבריאות שלו ל־0 או פחות, ממש לפני השמדתו.
  2. הריגה מזכה פעם אחת: כאשר קוראים ל־TakeDamage עבור אויב שהבריאות שלו כבר 0 או פחות, לא קורה דבר.
  3. ב־GameManager, הוסיפו את public void Earn(int amount), שמוסיף לכסף ומציג אותו. הירשמו ל־Enemy.Killed לצד ReachedBase, והוסיפו את ה־reward של האויב שנהרג.

לחצו על Play וצפו בכסף גדל כשהמגדלים פועלים, ואז לחצו על Check.

נסו בעצמכם

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

public class Enemy : MonoBehaviour, IDamageable
{
    public static readonly List<Enemy> All = new List<Enemy>();
    public static event Action<Enemy> ReachedBase;

    public EnemyData data;
    public Transform[] waypoints;

    private int next = 1;
    private int health;

    void Awake()
    {
        health = data.maxHealth;
    }

    void OnEnable()
    {
        All.Add(this);
    }

    void OnDisable()
    {
        All.Remove(this);
    }

    void Update()
    {
        Vector3 target = waypoints[next].position;
        transform.position = Vector3.MoveTowards(transform.position, target, data.speed * Time.deltaTime);
        if (transform.position == target)
        {
            next++;
            if (next == waypoints.Length)
            {
                ReachedBase?.Invoke(this);
                Destroy(gameObject);
            }
        }
    }

    public void TakeDamage(int amount)
    {
        health -= amount;
        if (health <= 0)
        {
            Destroy(gameObject);
        }
    }
}
quiz iconבחנו את עצמכם

השיעור הזה כולל חידון קצר. התחילו את השיעור כדי לענות עליו ולעקוב אחרי ההתקדמות.

כל השיעורים ביחידה משחק Unity: הגנת מגדלים