Menu
CoddyTech

מאגר עם תור

חלק מהיחידה ארכיטקטורת משחקים ב-Unity במסלול ה-Unity של Coddy. שיעור 47 מתוך 64.

בריכה צריכה מקום לשמור בו את האובייקטים הרזרביים שלה, ול־C# יש אוסף מתאים, Queue<T>: הפעולה Enqueue מוסיפה פריט לסוף, הפעולה Dequeue לוקחת את הפריט שבתחילה, ו־Count מציין כמה פריטים ממתינים. באקווריום הזה עולה בועה אחת כל 0.3 שניות, וכל בועה חוזרת לבריכה כשהיא מגיעה לפני המים:

using System.Collections.Generic;
using UnityEngine;

public class BubblePool : MonoBehaviour
{
    public GameObject bubblePrefab;
    private Queue<GameObject> pool = new Queue<GameObject>();
    private float timer;

    void Update()
    {
        timer += Time.deltaTime;
        if (timer >= 0.3f)
        {
            timer = 0f;
            Get(new Vector3(Random.Range(-2f, 2f), 0f, 0f));
        }
    }

    public GameObject Get(Vector3 position)
    {
        GameObject bubble;
        if (pool.Count > 0)
        {
            bubble = pool.Dequeue();
        }
        else
        {
            bubble = Instantiate(bubblePrefab);
            bubble.GetComponent<Bubble>().pool = this;
        }
        bubble.transform.position = position;
        bubble.SetActive(true);
        return bubble;
    }

    public void Return(GameObject bubble)
    {
        bubble.SetActive(false);
        pool.Enqueue(bubble);
    }
}
// Bubble.cs, על ה-prefab של הבועה
public BubblePool pool;

void Update()
{
    transform.Translate(0f, 2f * Time.deltaTime, 0f);
    if (transform.position.y > 5f) pool.Return(gameObject);
}

הפעולה Get בודקת קודם את Count, כי קריאה ל־Dequeue כשהתור ריק גורמת לחריגת InvalidOperationException. רק לאחר מכן היא יוצרת מופע באמצעות Instantiate, ורק לבועה חדשה צריך להגדיר את השדה pool: בבועה שנעשה בה שימוש חוזר הוא כבר מוגדר. התור מוסר קודם את הבועה שהמתינה הכי הרבה זמן — הראשונה שנכנסה היא הראשונה שיוצאת. בועה שמגיעה לפני המים קוראת ל־Return במקום ל־Destroy, ונשארת בסצנה כשהיא לא פעילה עד לקריאה הבאה ל־Get.

הפעולה Get ממקמת את הבועה לפני הקריאה ל־SetActive(true), כי הפעלתה מריצה מיד את OnEnable, וכל מה שקורה שם צריך לראות את המיקום החדש, ולא את המקום שבו הבועה נעלמה בפעם הקודמת. כך גם אובייקט שנעשה בו שימוש חוזר מתחיל מחדש: Awake ו־Start רצו פעם אחת, כשהבועה נוצרה, ואילו OnEnable רץ בכל קריאה ל־Get.

challenge icon

אתגר

בינוני

שמרו את עקבות הרגליים במאגר במקום להשמיד אותן.

  1. ב־Trail, שמרו עותקים נוספים ב־Queue<GameObject>. Return(footprint) מכבה את העקבה ומכניסה אותה לתור; Start יוצרת prewarm עקבות ומחזירה אותן.
  2. Get(position) מוציאה עותק נוסף מהתור (או יוצרת אחד), מציבה אותו ומפעילה אותו.
  3. ב־Footprint, החליפו את Destroy: אפסו את הגיל ב־OnEnable; אחרי life שניות, הפעילו את trail.Return(gameObject).

לחצו על "שחק" והתקדמו: עקבות הרגליים נעלמות אחרי 1.5 שניות. לאחר מכן לחצו על "בדיקה".

נסו בעצמכם

using System.Collections.Generic;
using UnityEngine;

public class Trail : MonoBehaviour
{
    public GameObject footprintPrefab;
    public float step = 1f;
    public int prewarm = 6;
    private Vector3 lastDrop;

    void Start()
    {
        lastDrop = transform.position;
        // מלאו את המאגר בעקבות מוכנות מראש
    }

    void Update()
    {
        if (Vector3.Distance(transform.position, lastDrop) >= step)
        {
            lastDrop = transform.position;
            Get(new Vector3(transform.position.x, 0.02f, transform.position.z));
        }
    }

    public GameObject Get(Vector3 position)
    {
        GameObject footprint = Instantiate(footprintPrefab, position, Quaternion.identity);
        footprint.GetComponent<Footprint>().trail = this;
        return footprint;
    }

    public void Return(GameObject footprint)
    {
        // עקבות רזרביות ממתינות במאגר
    }
}

כל השיעורים ביחידה ארכיטקטורת משחקים ב-Unity

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