Tingkatkan
Pelajaran 12 dari 18 dalam kursus Game Unity: Tower Defense di Coddy.
Menekan sebuah tower akan membuka panel yang menampilkan levelnya dan tombol Upgrade. Setiap level menambah damage dan jangkauan tower, dan biaya setiap upgrade lebih besar daripada sebelumnya. Level-levelnya mengikuti suatu aturan, jadi asset menyimpan aturan tersebut, bukan daftar angka: statistik pada level 1, jumlah yang ditambahkan setiap level, dan harga upgrade. Method pada ScriptableObject menghitung sisanya, sehingga setiap script yang meminta akan mendapat jawaban yang sama. Hasil panen tanaman dalam game pertanian:
public int YieldAt(int level)
{
return baseYield + yieldPerLevel * (level - 1);
}Tower hanya menyimpan level-nya sendiri, dan panel menampilkan angka level berikutnya di samping angka saat ini, sehingga pemain melihat apa yang didapat dari uangnya. Klik pada tower mengenai salah satu bagiannya, yaitu alas atau kepala, yang merupakan child dari tower. Jadi, hit.collider.GetComponentInParent<Tower>() menemukan tower tempat bagian tersebut berada: method ini mencari pada object yang terkena, lalu ke parent-nya.
Panel adalah UI di atas tampilan 3D, dan klik pada tombol Upgrade juga merupakan tekanan mouse yang dilihat BuildManager. Ray-nya menembus tombol hingga ke tanah di belakangnya, dan BuildManager menutup panel sebelum tombol dilepas. EventSystem.current.IsPointerOverGameObject() bernilai true saat pointer berada di atas UI, sehingga BuildManager langsung keluar dan membiarkan tombol menangani klik tersebut.
Tantangan
Sedang- Di
TowerData, tambahkan int publikmaxLevel,upgradeCost, dandamagePerLevel, serta float publikrangePerLevel. Tambahkanint DamageAt(int level)danfloat RangeAt(int level): level 1 menggunakan damage dan range bawaan asset, lalu setiap level di atasnya menambahkan jumlah per level. Tambahkanint UpgradeCost(int level), harga untuk naik dari level tersebut:upgradeCostdikalikan dengan levelnya. - Di
Tower, gunakan int privatlevelyang dimulai dari 1 dan dapat dibaca sebagaipublic int Level => level;. Tembakkan proyektil denganDamageAt(level)dan bidik target dalam jarakRangeAt(level). Tambahkanpublic void Upgrade(), yang menambahkan 1 ke level. - Di
BuildManager, klik tower untuk memilihnya, dan klik apa pun yang lain untuk tidak memilih apa pun. Klik pada pad kosong tetap membangun tower di sana.towerPanelyang diserialisasi hanya ditampilkan saat tower dipilih, denganArrow level 1ditowerNameText,Damage 2 > 3danRange 4.5 > 5dalam dua baris ditowerStatsText, sertaUpgrade 40diupgradeLabel. PadamaxLevel, statistik hanya menampilkan nilai saat ini, label bertuliskanMax level, danupgradeButtontidak dapat digunakan. - Tulis
public void UpgradeSelected(), yang dipanggil oleh tombol Upgrade: sebelum mencapai level tertinggi, jika GameManager dapat membayar peningkatan, tingkatkan tower dan perbarui panel. Abaikan klik pada UI diUpdate.
Tekan Play, bangun tower, klik tower tersebut dan tingkatkan levelnya, lalu tekan Check.
Coba sendiri
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);
}
}
Pelajaran ini berisi kuis singkat. Mulai pelajarannya untuk menjawab kuis dan melacak progresmu.