Menu
CoddyTech

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.

challenge icon

Défi

Moyen

Améliore la tour sélectionnée depuis son panneau.

  1. Écris public void UpgradeSelected() : sous maxLevel, lorsque game.TrySpend(data.UpgradeCost(level)) effectue le paiement, améliore la tour et actualise le panneau.
  2. À maxLevel, le panneau affiche Damage 4 et Range 5.5 sur deux lignes, ainsi que Max level, et un upgradeButton sérialisé n’est pas interactif.
  3. Dans Update, retourne lorsque EventSystem.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