Verbessern
Lektion 18 von 25 im Kurs Unity-Spiel: Tower Defense von Coddy.
Die Schaltfläche „Verbessern“ des Panels ruft UpgradeSelected auf. Sie bezahlt über das TrySpend des GameManager, sodass ein knappes Budget nichts ändert. Auf der höchsten Stufe gibt es nichts mehr zu kaufen: Die Werte zeigen nur die aktuellen Werte an, und die Schaltfläche ist nicht interaktiv.
Das Panel liegt als UI über der 3D-Ansicht, und ein Klick auf seine Schaltfläche ist auch ein Mausklick, den der BuildManager wahrnimmt. Sein Strahl geht durch die Schaltfläche hindurch auf den Boden dahinter, und der BuildManager würde das Panel schließen, bevor die Schaltfläche losgelassen wird. EventSystem.current.IsPointerOverGameObject() ist wahr, solange sich der Mauszeiger über der UI befindet. Daher kehrt der BuildManager vorzeitig zurück und überlässt diese Klicks den Schaltflächen.
Aufgabe
MittelRüste den ausgewählten Turm über sein Bedienfeld auf.
- Schreibe
public void UpgradeSelected(): Unterhalb vonmaxLevelwird der Turm aufgerüstet und das Bedienfeld aktualisiert, wenngame.TrySpend(data.UpgradeCost(level))die Kosten bezahlt. - Bei
maxLevelzeigt das BedienfeldDamage 4undRange 5.5in zwei Zeilen sowieMax levelan, und ein serialisierterupgradeButtonist nicht interaktiv. - Gib in
Updatezurück, wennEventSystem.current.IsPointerOverGameObject()zutrifft.
Drücke „Spielen“, baue einen Turm, klicke darauf und rüste ihn zweimal auf: Das Bedienfeld zeigt Max level an. Drücke dann „Prüfen“.
Probier es selbst
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);
}
}
Alle Lektionen in Unity-Spiel: Tower Defense
Übe selbstständig: Unity-Playground