מעבר בין מצבים
חלק מהיחידה בונים משחקים אמיתיים במסלול ה-Unity של Coddy. שיעור 15 מתוך 56.
כל מצב במשחק מבצע עבודה שונה בכל פריים. פקודת switch על שדה המצב ממקמת את העבודה הזאת במקרה אחד לכל מצב, ובכל פריים מופעל בדיוק מקרה אחד. שינוי המצב מתבצע דרך מתודה אחת, כך שהמסך תמיד תואם למצב. לקרב הבוס הזה יש פתיח, קרב ומסך ניצחון:
public enum Phase { Intro, Fight, Won }
public class BossFight : MonoBehaviour
{
public GameObject introPanel;
public GameObject fightPanel;
public GameObject winPanel;
public int bossHp = 10;
private Phase phase;
private float timer = 3f;
void Start()
{
Enter(Phase.Intro);
}
void Update()
{
switch (phase)
{
case Phase.Intro:
timer -= Time.deltaTime;
if (timer <= 0f) Enter(Phase.Fight);
break;
case Phase.Fight:
if (bossHp <= 0) Enter(Phase.Won);
break;
case Phase.Won:
break;
}
}
void Enter(Phase next)
{
phase = next;
introPanel.SetActive(next == Phase.Intro);
fightPanel.SetActive(next == Phase.Fight);
winPanel.SetActive(next == Phase.Won);
}
}כל מקרה מסתיים ב-break, כי C# לא מאפשרת לקמפל מקרה שממשיך לרוץ אל תוך המקרה הבא. כשהטיימר של הפתיח מסתיים, Enter(Phase.Fight) משנה את השלב, אבל מקרה Fight מופעל לראשונה רק בפריים הבא, כי הפריים הנוכחי כבר בחר את המקרה שלו. עם בלוקי if נפרדים זה אחר זה, פריים יכול להתחיל את הקרב ולהריץ את קוד הקרב באותו פריים.
Enter הוא המקום היחיד שבו phase משתנה. next == Phase.Fight הוא true רק עבור לוח הקרב, כך שקריאה אחת מציגה את הלוח הזה ומסתירה את שני האחרים. עבודה ששייכת לכניסה למצב, כמו איפוס טיימר, מתבצעת גם ב-Enter, ורצה פעם אחת במקום בכל פריים.
אתגר
קלמרוץ לחיצות: כמה פעמים אפשר ללחוץ על Space בתוך 5 שניות? ל-GameManager יש את המנייה GameState (Ready, Playing, GameOver), פאנל לכל מצב, ו-Start קוראת ל-SetState(GameState.Ready). כתבו את Update ואת SetState.
ב-Update, בצעו switch על state:
- Ready: לחיצה על Space מתחילה סיבוב. הלחיצה הזאת לא נחשבת ללחיצה.
- Playing: כל לחיצה על Space מוסיפה 1 ל-
tapsומציגה את המספר ב-tapsText, כך:Taps: 3. אחריroundTimeשניות (5), המשחק מסתיים. - GameOver: לחיצה על Space מחזירה ל-Ready.
SetState(GameState next) מגדירה את state ומציגה רק את הפאנל של המצב החדש. מעבר ל-Playing מתחיל סיבוב עם 0 לחיצות, Taps: 0 על המסך ו-roundTime שניות שנותרו; מעבר ל-GameOver מציג את התוצאה ב-resultText, כך: Taps: 3.
לחצו על Play, התחרו פעמיים ואז לחצו על Check.
נסו בעצמכם
using UnityEngine;
using TMPro;
public enum GameState { Ready, Playing, GameOver }
public class GameManager : MonoBehaviour
{
public GameObject readyPanel;
public GameObject playPanel;
public GameObject gameOverPanel;
public TMP_Text tapsText;
public TMP_Text resultText;
public float roundTime = 5f;
public GameState state;
private int taps;
private float timeLeft;
void Start()
{
SetState(GameState.Ready);
}
void Update()
{
// בצע מיתוג לפי state:
// Ready: לחיצה על Space מתחילה סיבוב
// Playing: לחיצה על Space נספרת כהקשה; כשהזמן נגמר, המשחק מסתיים
// GameOver: לחיצה על Space מחזירה ל-Ready
}
void SetState(GameState next)
{
state = next;
// הצג רק את הפאנל של המצב החדש
// סיבוב חדש מתחיל עם 0 הקשות ו-roundTime שניות; בסיום, resultText מציג את מספר ההקשות
}
}
השיעור הזה כולל חידון קצר. התחילו את השיעור כדי לענות עליו ולעקוב אחרי ההתקדמות.
כל השיעורים ביחידה בונים משחקים אמיתיים
10פרויקט: משחק פלטפורמה תלת־ממדי
המסלולפלטפורמות נעות2כפתורים ומסכים
כפתורים ו-onClickביטויי למבדהחיבור ב-Inspectorהפעלה וכיבוי של פאנליםפסי בריאותסיכום: חנות שדרוגים