Menu
CoddyTech

Potenziamento

Lezione 12 di 18 del corso Gioco Unity: difesa della torre di Coddy.

Facendo clic su una torre si apre un pannello con il suo livello e un pulsante Upgrade. Ogni livello aumenta i danni e la gittata della torre, e ogni potenziamento costa più del precedente. I livelli seguono una regola, quindi l’asset contiene la regola anziché un elenco di numeri: le statistiche al livello 1, quanto aggiunge ogni livello e il prezzo di un potenziamento. I metodi di ScriptableObject calcolano il resto, così ogni script che lo richiede ottiene la stessa risposta. Il raccolto di un gioco agricolo:

public int YieldAt(int level)
{
    return baseYield + yieldPerLevel * (level - 1);
}

La torre conserva solo il proprio level, e il pannello mostra i numeri del livello successivo accanto a quelli attuali, così il giocatore vede cosa ottiene in cambio dei soldi. Un clic su una torre colpisce una delle sue parti, la base o la testa, che sono figlie della torre, quindi hit.collider.GetComponentInParent<Tower>() trova la torre a cui appartengono: cerca sull’oggetto colpito, poi risale ai suoi genitori.

Il pannello è un’interfaccia UI sovrapposta alla visuale 3D, e un clic sul suo pulsante Upgrade è anche una pressione del mouse che BuildManager rileva. Il suo raggio attraversa il pulsante e raggiunge il terreno dietro di esso, e BuildManager chiude il pannello prima che il pulsante venga rilasciato. EventSystem.current.IsPointerOverGameObject() è true mentre il puntatore si trova sopra la UI, quindi BuildManager ritorna subito e lascia che siano i pulsanti a gestire quei clic.

challenge icon

Sfida

Medio
  1. In TowerData, aggiungi gli interi pubblici maxLevel, upgradeCost e damagePerLevel, e il float pubblico rangePerLevel. Aggiungi int DamageAt(int level) e float RangeAt(int level): il livello 1 ha il danno e la portata propri dell’asset, mentre ogni livello successivo aggiunge la quantità per livello. Aggiungi int UpgradeCost(int level), il prezzo per passare da quel livello al successivo: upgradeCost moltiplicato per il livello.
  2. In Tower, mantieni un int privato level che parte da 1, leggibile come public int Level => level;. Spara usando DamageAt(level) e mira ai bersagli entro RangeAt(level). Aggiungi public void Upgrade(), che incrementa il livello di 1.
  3. In BuildManager, un clic su una torre la seleziona, mentre un clic su qualsiasi altra cosa non seleziona nulla (un clic su una piattaforma libera continua a costruirci sopra). Il towerPanel serializzato viene mostrato solo quando è selezionata una torre, con Arrow level 1 in towerNameText, Damage 2 > 3 e Range 4.5 > 5 su due righe in towerStatsText, e Upgrade 40 in upgradeLabel. A maxLevel, le statistiche mostrano solo i valori correnti, l’etichetta dice Max level e upgradeButton non è interattivo.
  4. Scrivi public void UpgradeSelected(), che viene chiamato dal pulsante Upgrade: sotto il livello massimo, se il GameManager può pagare il potenziamento, potenzia la torre e aggiorna il pannello. In Update, ignora i clic sull’interfaccia utente.

Premi Play, costruisci una torre, cliccaci sopra e potenziala, quindi premi Check.

Provalo tu

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);

    private Tower chosen;

    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]);
    }

    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) && 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);
    }
}
quiz iconMettiti alla prova

Questa lezione include un breve quiz. Inizia la lezione per rispondere e tenere traccia dei tuoi progressi.

Tutte le lezioni di Gioco Unity: difesa della torre