Jual
Pelajaran 19 dari 25 dalam kursus Game Unity: Tower Defense di Coddy.
Menjual tower mengembalikan setengah dari biayanya, termasuk biaya upgrade, jadi memindahkan pertahanan membutuhkan biaya, tetapi tidak seluruhnya. Tower menyimpan total uang yang telah dikeluarkan untuknya: harganya saat dibangun, ditambah harga setiap upgrade saat dibayar. Pengembalian dana adalah setengah dari total tersebut, dan pembagian bilangan bulat membulatkannya ke bawah. Penyewaan sepeda menyimpan total dengan cara yang sama:
public void ExtendRide(int extraHours)
{
paid += extraHours * pricePerHour;
}
public int Deposit => paid / 4;Menjual akan menghancurkan tower, dan field tower pada pad masih menunjuk ke sana. == milik Unity menganggap object yang sudah dihancurkan sebagai null, jadi mulai frame berikutnya pad.tower == null bernilai true, dan pad kembali kosong tanpa kode tambahan. Panelnya berbeda: panel masih menampilkan tower yang sudah dijual, dan klik Upgrade akan mengakses object yang sudah dihancurkan lalu memunculkan MissingReferenceException. Setelah penjualan, tidak ada yang dipilih, sehingga panel tersembunyi.
Tantangan
SedangJual menara seharga setengah dari biaya pembeliannya.
- Di
Tower, pertahankanprivate int spent;:data.costdiStart, ditambah harga setiap peningkatan diUpgrade(). Tambahkanpublic int SellValue => spent / 2;. - Di
BuildManager, tampilkanSell 25(nilai jual) dalam TMP_Text berserialisasisellLabelsaat panel diisi. - Tulis
public void SellSelected(): kembalikan uang sebesar nilai jual, hancurkan menara, lalu jangan pilih apa pun.
Tekan tombol “Main”, lalu bangun, tingkatkan, dan jual menara. Setelah itu, tekan tombol “Periksa”.
Coba sendiri
using UnityEngine;
using UnityEngine.EventSystems;
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 Button upgradeButton;
[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 || EventSystem.current.IsPointerOverGameObject())
{
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;
if (level < data.maxLevel)
{
towerStatsText.text = "Damage " + data.DamageAt(level) + " > " + data.DamageAt(level + 1)
+ "\nRange " + data.RangeAt(level) + " > " + data.RangeAt(level + 1);
upgradeLabel.text = "Upgrade " + data.UpgradeCost(level);
upgradeButton.interactable = true;
}
else
{
towerStatsText.text = "Damage " + data.DamageAt(level) + "\nRange " + data.RangeAt(level);
upgradeLabel.text = "Max level";
upgradeButton.interactable = false;
}
}
public void UpgradeSelected()
{
if (selected.Level >= selected.data.maxLevel)
{
return;
}
if (game.TrySpend(selected.data.UpgradeCost(selected.Level)))
{
selected.Upgrade();
ShowPanel();
}
}
}
Semua pelajaran di Game Unity: Tower Defense
Latihan sendiri: Playground Unity