שדרוג
שיעור 18 מתוך 25 בקורס משחק Unity: הגנת מגדלים של Coddy.
כפתור השדרוג בלוח מפעיל את UpgradeSelected. התשלום מתבצע דרך TrySpend של GameManager, כך שיתרה נמוכה לא משנה דבר. ברמה המרבית אין עוד מה לקנות: הנתונים מציגים רק את הערכים הנוכחיים, ואי אפשר ללחוץ על הכפתור.
הלוח הוא ממשק משתמש שמוצג מעל תצוגת התלת־ממד, ולחיצה על הכפתור שלו נחשבת גם ללחיצת עכבר ש-BuildManager מזהה. הקרן שלו עוברת דרך הכפתור אל הקרקע שמאחוריו, ו-BuildManager יסגור את הלוח לפני שחרור הכפתור. EventSystem.current.IsPointerOverGameObject() מחזיר true כשהסמן נמצא מעל ממשק המשתמש, ולכן BuildManager חוזר מוקדם ומשאיר את הלחיצות האלה לטיפול הכפתורים.
אתגר
בינונישדרגו את המגדל שנבחר דרך הלוח שלו.
- כתבו
public void UpgradeSelected(): מתחת ל־maxLevel, כאשרgame.TrySpend(data.UpgradeCost(level))מצליח לשלם, שדרגו את המגדל ורעננו את הלוח. - ב־
maxLevel, הלוח מציגDamage 4ו־Range 5.5בשתי שורות, וגםMax level, וכפתורupgradeButtonשסומן לסריאליזציה אינו ניתן להפעלה. - ב־
Update, החזירו את הפעולה כאשרEventSystem.current.IsPointerOverGameObject().
לחצו על "שחק", בנו מגדל, לחצו עליו ושדרגו אותו פעמיים: הלוח מציג Max level. לאחר מכן לחצו על "בדיקה".
נסו בעצמכם
using UnityEngine;
using UnityEngine.InputSystem;
using UnityEngine.UI;
using TMPro;
public class BuildManager : MonoBehaviour
{
[SerializeField] private GameManager game;
[SerializeField] private Tower[] shop;
[SerializeField] private Button[] shopButtons;
[SerializeField] private Color chosenColor = new Color(1f, 0.85f, 0.3f);
[SerializeField] private GameObject towerPanel;
[SerializeField] private TMP_Text towerNameText;
[SerializeField] private TMP_Text towerStatsText;
[SerializeField] private TMP_Text upgradeLabel;
private Tower chosen;
private Tower selected;
void Start()
{
for (int i = 0; i < shop.Length; i++)
{
Tower prefab = shop[i];
shopButtons[i].GetComponentInChildren<TMP_Text>().text = prefab.data.towerName + "\n" + prefab.data.cost;
shopButtons[i].onClick.AddListener(() => Choose(prefab));
}
Choose(shop[0]);
Select(null);
}
void Choose(Tower prefab)
{
chosen = prefab;
for (int i = 0; i < shop.Length; i++)
{
shopButtons[i].image.color = shop[i] == chosen ? chosenColor : Color.white;
}
}
void Update()
{
if (!Mouse.current.leftButton.wasPressedThisFrame)
{
return;
}
Ray ray = Camera.main.ScreenPointToRay(Mouse.current.position.ReadValue());
if (!Physics.Raycast(ray, out RaycastHit hit))
{
Select(null);
return;
}
Tower tower = hit.collider.GetComponentInParent<Tower>();
if (tower != null)
{
Select(tower);
return;
}
Select(null);
if (hit.collider.TryGetComponent(out BuildPad pad))
{
Build(pad);
}
}
void Build(BuildPad pad)
{
if (pad.tower != null)
{
return;
}
if (!game.TrySpend(chosen.data.cost))
{
Debug.Log("Not enough money");
return;
}
pad.tower = Instantiate(chosen, pad.transform.position, Quaternion.identity);
}
void Select(Tower tower)
{
selected = tower;
towerPanel.SetActive(tower != null);
if (tower != null)
{
ShowPanel();
}
}
void ShowPanel()
{
TowerData data = selected.data;
int level = selected.Level;
towerNameText.text = data.towerName + " level " + level;
towerStatsText.text = "Damage " + data.DamageAt(level) + " > " + data.DamageAt(level + 1)
+ "\nRange " + data.RangeAt(level) + " > " + data.RangeAt(level + 1);
upgradeLabel.text = "Upgrade " + data.UpgradeCost(level);
}
}
כל השיעורים ביחידה משחק Unity: הגנת מגדלים
תרגלו בעצמכם: Unity אונליין