ترقية
الدرس 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()صحيحة.
اضغط «العب»، وابنِ برجًا، ثم انقر عليه ورقِّه مرتين: ستعرض اللوحة أنه بلغ المستوى الأقصى. ثم اضغط «تحقق».
جرّب بنفسك
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: الدفاع عن الأبراج
تدرّب بنفسك: Playground لـ Unity