Menu
CoddyTech

תגמולים

שיעור 13 מתוך 25 בקורס משחק 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, הוסף את public static event Action<Enemy> Killed; והפעל את האירוע בתוך TakeDamage ממש לפני השמדת האויב.
  2. התחל את TakeDamage עם if (health <= 0) return;, כדי שהריגה תזכה בפרס פעם אחת בלבד.
  3. ב־GameManager, הוסף את public void Earn(int amount) (הוסף את הסכום והצג אותו), והירשם לאירוע Enemy.Killed כדי להרוויח את enemy.data.reward.

לחץ על "שחק": כמות הכסף גדלה בזמן שהצריחים פועלים. לאחר מכן לחץ על "בדיקה".

נסו בעצמכם

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: הגנת מגדלים

תרגלו בעצמכם: Unity אונליין