Bán
Bài học 19 trên 25 trong khóa học Game Unity: thủ thành của Coddy.
Bán tháp sẽ hoàn lại một nửa chi phí, bao gồm cả chi phí nâng cấp, vì vậy di chuyển một tháp phòng thủ sẽ tốn tiền, nhưng không phải toàn bộ số tiền. Tháp lưu tổng số tiền đã chi cho nó: giá lúc xây dựng, cộng với giá của mỗi lần nâng cấp khi thanh toán. Tiền hoàn lại bằng một nửa tổng số đó, phép chia số nguyên sẽ làm tròn xuống. Dịch vụ cho thuê xe đạp cũng lưu tổng số tiền theo cách tương tự:
public void ExtendRide(int extraHours)
{
paid += extraHours * pricePerHour;
}
public int Deposit => paid / 4;Bán tháp sẽ phá hủy nó, nhưng trường tower của bệ vẫn trỏ đến tháp đó. Toán tử == của Unity xem một đối tượng đã bị phá hủy là null, nên từ khung hình tiếp theo, pad.tower == null là đúng và bệ lại trống mà không cần thêm code. Bảng điều khiển thì khác: nó vẫn hiển thị tháp đã bán, và khi nhấp vào Upgrade, chương trình sẽ truy cập một đối tượng đã bị phá hủy và gây ra MissingReferenceException. Bán tháp sẽ bỏ chọn mọi thứ, khiến bảng điều khiển ẩn đi.
Thử thách
Trung bìnhBán một tháp với giá bằng một nửa chi phí ban đầu.
- Trong
Tower, giữprivate int spent;:data.costtrongStart, cộng thêm giá của mỗi lần nâng cấp trongUpgrade(). Thêmpublic int SellValue => spent / 2;. - Trong
BuildManager, hiển thịSell 25(giá bán) trong TMP_Text được tuần tự hóasellLabelkhi bảng được điền thông tin. - Viết
public void SellSelected(): hoàn lại giá bán, phá hủy tháp và không chọn gì.
Nhấn Chơi, sau đó xây, nâng cấp và bán một tháp. Rồi nhấn Kiểm tra.
Tự làm thử
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();
}
}
}
Tất cả bài học trong Game Unity: thủ thành
Tự luyện tập: Playground Unity