Menu
CoddyTech

The Shop

Lesson 15 of 25 in Coddy's Unity Game: Tower Defense course.

With two towers the player needs a shop. It builds itself from data: for each tower prefab, a button shows the name and the price, and a click chooses that tower for the next pad. The ShopPanel at the bottom holds the two buttons.

Buttons made in a loop get their listeners there, with a lambda. A lambda captures variables, not their values, and a for loop has one i for all its turns: clicked later, every lambda reads i after the loop ran past the end. A local declared inside the loop is new on every turn, so copy into it first:

for (int i = 0; i < levels.Length; i++)
{
    LevelData level = levels[i];
    levelButtons[i].onClick.AddListener(() => Load(level));
}
challenge icon

Challenge

Medium

Add a shop where a click chooses the tower to build.

  1. In BuildManager, replace towerPrefab with serialized Tower[] shop, Button[] shopButtons and Color chosenColor, and add private Tower chosen;.
  2. In Start, label each button prefab.data.towerName + "\n" + prefab.data.cost and make a click call Choose(prefab); then Choose(shop[0]).
  3. Choose keeps the tower and tints its button chosenColor, the others white. Build chosen for chosen.data.cost.

Press Play and build both kinds. Then Check.

Try it yourself

using UnityEngine;
using UnityEngine.InputSystem;

public class BuildManager : MonoBehaviour
{
    [SerializeField] private GameManager game;
    [SerializeField] private Tower towerPrefab;

    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(towerPrefab.data.cost))
        {
            Debug.Log("Not enough money");
            return;
        }

        pad.tower = Instantiate(towerPrefab, pad.transform.position, Quaternion.identity);
    }
}

All lessons in Unity Game: Tower Defense

Practice on your own: Unity playground