ふりかえり
前回は攻撃やダメージ時の効果音(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バーを実装していきます!
より直感的で迫力あるバトル画面を目指しましょう!
お楽しみに!




コメント