ふりかえり
前回は攻撃やダメージ時の効果音(SE)を実装し、バトルに臨場感が生まれました!
ステージ制を実装
これまでのバトルは、ひたすらスライムを倒し続ける単調なものでした。
今回は「10体倒すと次のステージに進む」というステージ制を導入し、プレイヤーに明確な目標を持たせていきます!
- 各ステージは10体のモンスターで構成
- ステージが進むとモンスターのレベルが上がっていく
BattleManagerの変更
ステージの進行はすべてBattleManagerで管理します。
新たに追加された主な要素:
- currentStage:現在のステージ番号
- monstersDefeatedInStage:そのステージで倒した敵の数
- StageClear():ステージクリア時の処理
- NextStage():次のステージに進む処理
敵を倒すたびにOnMonsterDefeated()が呼ばれ、10体倒すとStageClear()が発動し、クリアUI・SEが再生されます。
using UnityEngine; public class BattleManager : MonoBehaviour { public PlayerManager playerManager; public EnemyManager enemyManager; public AudioManager audioManager; // AudioManagerの参照を追加 public BattleUIManager battleUIManager; // BattleUIManagerの参照を追加 public AnimationManager animationManager; // AnimationManagerの参照を追加 private bool isPlayerTurn = true; // プレイヤーのターンかどうかを管理 private int currentStage = 1; // 現在のステージ private int monstersDefeatedInStage = 0; // 現在のステージで倒したモンスター数 private int monstersPerStage = 10; // 1ステージあたりのモンスター数 void Start() { // 初期化処理 StartPlayerTurn(); // プレイヤーのターン開始時にログを出力 Debug.Log($"ステージ{currentStage}開始!{monstersPerStage}匹のモンスターを倒してください!"); } public void PlayerAttack() { // アニメーション中は攻撃できない if (animationManager != null && animationManager.IsAnyAnimationPlaying()) { Debug.Log("アニメーション中です。しばらくお待ちください。"); return; } if (isPlayerTurn) { // 敵が倒されている場合は攻撃しない if (enemyManager != null && enemyManager.IsEnemyDead()) { Debug.Log("敵は既に倒されています。新しい敵が出現するまで待ってください。"); return; } playerManager.Attack(enemyManager); isPlayerTurn = false; // プレイヤーのターン終了 Invoke("EnemyAttack", 1.0f); // 1秒後に敵の攻撃を呼び出す } } public void EnemyAttack() { if (!isPlayerTurn) { // アニメーション中は攻撃を遅延させる if (animationManager != null && animationManager.IsAnyAnimationPlaying()) { Invoke("EnemyAttack", 0.1f); // 0.1秒後に再試行 return; } // 敵が倒されている場合は攻撃しない if (enemyManager != null && enemyManager.IsEnemyDead()) { Debug.Log("敵は倒されているため、攻撃をスキップします。"); isPlayerTurn = true; // プレイヤーのターンに戻る StartPlayerTurn(); return; } enemyManager.Attack(playerManager); isPlayerTurn = true; // 敵のターン終了、プレイヤーのターンに戻る StartPlayerTurn(); // プレイヤーのターン開始時にログを出力 } } private void StartPlayerTurn() { Debug.Log(playerManager.player.name + "のターン:攻撃ボタンをタップして下さい"); } // モンスターが倒された時の処理 public void OnMonsterDefeated() { monstersDefeatedInStage++; Debug.Log($"モンスターを倒しました!({monstersDefeatedInStage}/{monstersPerStage})"); // ステージクリアのチェック if (monstersDefeatedInStage >= monstersPerStage) { StageClear(); } } // ステージクリア時の処理 private void StageClear() { Debug.Log($"ステージ{currentStage}クリア!お疲れさまでした!"); // ステージクリアUIを表示 if (battleUIManager != null) { battleUIManager.ShowStageClearUI(); } // ステージクリアSEを再生 if (audioManager != null) { audioManager.PlayStageClearSE(); } } // 次のステージに進む(UIから呼び出される) public void NextStage() { currentStage++; monstersDefeatedInStage = 0; Debug.Log($"ステージ{currentStage}開始!{monstersPerStage}匹のモンスターを倒してください!"); // 敵のレベルアップ if (enemyManager != null) { enemyManager.LevelUpEnemy(); } } // 現在のステージ情報を取得 public int GetCurrentStage() { return currentStage; } // 現在のステージで倒したモンスター数を取得 public int GetMonstersDefeatedInStage() { return monstersDefeatedInStage; } // 1ステージあたりのモンスター数を取得 public int GetMonstersPerStage() { return monstersPerStage; } // ステージ進行度を取得(0.0f~1.0f) public float GetStageProgress() { return (float)monstersDefeatedInStage / monstersPerStage; } }
BattleUIManagerの作成
ゲーム画面にステージ情報や進行度バーを表示するために、BattleUIManager.csを新規作成します。
表示内容:
- 現在のステージ番号
- 倒したモンスター数(例:3/10)
- 進行度バー(Slider+Gradient)
- ステージクリアパネル+「次のステージへ」ボタン
進行度はDOTweenでアニメーションし、徐々にバーが伸びていく演出が加わります。
ボタンを押すとBattleManager.NextStage()が呼び出され、ステージが進行します。
using UnityEngine; using UnityEngine.UI; using TMPro; using DG.Tweening; public class BattleUIManager : MonoBehaviour { [Header("Battle Manager Reference")] public BattleManager battleManager; [Header("Stage Information UI")] public TextMeshProUGUI stageText; // ステージ番号を表示 public TextMeshProUGUI monsterCountText; // 倒したモンスター数を表示 [Header("Progress Bar UI")] public Slider progressBar; // 進行度バー public Image progressBarFill; // 進行度バーのフィル部分 public Gradient progressBarGradient; // 進行度バーのグラデーション [Header("Stage Clear UI")] public GameObject stageClearPanel; // ステージクリアパネル public TextMeshProUGUI stageClearText; // ステージクリアテキスト public Button nextStageButton; // 次のステージボタン [Header("Animation Settings")] public float progressBarAnimationDuration = 0.5f; // 進行度バーのアニメーション時間 private int lastMonstersDefeated = 0; // 前回の倒したモンスター数 private int lastStage = 1; // 前回のステージ void Start() { InitializeUI(); SetupEventListeners(); } void Update() { UpdateUI(); } // UIの初期化 private void InitializeUI() { if (battleManager == null) { Debug.LogError("BattleManager is not assigned to BattleUIManager!"); return; } // 進行度バーの初期化 if (progressBar != null) { progressBar.minValue = 0f; progressBar.maxValue = 1f; progressBar.value = 0f; } // ステージクリアパネルを非表示 if (stageClearPanel != null) { stageClearPanel.SetActive(false); } // 初期UIを更新 UpdateStageInfo(); UpdateProgressBar(); } // イベントリスナーの設定 private void SetupEventListeners() { if (nextStageButton != null) { nextStageButton.onClick.AddListener(OnNextStageButtonClicked); } } // UIの更新 private void UpdateUI() { if (battleManager == null) return; int currentMonstersDefeated = battleManager.GetMonstersDefeatedInStage(); int currentStage = battleManager.GetCurrentStage(); // モンスター数が変わった場合 if (currentMonstersDefeated != lastMonstersDefeated) { UpdateMonsterCount(); UpdateProgressBar(); lastMonstersDefeated = currentMonstersDefeated; } // ステージが変わった場合 if (currentStage != lastStage) { UpdateStageInfo(); lastStage = currentStage; } } // ステージ情報の更新 private void UpdateStageInfo() { if (battleManager == null) return; int currentStage = battleManager.GetCurrentStage(); int monstersPerStage = battleManager.GetMonstersPerStage(); // ステージテキストの更新 if (stageText != null) { stageText.text = $"ステージ {currentStage}"; } // モンスター数テキストの更新 if (monsterCountText != null) { monsterCountText.text = $"{battleManager.GetMonstersDefeatedInStage()}/{monstersPerStage}"; } } // モンスター数の更新 private void UpdateMonsterCount() { if (battleManager == null) return; int currentMonstersDefeated = battleManager.GetMonstersDefeatedInStage(); int monstersPerStage = battleManager.GetMonstersPerStage(); if (monsterCountText != null) { monsterCountText.text = $"{currentMonstersDefeated}/{monstersPerStage}"; } } // 進行度バーの更新 private void UpdateProgressBar() { if (battleManager == null || progressBar == null) return; float targetProgress = battleManager.GetStageProgress(); // 進行度バーをアニメーション付きで更新 DOTween.To(() => progressBar.value, x => progressBar.value = x, targetProgress, progressBarAnimationDuration) .SetEase(Ease.OutQuad); // グラデーションの適用 if (progressBarFill != null && progressBarGradient != null) { progressBarFill.color = progressBarGradient.Evaluate(targetProgress); } } // ステージクリアUIの表示 public void ShowStageClearUI() { if (stageClearPanel != null) { stageClearPanel.SetActive(true); } if (stageClearText != null) { stageClearText.text = $"ステージ{battleManager.GetCurrentStage()}クリア!"; } } // ステージクリアUIの非表示 public void HideStageClearUI() { if (stageClearPanel != null) { stageClearPanel.SetActive(false); } } // 次のステージボタンがクリックされた時の処理 private void OnNextStageButtonClicked() { HideStageClearUI(); // BattleManagerで次のステージに進む if (battleManager != null) { battleManager.NextStage(); } } // 進行度バーの色を設定 public void SetProgressBarColor(Color color) { if (progressBarFill != null) { progressBarFill.color = color; } } // 進行度バーのグラデーションを設定 public void SetProgressBarGradient(Gradient gradient) { progressBarGradient = gradient; UpdateProgressBar(); } }
EnemyManagerの対応
BattleManager.NextStage()から呼び出される形で、EnemyManager.LevelUpEnemy()を実装し、
敵のレベルやステータスがステージごとに強化される仕組みも整えます。
Unityでの設定
- 新しい空のオブジェクトを作成し、BattleUIManager.csをアタッチ
- 必要なUI(Text、Slider、Panel、Buttonなど)を用意
- Inspectorで各UIコンポーネントを正しくアサイン
- BattleManagerにもBattleUIManagerを接続

動作確認
ゲームを開始して敵を倒すと:
- ステージ番号が「ステージ1」
- モンスター討伐数が「1/10」
- プログレスバーが10%ほど進行

という風に、視覚的に進行状況がわかるようになりました!
まとめ
今回は、ステージ制の導入とUIによる進行表示を実装しました!
バトルに「目標」ができたことで、ゲームのモチベーションもグッと高まりますね!
次回予告
次回は、キャラクターのHPバーを実装していきます!
より直感的で迫力あるバトル画面を目指しましょう!
お楽しみに!
コメント