Améliorer
Leçon 18 sur 25 du cours Jeu Unity : défense de tours de Coddy.
Le bouton Upgrade du panneau appelle UpgradeSelected. Il effectue le paiement via TrySpend de GameManager ; une bourse trop modeste ne change donc rien. Au niveau maximal, il n’y a plus rien à acheter : les statistiques affichent uniquement les valeurs actuelles, et le bouton n’est pas interactif.
Le panneau est une interface superposée à la vue 3D, et un clic sur son bouton est également une pression de souris détectée par BuildManager. Son rayon traverse le bouton et atteint le sol derrière lui, et BuildManager fermerait le panneau avant que le bouton ne soit relâché. EventSystem.current.IsPointerOverGameObject() renvoie true lorsque le pointeur se trouve au-dessus de l’interface, donc BuildManager quitte la fonction prématurément et laisse les boutons gérer ces clics.
Défi
MoyenAméliore la tour sélectionnée depuis son panneau.
- Écris
public void UpgradeSelected(): sousmaxLevel, lorsquegame.TrySpend(data.UpgradeCost(level))effectue le paiement, améliore la tour et actualise le panneau. - À
maxLevel, le panneau afficheDamage 4etRange 5.5sur deux lignes, ainsi queMax level, et unupgradeButtonsérialisé n’est pas interactif. - Dans
Update, retourne lorsqueEventSystem.current.IsPointerOverGameObject().
Appuie sur « Jouer », construis une tour, clique dessus et améliore-la deux fois : le panneau affiche Max level. Puis appuie sur « Vérifier ».
Essayez vous-même
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);
}
}
Toutes les leçons de Jeu Unity : défense de tours
Entraînez-vous par vous-même : Playground Unity