この講座はハクスラローグライク×デッキ構築型カードバトルRPG「呪術迷宮」の作り方講座の第10回です。
ここまでで戦闘システムの実装に取り掛かるために必要な準備を進めてきました。
前回は敵のUIやダメージ処理や倒したときのアニメーションなどを実装しました。
前回の記事:
この章ではいよいよカードバトル時のカード効果を発動させる処理を実現します。
呪術迷宮に特有のカードをフィールドに5枚配置し、戦闘開始すると左から順番にカード効果が発動されるシステムを実装します。
カード効果を発動させるプレイボード管理クラスの作成
フィールド上のカードがどこに配置されているかの情報はFieldManagerが保持していますが、このクラスに効果発動の処理まで追加するとスクリプトが長くなりすぎますね。
そこで、新たにPlayBoardManagerクラスを作成して処理を実装していきます。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 |
using System.Collections; using System.Collections.Generic; using UnityEngine; using UnityEngine.UI; using DG.Tweening; /// <summary> /// プレイボード上のカードの効果発動処理クラス /// </summary> public class PlayBoardManager : MonoBehaviour { // オブジェクト・コンポーネント [HideInInspector] public BattleManager battleManager; // 戦闘画面マネージャクラス private FieldManager fieldManager; private CharacterManager characterManager; // カード効果実行Sequence private Sequence playSequence; // 定数定義 public const int PlayBoardCardNum = 5; // プレイボード内のカード枠数 // 初期化関数(BattleManager.csから呼出) public void Init (BattleManager _battleManager) { // 参照取得 battleManager = _battleManager; fieldManager = battleManager.fieldManager; characterManager = battleManager.characterManager; } /// <summary> /// プレイボード上のカードを左から順番に効果発動する /// </summary> /// <param name="boardCardList">発動対象となるカード配列</param> public void BoardCardsPlay (Card[] boardCards) { // 順番にカードの効果を実行する(Sequence) const float PlayIntervalTime = 0.2f; // 各カード実行の時間間隔 playSequence = DOTween.Sequence (); for (int i = 0; i < PlayBoardCardNum; i++) { // 現在実行中の配列内番号を記憶 // (カウンタ変数iは効果処理実行時に5になってしまっている為に用意) int index = i; // 発動対象カードごとの処理(カードがないならスキップ) if (boardCards[index] != null) {// カードが存在する // このカードの使用者のキャラクターIDを取得 int useCharaID = boardCards[index].controllerCharaID; // カード効果発動 playSequence.AppendCallback (() => { // 効果発動 PlayCard (boardCards[index], useCharaID, index); }); // 戦闘終了条件を満たすか確認 playSequence.AppendCallback (() => { if (characterManager.IsPlayerDefeated () || // プレイヤー敗北 characterManager.IsEnemyDefeated ()) // 敵を撃破 { // シーケンス強制終了 playSequence.Complete (); playSequence.Kill (); return; } }); } else {// カードが存在しない } // 時間間隔を設定 playSequence.AppendInterval (PlayIntervalTime); } } /// <summary> /// カードの全ての効果を発動する /// </summary> /// <param name="targetCard">対象カード</param> /// <param name="useCharaID">このカードの使用者のキャラクターID</param> /// <param name="boardIndex">プレイボード上のこのカードの順番(0-4)</param> /// <returns>効果発動成功フラグ(true:発動成功)</returns> private bool PlayCard (Card targetCard, int useCharaID, int boardIndex) { // 相手キャラクターのID int targetCharaID = useCharaID ^ 1; // カードの各効果量 int damagePoint = 0; // 与ダメージ量 // カード内のそれぞれの効果を実行 // ①:他の効果より優先して実行される効果 foreach (var effect in targetCard.effects) { switch (effect.cardEffect) { case CardEffectDefine.CardEffect.ForceEqual: // 強度n限定 if (effect.value != targetCard.forcePoint) return false; // カード強度が指定の数値と異なるなら全ての効果を無効 break; } } // ②:通常の効果 foreach (var effect in targetCard.effects) { switch (effect.cardEffect) { case CardEffectDefine.CardEffect.Damage: // ダメージ damagePoint += effect.value; break; } } // 各種計算数値を対象ごとに適用 // ダメージ characterManager.ChangeStatus_NowHP (targetCharaID, -damagePoint); return true; } #region その他Set・Get系 /// <summary> /// カードの効果実行中ならtrueを返す /// </summary> public bool IsPlayingCards () { if (playSequence != null) return playSequence.IsPlaying (); return false; } #endregion } |
BoardCardsPlayメソッドにプレイボード上のカードデータ(最大5枚分)が渡されると順番に効果処理が開始します。
効果の発動演出を後で実装するために一連の処理はDOTweenのSequence処理で組み立てていきます。Sequence内に任意の処理を組み込めるAppendCallbackメソッドを活用しましょう。
1 2 3 4 |
(Sequence参照).AppendCallback (() => { // ここに実行したい処理 }); |
このような書式(ラムダ式と言います)でこのメソッドを呼ぶ事によって任意の処理をSequence内に追加する事が可能です。Appendによる追加なので、対象Sequenceにおいてそこまでに設定された他の処理が全て完了してから実行が始まります。
カードの個別の効果処理はPlayCardメソッド内に追加していきます。現在はDamage(相手のHPを減らす)効果とForceEqual(カードの強度が効果値と同じでないなら発動を無効)効果の2種類のみを実装しています。
まずDamage効果の実現のためメソッドの最初にdamagePoint変数を宣言しています。現在は相手のHPを減らせる効果がDamage効果しかないのでこの変数は不要ですが、今後別の効果を増やした時に全ての効果で「相手のHPを減らせる量」というのは合計する必要があるので変数を用意しています。
1枚のカードの中には複数の効果が含まれている場合があるのでforeach文で全ての効果を漏らさず適用していきます。foreach文を2つに分けているのは、「他の効果より先に発動させる必要のある効果(ForceEqualなど)」とそれ以外とに分割するためです。今後foreachの数は更に増やします。
foreach内ではswitch文を使用し、該当の効果をそのカードが持っているか確認し、持っていたらその効果を適用させます。
効果がDamageなら先ほど述べたようにdamagePoint変数に対してその効果量を加算します。
最後にCharacterManagerに用意していたHP変更処理を呼び出して、カードを使用したキャラから見て相手側のキャラのHPをダメージ数量分だけ減らすようにします。
以上の処理を呼び出すため、カード効果発動ボタンが押された時に呼び出されるFieldManager側の処理を実装していきます。
全カードの中からプレイボード上に配置されているカードを選んで配列に格納し、これをPlayBoardManagerに渡します。
FieldManager.cs (一部省略)
テストプレイすれば今回実装した効果が一通り動作することが確認できます。
現状はカードの合成機能がないので初期デッキまたはプレイヤーカードの効果を変更して試してみてください。
回復効果などを試したいときは以前作成したBattleManager.csのUpdate関数内にあるデバッグ機能でプレイヤーのHPを減らしてからカードをプレイすると確認できます。
まとめ
プレイボードに配置したカード効果を順番に発動させる処理を実装していきました。
これでカードゲームの基本であるカードをプレイすることができるようになりました。
呪術迷宮では5枚のカードをプレイする形ですが、このシステムを応用すれば様々なカードの出し方、発動のさせ方に対応したカードゲームを開発することができるはずです。
一通りのカード効果の機能を実装しましたが、まだ未実装の効果も複数あり、一度発動したらテストプレイを終えるしかない問題も残っています。
また、呪術迷宮の戦闘システムの肝となるカードの合成処理も未実装ですね。このあたりのゲームシステムをUnityで引き続き開発していきます。
次の記事:
コメント