この記事はUnityとC#で作るターン制のタクティクス戦略シミュレーションRPGプログラミング開発講座の第16回です。今回が講座内容としては最終回になります。
前回の記事でキャラクターの特技スキルを実装し、バフやデバフ・回復や強力な攻撃スキルの実装を行いました。
前回の記事:
今回の記事では、最終回としてゲームクリアまたはゲームオーバー後にキャラクターを強化する機能を追加して繰り返し楽しめるようにしてみましょう。
スマホゲームなどでよくある周回コンティニュー機能を実装する方法をマスターできます。また、シーン間でのデータ引継ぎなども会得していきましょう!
シングルトンなどの使い方もここで解説していきます。
そして強化回数をPlayerPrefsにて保存し、ゲームを終了しても保持されるようにします。ステージを増やしていけばより本格的なシミュレーションRPGを作ることも可能になります。
新しいシーン(レベルアップ強化システム画面)を作成する
ゲーム終了後に遷移する強化画面では、全味方キャラクターの「最大HP」「攻撃力」「防御力」から1種類を選んで強化(数値の上昇)を行えるようにします。
まずは強化画面のシーンを新規作成します。エディター左上のメニューから[File]→[New Scene]とクリックしましょう。開かれる画面にて使用するテンプレートが聞かれますが、Basicを選択したままCreateを押せばOKです。
これで新規シーンが作成されて編集状態に入りました。画面の作成を行う前に、まずはこのシーンに名前を付けて保存しておきます。
[File]→[Save]をクリック(またはショートカットキーのCtrl+Sキー)でSceneフォルダ内にこのシーンを保存します。シーン名は「Enhance」としました。UIを配置する
最低限必要なものは以下のUIオブジェクトとなります。
UI | オブジェクト名 | 種類 | 概要 |
背景UI | BackGround | Image |
背景画像を表示するUIです。 Hierarchy内では他のUIオブジェクトより一番上に配置します。 |
最大HP強化ボタン | AddHPButton | Button+Text+Image |
押下する事でそれぞれのパラメータの強化を適用するボタンです。 ボタンの右側にはTextやImageUIで何が強化されるのか分かりやすく表示しておくと良いです。 |
攻撃力強化ボタン | AddAtkButton | ||
防御力強化ボタン | AddDefButton | ||
リトライボタン | GoGameButton | Button+Text | 押下する事でGameシーンに戻り、強化が適用された状態で再び遊べるようになるボタンです。 |
まずはCanvasから作成します。Canvasの設定はGameシーンで用意したものと全く同一になります。
- オブジェクトはシーンをまたいでもコピー&ペースト可能です。
背景画像UIの表示
一番後ろに全画面に表示する背景画像のUIオブジェクト(BackGround)を作成します。
Anchor設定にて縦横ともにstretch指定を行い、[Left・Top・Right・Bottom]のパラメータにそれぞれ0を入力すれば全画面表示にする事が可能です。
今回は1枚の小さな画像をタイル状に並べて表示する方法を行ってみます。
[Source Image]には素材BackGroundを指定し、[Image Type]をTiledに指定しましょう。すると画像本来の大きさで領域を埋めるように表示してくれます。
Tiledに変更すると[Pixels Per Unit Multiplier]というパラメータが出現しますが、これは画像1枚あたりの大きさを変更しより多く/少なくタイルを表示できる設定です。(1以上の数値を指定すると多くなります。)使用する素材にあわせて変更すると良いでしょう。
強化画面のロゴを表示(任意)
この画面が何の画面かを分かりやすくすためにTextUIでロゴを表示しておくのがオススメです。
強化ボタン3種類を配置
味方キャラクターの「最大HP」「攻撃力」「防御力」上昇ボタンをそれぞれ作成して配置しましょう。押下時に呼び出すメソッドはのちほど設定する事になります。
何をするボタンかが分かりやすくなっていればどのように作成してもOKです。まずは最大HP上昇ボタン(AddHPButton)を作成し、説明のアイコンや文章はボタンの子オブジェクト内に作成すると配置しやすくなります。
ボタンの画像素材は「EnchanceButton」を使用しますが、コマンドボタンの画像素材と同様に9スライスの設定をおくと良いです。
あわせて説明用のアイコン(ImageUI)と文章(TextUI)を位置調整しながら作成していきます。
アイコン画像についてはHPIconを使用します。また上昇量については任意ですが、サンプルでは2上昇としています。
前述の通り、これらの説明用UIはボタンオブジェクトの子に作成するとボタンをコピー&ペーストした時に配置しやすくなりますが、初期設定だと説明用UIもボタンを構成する一部として扱われてしまうため[Raycast Target]はオフにしておくと良いでしょう。
最大HP強化ボタンが作成できたら、これをコピー&ペーストして攻撃力強化・防御力強化のボタンも作成しておきます。
アイコンで使用する画像素材はそれぞれIcon_Atk、Icon_Defです。上昇量については最大HPとは別で1としました。
リトライボタンを配置
強化を行った後もう一度プレイする(Gameシーンに移行する)ためのボタンも用意しておきましょう。
これで必要なUIは配置完了です。そろそろUIの作成にも慣れてきたころでしょうか?
その場合はぜひオリジナルデザインに挑戦してみてください!
データマネージャを作成する
キャラクターの強化を反映させる処理をこれから実装していきますが、そのためにはシーン間でデータを受け渡す手段を考えておかなければいけません。
Unityではシーン切り替えを行うとシーン内にあったオブジェクトは全て消去されてしまうため、このEnhanceシーン内でGameシーンのデータにアクセスを行う事は出来ません。
今回は情報を渡すための手段の1つとして「シーンをまたいでも消えないオブジェクト」を使用し、そこにアタッチされているスクリプト(データクラス)を介してデータを受け渡す事にしましょう。
まずは空のオブジェクト「DataManager」をGameシーン・Enhanceシーンどちらでもよいので作成します(ゲーム進行時に最初に開くシーンに置いておくと実行時のエラーが出なくなります)。
そこにデータ受け渡しクラス(Data.cs)を作成してアタッチしておきます。
シーンをまたいでもオブジェクトが消えない設定についてはスクリプト内で以下のメソッドを呼び出すだけでOKです。
1 |
DontDestroyOnLoad (gameObject); |
これだけでこのデータクラスによって情報の受け渡しが可能となりましたが、1つだけ問題が残ります。それは「同じシーンを何度も開いた時オブジェクトがたまり続ける」というものです。
データマネージャがいくつも存在してはどのデータマネージャが本当のデータを持っているのかが分からなくなってしまうため、2つ目以降に生成されるオブジェクトは全て初期化処理の時に自分を消去するようにします。このような特性をもったオブジェクト・クラスはシングルトンと呼ばれます。
非破壊設定とシングルトン処理をデータクラス内に書いていきましょう。
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 |
using System.Collections; using System.Collections.Generic; using UnityEngine; public class Data : MonoBehaviour { // シングルトン管理用変数 // (static設定によって全てのインスタンスでこの値を共有する) [HideInInspector] public static bool _instance = false; // Awake(Startより前に1度だけ実行されるメソッド) private void Awake () { // シングルトン用処理 … 既にデータマネージャがシーン内に存在している場合は自分を消去 if (_instance) { Destroy (gameObject); return; } _instance = true; // データマネージャが生成された事をstatic変数に記録する // シーンをまたいでもこのオブジェクトが消去されないように設定する DontDestroyOnLoad (gameObject); } } |
- static設定によってどのインスタンスでも共通の値をもつ変数を使用しています。staticはクラス宣言時に使う場合も含めて便利ですが、管理が難しくなるので頼りすぎないようにすると良いでしょう。
この処理によってDataManagerオブジェクトはシーン切り替えが発生しても残り続けるだけでなく、常にシーン内に1つのみが存在するようになりました。このデータクラスを介する事で情報の受け渡しが可能となります。
まずはどのシーンからゲームを開始しても必ずデータマネージャが存在するように、オブジェクトをプレハブ化して全シーンにインスタンスを配置しておきます。
そしてこのデータクラスに保持して欲しいデータとして3種のステータスの上昇量を定義しておきます。
Data.cs
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 |
using System.Collections; using System.Collections.Generic; using UnityEngine; public class Data : MonoBehaviour { // シングルトン管理用変数 // (static設定によって全てのインスタンスでこの値を共有する) [HideInInspector] public static bool _instance = false; // プレイヤー強化データ public int addHP; // 最大HP上昇量 public int addAtk; // 攻撃力上昇量 public int addDef; // 防御力上昇量 // Awake(Startより前に1度だけ実行されるメソッド) private void Awake () { // シングルトン用処理 … 既にデータマネージャがシーン内に存在している場合は自分を消去 if (_instance) { Destroy (gameObject); return; } _instance = true; // データマネージャが生成された事をstatic変数に記録する // シーンをまたいでもこのオブジェクトが消去されないように設定する DontDestroyOnLoad (gameObject); } } |
Enhanceシーンでこの上昇量データを変更し、Gameシーンでは上昇量を読み取って反映するという処理を実装していきます。
(Enhanceシーン)ステータス上昇ボタンに関する処理
それではステータス上昇ボタンと再プレイボタンを押した時の処理を実装していきます。データマネージャの参照を取得し、いま用意した上昇量の変数に変更を加える所まで行っていきましょう。
Enhanceシーンに空のオブジェクトを作成し、スクリプトを割り当てます。どちらも名前を「EnhanceManager」としました。
これで攻撃先をタップした時にはボタンによる確認が行われるようになり、「決定」を押せば攻撃開始、「やめる」を押せばキャラクターが移動前の状態にまでリセットされるようになりました。
完成!
これにて本講座『シミュレーションRPGの作り方』の全ての解説が完了しました。最後までお読みいただきありがとうございます。お疲れ様でした。
シミュレーションRPGを開発する上で必要になる知識・知っていると便利な技術などを学んでいく事ができたと思います。この経験をもとにぜひ更なる拡張をこのゲームに行うか、完全オリジナルなシミュレーションRPG開発に挑戦してみてください!
コメント
ファイアーエムブレムのようなSRPGを作りたいと思って検索していて見つけました。
色々なテクニックが組まれていて参考になりました。
ユニットの移動方法がチェスのコマのようなものだけでなく、戦士:移動力5、魔導士:移動力6とかの解説もあると嬉しかったです。
テクニックは非常に良かったです。拡張していけば面白いものが作れそうですね
今回も最後まで実践していただきありがとうございます!
SRPG制作で基本&応用が利きやすいテクニックをメインに取り込んでみました。
移動力であれば、パラメータをHPと同様の形でまず持たせ、その移動力の値に応じて移動できる場所の範囲を制限・拡張していく実装などを追加していけばよさそうですね。
オリジナルSRPG制作の役に立てたようで何よりです。