Menu
CoddyTech

自分好みにカスタマイズ

Coddyの「Unityゲーム:タワーディフェンス」コースのレッスン 18/18。

ゲームにはエンディングが必要です。ライフが0になると負け、すべてのウェーブが送り出され、ボード上に敵が残っていなければ勝ちです。Spawnerは最後のウェーブが送り出されたことを把握しており、Enemy.Allは残っている敵の数を把握しているため、Spawnerはボードが空になるまで待ち、その後、GameManagerが監視するイベントを発生させます。コルーチンはWaitUntilを使って条件を待ちます。これはラムダ式をフレームごとに1回チェックします。すべてのスイッチがオンになると出口が開くパズルルームの例です:

yield return new WaitUntil(() => switchesOn == switches.Length);
exit.SetActive(true);

どちらのエンディングでも、メッセージを表示したEndPanelが現れ、Time.timeScale = 0でゲームが停止します。ライフが0を下回ることはありません。残り1ライフのときにTankが2ダメージを受けると、ちょうど0かどうかのチェックを通り過ぎてしまうため、Mathf.Maxでライフを0以上に保ちます。

Play Againを押すと、シーンが再読み込みされます。Time.timeScaleはシーンの一部ではなく、シーンを読み込んでも値が維持されるため、ゲームが0で停止していると、再開後も停止したままになります。読み込む前に1に戻しましょう。

次に、ゲームを自分好みに調整しましょう。ゲームバランスに関わる設定はすべてInspectorにあります:

  • GameのGameManager:startMoney(150)とstartLives(20)。
  • Spawnerのwaves:敵の種類、数、間隔を指定する8行と、timeBetweenWaves(8)。
  • EnemyDataアセット:速度、体力、報酬、および各種類の敵が減らすライフ数。Bossは体力が450で、ライフを10減らします。
  • TowerDataアセット:コスト、ダメージ、射程、連射速度、アップグレード時の数値、Cannonの範囲攻撃、Frostタワーのスロウ効果。

初期設定の数値なら、道のカーブに複数種類のタワーを配置し、お金が増えるにつれてアップグレードすればクリアできます。同じ種類のタワーを少数置くだけでは持ちこたえられません。数値を一度に1つずつ変更して、プレイしながらその影響を確かめましょう。

challenge icon

チャレンジ

難しい
  1. WaveSpawner に public event Action AllWavesCleared を追加します。最後のウェーブを送り出した後、Enemy.All が空になるまで待ち、その後イベントを発生させます。
  2. GameManager に、シリアライズされたフィールド endPanel(GameObject)と endText(TMP_Text)を追加します。ライフが 0 未満にならないようにし、0 になったら Game Over でゲームを終了します。ライフが残っている状態で全ウェーブをクリアしたら、You Win! で終了します。終了時にはメッセージとともにパネルを表示し、Time.timeScale を 0 に設定します。
  3. パネルのボタンから呼び出す public void PlayAgain() を記述します。時間を通常に戻し、アクティブなシーンを再度読み込みます。

Play を押し、8 つすべてのウェーブを通して基地を守り、その後 Check を押します。その後、Inspector でゲームを調整して、自分のやり方でプレイしましょう。

自分で試してみよう

using UnityEngine;
using TMPro;

public class GameManager : MonoBehaviour
{
    [SerializeField] private int startMoney = 100;
    [SerializeField] private int startLives = 20;
    [SerializeField] private WaveSpawner spawner;
    [SerializeField] private TMP_Text moneyText;
    [SerializeField] private TMP_Text livesText;
    [SerializeField] private TMP_Text waveText;

    private int money;
    private int lives;

    void OnEnable()
    {
        Enemy.ReachedBase += OnReachedBase;
        Enemy.Killed += OnKilled;
        spawner.WaveStarted += ShowWave;
    }

    void OnDisable()
    {
        Enemy.ReachedBase -= OnReachedBase;
        Enemy.Killed -= OnKilled;
        spawner.WaveStarted -= ShowWave;
    }

    void Start()
    {
        money = startMoney;
        lives = startLives;
        ShowMoney();
        ShowLives();
    }

    public bool TrySpend(int amount)
    {
        if (amount > money)
        {
            return false;
        }

        money -= amount;
        ShowMoney();
        return true;
    }

    public void Earn(int amount)
    {
        money += amount;
        ShowMoney();
    }

    void OnKilled(Enemy enemy)
    {
        Earn(enemy.data.reward);
    }

    void OnReachedBase(Enemy enemy)
    {
        lives -= enemy.data.damage;
        ShowLives();
    }

    void ShowMoney()
    {
        moneyText.text = "Money: " + money;
    }

    void ShowLives()
    {
        livesText.text = "Lives: " + lives;
    }

    void ShowWave(int wave, int total)
    {
        waveText.text = "Wave " + wave + "/" + total;
    }
}
quiz icon腕試し

このレッスンには短いクイズがあります。レッスンを始めて解答し、進捗を記録しましょう。

Unityゲーム:タワーディフェンスのすべてのレッスン