Menu
CoddyTech

업그레이드

Coddy의 Unity 게임: 타워 디펜스 코스 레슨. 25개 중 18번째.

패널의 업그레이드 버튼은 UpgradeSelected를 호출합니다. GameManager의 TrySpend를 통해 비용을 지불하므로, 가진 돈이 부족하면 아무것도 바뀌지 않습니다. 최고 레벨에서는 더 이상 구매할 것이 없습니다. 능력치에는 현재 값만 표시되고 버튼은 상호작용할 수 없습니다.

패널은 3D 뷰 위에 있는 UI이며, 패널의 버튼을 클릭하는 것은 BuildManager가 감지하는 마우스 누르기이기도 합니다. 레이저는 버튼을 통과해 뒤쪽의 지면까지 닿으며, 버튼에서 손을 떼기 전에 BuildManager가 패널을 닫게 됩니다. 포인터가 UI 위에 있는 동안에는 EventSystem.current.IsPointerOverGameObject()가 true이므로, BuildManager는 일찍 반환하고 버튼이 클릭을 처리하도록 둡니다.

challenge icon

챌린지

중급

패널에서 선택한 포탑을 업그레이드하세요.

  1. public void UpgradeSelected()를 작성하세요. maxLevel보다 낮을 때 game.TrySpend(data.UpgradeCost(level))로 비용을 지불하면 포탑을 업그레이드하고 패널을 새로 고치세요.
  2. maxLevel에서는 패널에 두 줄로 Damage 4와 Range 5.5, 그리고 Max level이 표시되고, 직렬화된 upgradeButton은 상호작용할 수 없게 됩니다.
  3. Update에서 EventSystem.current.IsPointerOverGameObject()일 때 반환하세요.

‘플레이’를 눌러 포탑을 건설하고, 포탑을 클릭한 다음 두 번 업그레이드하세요. 패널에 Max level이 표시됩니다. 그런 다음 ‘확인’을 누르세요.

직접 해보기

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);
    }
}

Unity 게임: 타워 디펜스의 모든 레슨

직접 연습해 보세요: Unity 플레이그라운드