23歩目 バトルログを実装! Unityで1日1ステップ!ノンフィールドRPG開発日記

1日1歩開発日記

ふりかえり

前回はボスを実装しました!強力な敵が出現することでバトルに緊張感が生まれました!

バトルログの実装!

これまで、攻撃やダメージ、レベルアップ、敵の出現といったバトルログはUnityのコンソールにしか表示されず、プレイヤーには見えない状態でした。

今回は、ゲーム画面内にバトルログを表示することで、戦闘の流れが分かりやすくなるようにします!

スクリプトの変更

バトルログを管理する新しいBattleLogManagerスクリプトを作成し、ゲーム画面にログを表示する機能を実装します。

  • ログ表示機能: ScrollRectとTextMeshProUGUIを使用したログ表示
  • 自動スクロール: 新しいログが追加されると自動的に一番下にスクロール
  • 色分け機能: 攻撃、ダメージ、回復、レベルアップなど、イベント別に色分け
  • タイムスタンプ: 各ログに時刻を表示
  • 最大行数制限: 古いログを自動削除してメモリを節約
using UnityEngine;
using UnityEngine.UI;
using TMPro;
using System.Collections.Generic;
using DG.Tweening;

public class BattleLogManager : MonoBehaviour
{
    [Header("UI References")]
    public ScrollRect logScrollRect;
    public TextMeshProUGUI logText;
    public GameObject logPanel;
    
    [Header("Log Settings")]
    public int maxLogLines = 20; // 表示する最大行数
    public float logFadeInDuration = 0.3f; // ログのフェードイン時間
    public float autoScrollDuration = 0.5f; // 自動スクロール時間
    
    [Header("Log Colors")]
    public Color playerAttackColor = Color.cyan;
    public Color enemyAttackColor = Color.red;
    public Color damageColor = Color.yellow;
    public Color healColor = Color.green;
    public Color levelUpColor = Color.magenta;
    public Color rewardColor = new Color(1f, 0.5f, 0f); // オレンジ色
    public Color stageClearColor = Color.cyan;
    public Color normalColor = Color.white;
    
    private List<string> logHistory = new List<string>();
    private Tween scrollTween;
    
    void Start()
    {
        InitializeLog();
    }
    
    void InitializeLog()
    {
        if (logText != null)
        {
            logText.text = "";
        }
        
        if (logPanel != null)
        {
            logPanel.SetActive(true);
        }
        
        // 初期ログを追加
        AddLog("バトル開始!", normalColor);
    }
    
    // ログを追加する
    public void AddLog(string message, Color color = default)
    {
        if (color == default)
        {
            color = normalColor;
        }
        
        string timestamp = System.DateTime.Now.ToString("HH:mm:ss");
        string coloredMessage = $"<color=#{ColorUtility.ToHtmlStringRGB(color)}>[{timestamp}] {message}</color>";
        
        logHistory.Add(coloredMessage);
        
        // 最大行数を超えた場合は古いログを削除
        while (logHistory.Count > maxLogLines)
        {
            logHistory.RemoveAt(0);
        }
        
        UpdateLogDisplay();
        ScrollToBottom();
    }
    
    // ログ表示を更新
    private void UpdateLogDisplay()
    {
        if (logText != null)
        {
            logText.text = string.Join("\n", logHistory);
        }
    }
    
    // ログを一番下にスクロール
    private void ScrollToBottom()
    {
        if (logScrollRect != null)
        {
            // 既存のTweenを停止
            if (scrollTween != null && scrollTween.IsActive())
            {
                scrollTween.Kill();
            }
            
            // 自動スクロール
            scrollTween = DOTween.To(() => logScrollRect.verticalNormalizedPosition, 
                                    x => logScrollRect.verticalNormalizedPosition = x, 
                                    0f, autoScrollDuration)
                                .SetEase(Ease.OutQuad);
        }
    }
    
    // プレイヤー攻撃ログ
    public void AddPlayerAttackLog(string playerName, string enemyName, int damage)
    {
        string message = $"{playerName}が{enemyName}に{damage}ダメージを与えた!";
        AddLog(message, playerAttackColor);
    }
    
    // 敵攻撃ログ
    public void AddEnemyAttackLog(string enemyName, string playerName, int damage)
    {
        string message = $"{enemyName}が{playerName}に{damage}ダメージを与えた!";
        AddLog(message, enemyAttackColor);
    }
    
    // ダメージログ
    public void AddDamageLog(string targetName, int damage)
    {
        string message = $"{targetName}は{damage}ダメージを受けた!";
        AddLog(message, damageColor);
    }
    
    // 回復ログ
    public void AddHealLog(string targetName, int healAmount)
    {
        string message = $"{targetName}は{healAmount}回復した!";
        AddLog(message, healColor);
    }
    
    // レベルアップログ
    public void AddLevelUpLog(string characterName, int newLevel)
    {
        string message = $"{characterName}がレベル{newLevel}になった!";
        AddLog(message, levelUpColor);
    }
    
    // 報酬ログ
    public void AddRewardLog(int exp, int gold)
    {
        string message = $"経験値{exp}、お金{gold}を獲得した!";
        AddLog(message, rewardColor);
    }
    
    // ステージクリアログ
    public void AddStageClearLog(int stageNumber)
    {
        string message = $"ステージ{stageNumber}クリア!";
        AddLog(message, stageClearColor);
    }
    
    // 敵出現ログ
    public void AddEnemySpawnLog(string enemyName, int level)
    {
        string message = $"{enemyName}(Lv.{level})が出現した!";
        AddLog(message, normalColor);
    }
    
    // 敵撃破ログ
    public void AddEnemyDefeatLog(string enemyName)
    {
        string message = $"{enemyName}を倒した!";
        AddLog(message, normalColor);
    }
    
    // ログをクリア
    public void ClearLog()
    {
        logHistory.Clear();
        UpdateLogDisplay();
    }
    
    // ログパネルの表示/非表示を切り替え
    public void ToggleLogPanel()
    {
        if (logPanel != null)
        {
            logPanel.SetActive(!logPanel.activeSelf);
        }
    }
    
    // ログパネルを表示
    public void ShowLogPanel()
    {
        if (logPanel != null)
        {
            logPanel.SetActive(true);
        }
    }
    
    // ログパネルを非表示
    public void HideLogPanel()
    {
        if (logPanel != null)
        {
            logPanel.SetActive(false);
        }
    }
    
    void OnDestroy()
    {
        // Tweenをクリーンアップ
        if (scrollTween != null && scrollTween.IsActive())
        {
            scrollTween.Kill();
        }
    }
} 

ログを出したい行動を実装している関数にBattleLogManagerのそれぞれ対応した関数を追加します。

public void Attack(EnemyManager enemyManager)
    {
        // 攻撃アニメーションを再生
        if (animationManager != null)
        {
            animationManager.PlayerAttackAnimation();
        }

        int damage = Mathf.Max(0, player.attack - enemyManager.enemy.defense);
        enemyManager.TakeDamage(damage);

        // バトルログに追加
        if (battleLogManager != null)
        {
            battleLogManager.AddPlayerAttackLog(player.name, enemyManager.enemy.name, damage);
        }

        Debug.Log($"{player.name}が{enemyManager.enemy.name}に{damage}ダメージ!");
    }

Unityでの設定

1. 必要なUIオブジェクトの作成

1-1. Canvasの中に「バトルログ用のScroll View」を作成

HierarchyでCanvasを右クリック →UI > Scroll Viewを選択→ 名前を「BattleLogScroll View」に変更

1-2. Scroll Viewの中身を整理
  • BattleLogScroll Viewの子にViewportがあり、その中にContentがあります。
  • Contentの名前を「BattleLogText」に変更し、TextMeshPro – Textコンポーネントをアタッチします。
  • もしTextMeshProが使えない場合は「Window > TextMeshPro > Import TMP Essential Resources」で導入してください。
  • Content Size Fitterコンポーネントをアタッチ
  • Vertical FitをPreferred Sizeにします。
1-3. サイズ・見た目を調整
  • BattleLogScroll ViewのRectTransformでサイズ・位置を調整(例:画面下部に横長で配置)
  • BattleLogTextのTextMeshProUGUIで
  • Alignmentを「左上」
  • Overflowを「Overflow」
  • Font Sizeや色も好みに調整

2. BattleLogManagerの設置

2-1. 空のGameObjectを作成
  • Hierarchyで右クリック → Create Empty → 名前を「BattleLogManager」に
2-2. スクリプトをアタッチ
  • BattleLogManagerオブジェクトを選択し、Inspectorで「Add Component」→ BattleLogManagerスクリプトを追加

3. BattleLogManagerのInspector設定

3-1. 必要な参照をセット
  • logScrollRect:BattleLogScroll Viewをドラッグ&ドロップ
  • logText:BattleLogText(TextMeshProUGUI)をドラッグ&ドロップ
  • logPanel:BattleLogScroll Viewをドラッグ&ドロップ

4. 各ManagerにBattleLogManagerの参照をセット

4-1. 参照が必要なManager(例:BattleManager, PlayerManager, EnemyManager, StageManager)を選択
  • InspectorでBattleLogManagerフィールドに、HierarchyのBattleLogManagerオブジェクトをドラッグ&ドロップ

動作確認

Unityでゲームを開始し、バトルをすると、バトルの進行状況がリアルタイムでログに表示され、プレイヤーが戦闘の流れを把握しやすくなります!

まとめ

今回はバトルログを実装しました!これによってバトルで何が起こっているか確認でき、戦況を把握することができます!

次回予告

次回は、バトル画面のUIを調整していきます!

見やすく、美しくすることでプレイ体験がグッと良くなります!

お楽しみに!

タイトルとURLをコピーしました