ゲーム的にはだいたい出来てきましたが、現在は無限にディフェンダーを配置出来てしまうので、コストによる制限を設けたいと思います。
目次
時間によってコインを獲得する処理
コインは時間経過によって一定時間ごとに獲得するようにします。
プログラム修正
時間経過でコインを獲得する処理を実装するにあたり、次のような機能も合わせて実装します
- 初期コインをインスペクターでセットできる
- 1コイン増えるのに必要な時間をインスペクターでセットできる
- インターバルで増えるコインの数も変更出来ますが、今回は1ずつ増やします
- インターバルの時間はRangeを使い制限を設ける
- コインの枚数に変化があった場合、通知を行う
- コインを使う処理
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
using UnityEngine.SceneManagement;
using UnityEngine.Events;
public class GameManager : MonoBehaviour
{
[SerializeField] private GameObject panelGameOver;
[SerializeField] private GameObject panelGameClear;
[SerializeField] private WaveData waveData;
private int totalEnemyCount = 0;
private int currentEnemyCount = 0;
[SerializeField] private int initialCoin = 5;
[Range(0.1f, 10.0f)]
[SerializeField] private float incrementIntervalSec = 1.0f;
private int coin = 0;
public int Coin { get { return coin; } }
public static UnityEvent<int> OnCoinChanged = new UnityEvent<int>();
private void Start()
{
coin = initialCoin;
OnCoinChanged.Invoke(coin);
StartCoroutine(AddCoin());
panelGameOver.SetActive(false);
panelGameClear.SetActive(false);
Castle.OnAnyDestroyed.AddListener((castle) =>
{
panelGameOver.SetActive(true);
});
panelGameOver.GetComponentInChildren<Button>().onClick.AddListener(() =>
{
SceneManager.LoadScene(SceneManager.GetActiveScene().name);
});
// waveデータに含まれる敵の数を調べる
foreach (var enemyData in waveData.enemyDataList)
{
if (enemyData != null)
{
totalEnemyCount += 1;
}
}
// 敵がいなくなったら
EnemyController.OnAnyDestroyed.AddListener((enemy) =>
{
// カウントアップして
currentEnemyCount += 1;
// すべての敵を倒しつつ、ゲームオーバーになってなければ
if (totalEnemyCount <= currentEnemyCount && panelGameOver.activeSelf == false)
{
// クリア
panelGameClear.SetActive(true);
}
});
}
private IEnumerator AddCoin()
{
while (true)
{
yield return new WaitForSeconds(incrementIntervalSec);
coin += 1;
OnCoinChanged.Invoke(coin);
Debug.Log("coin: " + coin);
}
}
public bool UseCoin(int cost)
{
if (coin < cost)
{
return false;
}
coin -= cost;
OnCoinChanged.Invoke(coin);
return true;
}
}
ログで処理がちゃんと動いているか確認
ここではログを見ながらコインが増えているか確認します。5から始まって1秒毎に1コインずつ増えています。
コインの枚数を表示するUIを作成
ここでは、コイン情報のみを持ったヘッダーを作成します。ゲームではいろんな情報を扱うことになりますが、必要に応じて拡張してみてください。
ヘッダーのビューを作成
上部に白いイメージを配置、その中にテキストを表示する。
- Imageを追加
- Canvas右クリック>UI>Imageを選択
- 名前をHeaderに変更
- Anchor PresetをAlt+Shiftを押しながら右上のStrechを選択する下図参考
- Height;100
中にテキストを追加する
- TextMeshProを追加
- Headerを右クリック>UI>Text – TextMeshProを選択
- 名前を変更:CoinText
- AnchoPresetを変更
- 選択内容はHorizontal:Strech Vertical:Strech(一番右下のやつ)
- 選択時はAlt+Shiftを押した状態で選択してください
- Textのコンポーネント変更
- 太字
- 色を黒
- FontSize:50
- Alignment:中央・中央
- 折返しなし:Wrapping=Disabled
プログラム作成
HeaderではGameManagerのコイン変化のイベントを察知し、UIに変更を加えます。インスペクターでセットを行いますが、これは1フレーム目にコインの枚数を強制的に更新するために利用します。
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using TMPro;
public class Header : MonoBehaviour
{
[SerializeField] private GameManager gameManager;
[SerializeField] private TextMeshProUGUI coinText;
private void Start()
{
GameManager.OnCoinChanged.AddListener(ShowCoin);
ShowCoin(gameManager.Coin);
}
private void ShowCoin(int coin)
{
coinText.text = "Coin:" + coin.ToString();
}
}
コンポーネントのセット
作成したスクリプトをセットして、テキストを更新してやりましょう。
- Headerコンポーネントをセット
- Headerゲームオブジェクトを選択し、Headerスクリプトをアタッチします
- インスペクターのセット
- GameManager
- 右の丸ポチから1つだけ絞り込めるはずなのでそれをセット
- CoinText
- ヘッダーの下のCoinTextゲームオブジェクトをセット
- GameManager
動かして確かめる
各種設定が出来たら、動作させてみて確認してみましょう。
ここまでうまくできたなら、あとはコストを利用してのディフェンダー設置処理を実装して完成です!
コメント