kuront’s blog

主にUnityでのゲーム制作やってます。

【Unity】RPG制作 その13-戦闘時の行動タイプの保持、実行

 前回は戦闘中に回復アイテムを使用する処理を実装しようとして、アイテムを使っている途中で動かなくなったところで終わりました。
バグの原因が不明なので、アイテムの使用処理の実装を置いておいて先に戦闘時の行動タイプによる処理分けを実装していきたいと思います。
 実際の戦闘中の処理はBattleManagerが行っているのでBattleManagerに処理を追加していきます。

はじめに、戦闘中の行動の処理分けをするための列挙定数を宣言します。

public enum BATTLEACTIONTYPE
    {
        NORMALATTACK,
        GUARD,
        ITEM,
        MAGIC,
        MOVE,
    };

それから、プレイヤーと敵のBATTLEACTIONTYPEを保持するためのDictionrayも宣言します。

private Dictionary<int, BATTLEACTIONTYPE> battleActionDic = new Dictionary<int, BATTLEACTIONTYPE>();

battleActionDicを初期化する関数を定義します。

//プレイヤー、敵の行動を初期化する関数
    public void InitBattleActionDic()
    {
        //初期値はNORMALATTACKにしておく
        battleActionDic[0] = BATTLEACTIONTYPE.NORMALATTACK;
        battleActionDic[1] = BATTLEACTIONTYPE.NORMALATTACK;
        battleActionDic[2] = BATTLEACTIONTYPE.NORMALATTACK;
        battleActionDic[3] = BATTLEACTIONTYPE.NORMALATTACK;
    }

InitBattleActionDic関数をバトルのはじめに呼び出されるSetUpBattle関数で呼び出します。

public void SetUpBattle()
    {
        SoundManager.instance.PlayBGM("Battle");
        player = PlayerManager.instance; 
        playerUI.SetupUI(player);
        commandUI.gameObject.SetActive(true);
        commandUI.SetBattleCommand();
        battleResult = new BattleResult(); // クラスから実体生成
        isBattleEnd = false;
        InitBattleActionDic(); //行動タイプDictionray初期化 New
    }

 準最初の備ができたので、まずはプレイヤーの行動を処理分けできるようにしていきます。
BattleManager.csのTurnProcessの中で、行動順がプレイヤーの場合、StartPlayerTurnコルーチンを実行しているので、こちらに処理を追加していきます。
 現状StartPlayerTurn関数の中身は以下のようになっています。

 


クリックで展開

 上記のコメントで書いてある、"敵を倒した時の処理"より上は、通常攻撃を行った時の処理になるので、この処理を関数にしておきます。



クリックで展開

この関数で処理を置き換え、BATTLEACTIONTYPEで処理を分けるとこんな感じになります。


クリックで展開

 これで行動タイプによって処理の分岐をするようになりました。
 

行動タイプITEMの場合の処理の実装

 行動タイプがITEMの場合に実行される処理を実装していきます。
実際に実行させたい処理をItemEventから指定したいので、ここでは関数登録を使います。ItemEvent.csに関数登録用の変数とプレイヤーがアイテムを使うと決めた時に実行する関数を作成します。


クリックで展開

 DecideUseItem、IEUseItemRegisterへの関数の登録はItemUsePanelで行います。


クリックで展開

 Buttonを押した時の処理にDecidePlayerUseItemOnBattleを追加し、DecideUseItemにbattleManagerのStartBattleTurn関数、IEUseItemRegisterにIEUseHealItemOnBattleコルーチンを登録しました。
 あとはアイテムを使った時にこれらの処理を実行されるようにBattleManagerに処理を書いていきます。
 battleManagerでitemEventクラスのデータを保持できるように、itemEvent型の変数を作ります。

public itemEvent playerItemEvent;

PlayerのBATTLEACTIONTYPEがITEMの時に実行されるコルーチンを作成します。



クリックで展開

 このコルーチンをStartPlayerTurnの中で呼び出します。

クリックで展開

あと1点バグ修正で、CommandUIManagerのスクリプトのHideCancelButton関数を以下のように記述し直します。


クリックで展開

 これを書いておかないと、PushItemButton関数のTranslateでY座標-150したキャンセルボタンがそのままになってしまいます。

 この状態で実行すると以下の状況で問題が発生します。

f:id:kuront:20211001091553p:plain

f:id:kuront:20211001091601p:plain

BattleManagerのエラー発生箇所を確認するとif (enemysList[targetIndex].hp <= 0)となっています。
これは、攻撃した後に、攻撃対象のHPが0以下であれば敵をDestroyするという処理の判定箇所なのですが、このtargetIndexの値が、アイテムを使った場合元々の数値が入ったままで、前のターンのtargetindexが入っている状態です。敵を倒した場合、enemyListのint型の要素が削除されるようになっているのでエラーが出るのです。なので、敵を倒した時にtargetIndexの値をenemyListの存在するint型のKeyの値に変更します。


クリックで展開

 enemysList.First().KeyでenemysListのDictionaryに存在する一番最初に見つけた要素のint型のKeyを取得できます。これでもう1回実行してみます。

youtu.be