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.
Sfida
Medio- In
TowerData, aggiungi gli interi pubblicimaxLevel,upgradeCostedamagePerLevel, e il float pubblicorangePerLevel. Aggiungiint DamageAt(int level)efloat RangeAt(int level): il livello 1 ha il danno e la portata propri dell’asset, mentre ogni livello successivo aggiunge la quantità per livello. Aggiungiint UpgradeCost(int level), il prezzo per passare da quel livello al successivo:upgradeCostmoltiplicato per il livello. - In
Tower, mantieni un int privatolevelche parte da 1, leggibile comepublic int Level => level;. Spara usandoDamageAt(level)e mira ai bersagli entroRangeAt(level). Aggiungipublic void Upgrade(), che incrementa il livello di 1. - 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). IltowerPanelserializzato viene mostrato solo quando è selezionata una torre, conArrow level 1intowerNameText,Damage 2 > 3eRange 4.5 > 5su due righe intowerStatsText, eUpgrade 40inupgradeLabel. AmaxLevel, le statistiche mostrano solo i valori correnti, l’etichetta diceMax leveleupgradeButtonnon è interattivo. - 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. InUpdate, 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);
}
}
Questa lezione include un breve quiz. Inizia la lezione per rispondere e tenere traccia dei tuoi progressi.