【Unity】RPGを作るチュートリアルその15 戦闘画面の構成を考える回
- 2025.01.23
- RPGチュートリアル
- RPG, Unity, ゲーム開発, チュートリアル

シンプルなRPGをUnityで作るチュートリアルシリーズの15回目です。
第14回では敵キャラクターの定義データに、行動パターンを設定できる項目を追加しました。行動パターンについては条件に応じて選択されるように実装しました。
定義データに関しては一旦作業が完了したので、今回からはひとつ目の大きな山である戦闘関連の機能の実装に入っていきます。まずは戦闘画面でどのようにゲームオブジェクトを用意していくか、構成を考えていきましょう。
制作環境
MacBook Pro 2023 Apple M2 Max
Unity6 (6000.0.30f1) Silicon
作業内容と順序
シンプルなRPGを作る上でどんな作業が必要か、どんな順番で作っていくと良さそうか、別ページで検討しました。基本的にこの流れに沿って進めていきます。
チュートリアルの一覧
このシリーズ全体の一覧は以下のページにまとめています。
前回の内容
前回は敵キャラクターの行動パターンの機能を実装しました。
戦闘画面をどう実装するか
戦闘画面をどのように実装するのか考えておきましょう。戦闘用のシーンを作成するのか、移動用のシーン内で戦闘用のゲームオブジェクトを用意するのか、といった部分を決めておきたいと思います。
戦闘用のシーンを作成する場合、背景用のゲームオブジェクトやUIなど、ひとつのシーン内で扱うことができるので調整がしやすくなります。例えば炎の洞窟、雪山など、シチュエーションに合わせた背景オブジェクトを用意して、エンカウントした場所によって切り替えることができます。シーン自体は1つで、背景オブジェクトはPrefabで切り替えるのも良いかと思います。
戦闘が始まった時にシーン自体を切り替えると、切り替え時のロード時間が長くなるため、シーンの追加ロードが良いかもしれません。特にフィールドが広大だと再ロードに時間がとてもかかるので、なるべくロードし直すことは避けたいところ。
移動用のシーン内で戦闘用のゲームオブジェクトを用意するケースでは、シーン内で戦闘用ゲームオブジェクトの親オブジェクトを作っておいて、戦闘が始まる時に有効にする形です。同じシーン内にあるので追加ロードが必要なく、待ち時間という意味では減らせるのではと思います。同じシーン内にあるので、キー操作の制御はしっかりとしておきましょう。また、同じシーン内にある場合、戦闘で使うゲームオブジェクト数が多かったりメモリをたくさん使う場合には負荷が大きくなります。近年だと移動して敵に近づくとシームレスに戦闘が始まるケースもよく見られます。
今回のチュートリアルでは、後者の移動用のシーン内で戦闘用のゲームオブジェクトを用意する方式で進めたいと思います。2Dの戦闘で背景オブジェクトも負荷が少ないことが予想されるので、ゲーム起動時に読み込んでしまいます。2Dか、3Dかによってメモリにロードするデータ量も変わってくるため、作りたいゲームに合わせて選択すると良いでしょう。戦闘機能を詳細に作り込んでいく前に、モック版の段階で両方試してみるのも良いかと思います。
親オブジェクトの作成
戦闘に関する機能をまとめた親オブジェクトを作成していきます。シーン内で編集すると複数人でいじるのが大変になるので、戦闘関連の機能についてはPrefab化してPrefabの編集画面でいじっていくとやりやすくなるかと思います。
まずはHierarchyウィンドウから空のゲームオブジェクトを作成しましょう。名前は [BattleParent] にしました。

作成したゲームオブジェクトを選択した状態で、InspectorウィンドウからTransformの値をリセットします。親オブジェクトとして使うため、位置が子オブジェクトに影響しないようにしておきます。

このゲームオブジェクトに関しては忘れないうちにPrefabにしておきます。Prefabの保存先フォルダをまだ作っていなかったので、Projectウィンドウから「Assets」に移動して、新規フォルダを作成します。名前は [Prefabs] にしました。

作成した「Prefabs」のフォルダに移動して、Hierarchyウィンドウの「BattleParent」のゲームオブジェクトをProjectウィンドウにドラッグ&ドロップしてPrefabファイルを作成します。名前は変更せずそのまま使います。

作成したPrefabをダブルクリックしてPrefabの編集画面を開いておきます。UIなどはここから配置していきましょう。

戦闘画面の構成
今回のチュートリアルで作りたい戦闘画面のイメージとしては、ファミコン時代のドラクエ1やスーパーファミコン時代のドラクエ5のように、フィールド画面は背景としてそのまま表示しつつ、その上に戦闘画面のパーツが表示される形式です。ただ戦闘の背景画像まで作ると大変なので、敵キャラクターのスプライトが表示される領域についてはドラクエ2, 3, 4のように黒塗りにします。
戦闘画面で必要なパーツ構成を考えてみると、以下のものが必要になりそうです。
- スプライトの表示領域
- 背景
- 敵キャラクター
- UIの表示エリア
- コマンド入力
- 敵キャラクターの名前
- 操作キャラクターのHP/MP
- メッセージ表示
- 管理用のゲームオブジェクト
移動用のフィールド画面より手前にスプライトを表示するため、Sorting Layerを追加します。戦闘用のスプライトの背景、戦闘用のスプライトの2つは必要そうです。敵キャラクターをスプライトで表示するか、Canvas上のImageで表示するかは更新頻度に応じて選択するとグッド。Canvas内の要素の一部が変更されるとそのCanvas全体が更新されるので、敵キャラクターのアニメーションなどがある場合はスプライトにしておいた方が良いかと思います。と言いつつ今回のチュートリアルでは敵キャラクターのアニメーションは入れませんが、拡張性を考えてスプライトとして描画したいと思います。
UIに関しては、コマンド入力用のエリア、敵キャラクターの名前を表示するエリア、操作キャラクターのHP/MPを表示するエリア、メッセージを表示するエリアなど、ドラクエを参考にしつつちょっとアレンジして配置していきます。これらのパーツについては戦闘画面用にCanvasを作成してその中で描画していきます。UnityのCanvasの更新の仕組みを考えると、それぞれCanvasを分けた方が更新頻度を減らせるのですが、今回のチュートリアルではそこまで厳密なパフォーマンスチューニングは行わないので同じCanvasに入れます。
管理用のゲームオブジェクトに関しては、「Game」のシーンと同じように「Managers」といった形で親オブジェクトを作成して、その中に必要なゲームオブジェクトを入れていきます。基本的には戦闘画面全体を管理するクラスを用意して、処理の内容に応じて別のクラスを呼び出す形になりそうです。対応するUIのパーツごとに管理する範囲を区切ってクラス分けしていこうと思います。操作キャラクターのHP/MPの表示を管理するクラス、コマンド入力を検知するクラス、といった感じです。
これらを踏まえて、準備作業を行なっていきます。
スプライト関係の準備
スプライトに関する親オブジェクトの作成と、Sorting Layerの追加を行います。
親オブジェクトの作成
Hierarchyウィンドウにて、Prefabの編集を行なっている状態で「BattleParent」の下に空のゲームオブジェクトを作成します。名前は [Sprites] にしました。

背景の親オブジェクト、敵キャラクターのスプライトの親オブジェクトについても作っておきましょう。作成した「Sprites」のゲームオブジェクトの下に、空のゲームオブジェクトを2つ作成し、それぞれ [Background] と [Enemies] と命名しました。

「Background」の下には背景画像1つを配置する予定です。「Enemies」の下には戦う相手の敵キャラクターのゲームオブジェクトを配置していきます。
Sorting Layerの追加
続いてSorting Layerを追加していきましょう。画面上部のメニューバーから [Edit] -> [Project Settings …] を選択し、「Project Settings」のウィンドウを表示します。左側のタブ領域から [Tags and Layers] を選択して「Tags and Layers」の画面を表示します。表示した画面で、「Sorting Layers」のリストにて [+] ボタンから2つ項目を追加し、それぞれ [BattleBackground] と [BattleCharacter] にリネームします。

フィールド画面における一番手前のレイヤーの「TilemapOverlay」よりも後ろの要素にすることで、戦闘関連のスプライトが画面手前に表示されるようになります。
手前に表示されるかどうかの確認
念の為設定がうまくいっているか確認してみましょう。
「Background」のゲームオブジェクトの下に、背景用のスプライトを作成します。Hierarchyウィンドウでコンテキストメニューを開き、[2D Object] -> [Sprites] -> [Square] から四角のスプライトを作成します。

作成したスプライトでは、Transformの値を以下のように変更しました。今は確認の段階なので直接位置を変えています。スプライトなので、戦闘が始まるタイミングでカメラの位置を読み取って、親オブジェクトである「Sprites」の位置を変更するように後程処理を入れたいと思います。Prefabの編集画面を表示している場合、Prefabでの編集を保存することでシーン内に変更が反映されます。
「Color」の項目は [#161616] にして完全な黒ではなく灰色に、「Sorting Layer」の項目は先ほど作成した [BattleBackground] にしています。

Prefabの設定を保存して、「Game」ウィンドウで以下のように表示されていればOKです。フィールド用の画像で一番手前にあるのは屋根のタイルですが、それよりも手前に戦闘用背景が表示されます。

敵キャラクターの画像についても配置してみましょう。先ほど編集していた「Square」のゲームオブジェクトを複製して、「Enemies」の下に移動させます。複製したゲームオブジェクトの名前は [Slime] に変更しました。

Inspectorウィンドウから設定を変更しましょう。Transformの「Scale」はそれぞれ [1] に変更しました。「SpriteRenderer」のコンポーネントでは「Color」の項目を [#FFFFFF] の白に、「Sorting Layer」の項目は [BattleCharacter] にしています。

設定を変更したらPrefabの編集内容を保存して、以下のように、戦闘用背景の手前に敵キャラクターが表示されればOKです。

これでスプライト部分の表示はいけそうですね。上でも少し触れましたが、スプライトなのでカメラの位置が動くと表示もずれてしまいます。そのため、戦闘突入時のスプライトの位置移動は課題として残しておきます。
今回のブランチ
まとめ
今回は戦闘関連の機能について、その実装方針を決めていきました。シーンは分けず、同じシーン内で戦闘用のパーツを実装していくことにして、その中のスプライトに関する表示機能を実装しました。
次回は戦闘画面のUI部分についてモック版として組んでいきましょう。
ゲーム開発の攻略チャートを作りました!
-
前の記事
【Unity】RPGを作るチュートリアルその14 敵の行動パターン定義の作成 2025.01.22
-
次の記事
【Unity】RPGを作るチュートリアルその16 戦闘画面のUIの仮組み〜HPとMP表示編〜 2025.01.27
コメントを書く