Menu
CoddyTech

Nâng cấp

Bài học 18 trên 25 trong khóa học Game Unity: thủ thành của Coddy.

Nút Upgrade của bảng gọi UpgradeSelected. Nút này thanh toán thông qua TrySpend của GameManager, vì vậy nếu không đủ tiền thì sẽ không có gì thay đổi. Ở cấp độ cao nhất, không còn gì để mua: các chỉ số chỉ hiển thị giá trị hiện tại và bạn không thể tương tác với nút.

Bảng này là giao diện người dùng nằm trên khung nhìn 3D, nên khi nhấp vào nút, thao tác đó cũng được BuildManager nhận diện là nhấn chuột. Tia của nó đi xuyên qua nút đến mặt đất phía sau, và BuildManager sẽ đóng bảng trước khi bạn nhả nút chuột. EventSystem.current.IsPointerOverGameObject() trả về true khi con trỏ nằm trên giao diện người dùng, vì vậy BuildManager thoát sớm và để các nút xử lý những lần nhấp đó.

challenge icon

Thử thách

Trung bình

Nâng cấp tháp đã chọn từ bảng điều khiển của tháp.

  1. Viết public void UpgradeSelected(): khi cấp thấp hơn maxLevel, nếu game.TrySpend(data.UpgradeCost(level)) thanh toán thành công, hãy nâng cấp tháp và làm mới bảng điều khiển.
  2. Ở maxLevel, bảng điều khiển hiển thị Damage 4 và Range 5.5 trên hai dòng, cùng với Max level; nút upgradeButton đã tuần tự hóa không thể tương tác.
  3. Trong Update, trả về khi EventSystem.current.IsPointerOverGameObject().

Nhấn Chơi, xây một tháp, nhấp vào tháp đó rồi nâng cấp hai lần: bảng điều khiển hiển thị Đạt cấp tối đa. Sau đó nhấn Kiểm tra.

Tự làm thử

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);
    [SerializeField] private GameObject towerPanel;
    [SerializeField] private TMP_Text towerNameText;
    [SerializeField] private TMP_Text towerStatsText;
    [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)
        {
            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;
        towerStatsText.text = "Damage " + data.DamageAt(level) + " > " + data.DamageAt(level + 1)
            + "\nRange " + data.RangeAt(level) + " > " + data.RangeAt(level + 1);
        upgradeLabel.text = "Upgrade " + data.UpgradeCost(level);
    }
}

Tất cả bài học trong Game Unity: thủ thành

Tự luyện tập: Playground Unity