この講座はハクスラローグライク×デッキ構築型カードバトルRPG「呪術迷宮」の作り方講座の第14回です。
前回の記事ではボス戦、画像のローカライズ、ステージクリア・ゲームオーバーを実装し、カードバトルの基幹部分がほぼ仕上がったところでした。
前回の記事:
が、まだステージクリア・ゲームオーバーになった後に戻る画面がありません。
そこで今回は戦闘画面の開発から少し離れてタイトル画面の作成を行います。
Unityではゲーム内のそれぞれの画面(場面)をシーン(Scene)と呼称し、独立したファイルで開発を行う事ができます。ファイル拡張子は.unityになります(シーンを分けずに1シーン内に全ての画面を用意することも可能です)。
ここまでUIオブジェクト等を使って画面構成を作ってきたのはAssets/Scenesフォルダ内のSampleScene.sceneファイルです。
ここからはアプリを起動した時に最初に開かれるシーンとしてタイトルシーンを作成していきましょう。
タイトルシーンの作成
既存のシーンは複製することも可能ですが今回はシーンの新規作成によってタイトルシーンを用意します。
エディター画面左上の[File]タブからNew Sceneを選択するとシーンの初期設定を選ぶウィンドウが表示されます。
左側のテンプレート欄では2Dゲーム画面用である[Basic 2D (Built-in)]を選択し、右下のCreateボタンを押下します。するとシーンが作成され、編集中のシーンも作成されたものに切り替わります。
(注:もし上記画面のように2DのSceneテンプレートが表示されない場合、Project > Scenesフォルダに移動し、既に作成してあるシーンを選んでctrl+Dキーで複製。その後Main CameraとEventSystemだけ残せばOKです。)
シーンの保存・名前付け
作成したばかりのシーンはファイル化していないため保存されていません。最初に名前を付けて保存([File]タブ→[Save as…])する事で.sceneファイルに保存され、以降上書き保存も可能になります。
Ctrl+S入力または[Save as…]から保存ダイアログを開き、Assets/Scenesフォルダ内にTitleというファイル名(シーン名)で保存しましょう。
既存のシーンは名前を変える事も可能です。これまで制作していた戦闘画面のシーンは現在SampleSceneという名前ですが、これをBattleという名前に変更します。(ファイルを右クリック→[Rename])
注意点として、シーン名に限らずUnityプロジェクト内のファイル名を変更する時は必ずUnityエディター上にて名前変更の操作を行ってください。エディター外で名前変更を行うと参照の設定などが解除される場合があります。
ビルド対象シーン設定
作成したシーンはUnityエディター上では問題なく編集・テストプレイが可能ですが、現在の設定ではビルド(ゲームをアプリとして出力する操作)を行った時にこのシーンを実機でプレイすることが出来ません。
よってビルド対象シーン設定というものにこのTitleシーンを追加する必要があります。[File]タブから[Build Settings…]を選択してビルド設定ウィンドウを開きます。
右上の[Add Open Scenes]とクリックすると現在編集中のシーンがビルド対象として組み込まれます。Scenes In Build欄にTitleシーンが追加される事が確認できます。
アプリを起動した時に最初に立ち上がるシーンの設定もここで行えます。
Scenes In Build欄の右端に上から0、1と書かれていますがこれはゲーム内におけるシーンの順番です。0番目に設定されたシーンが最初のシーンとして扱われます。
Scenes/Titleの行を上方向にドラッグ&ドロップする事で並び替えを行い、Titleシーンを一番上にする事で0番目(=最初のシーン)に設定できます。
シーンの切り替え・DataManagerプレハブ化
sceneファイルをProjectビュー内でダブルクリックすると編集中のシーンが対象のものに切り替わります。一旦Battleシーンに切り替えましょう。
Battleシーン内には7章で作成したシングルトンオブジェクトであるDataManagerが存在しています。これをプレハブ化してTitleシーンにも配置する事で、Titleシーンからゲームを開始した時にも問題なくセーブデータ等のやりとりを行えるようにします。
SceneビューからProjectビューにドラッグ&ドロップしてプレハブ化し、Titleシーン内にプレハブのインスタンスを配置しましょう。
DataManagerはシングルトンオブジェクトですので、プレイ中にTitleシーンとBattleシーンを何度切り替えても最初に出てきたDataManagerオブジェクト1つだけが残り続けるという事になります。
通常はシーンを切り替えるとそれまでゲーム内に存在したオブジェクトは全削除されますが、このオブジェクトだけは残り続けるのでシーンの間をまたいでのデータの受け渡しが可能になるという事です。
タイトル画面の構成
それではTitleシーンの編集を開始しましょう。この章ではステージを選択してBattleシーンに移動できるようにしましょう。
Canvasの作成
全てのUIオブジェクトの親であるCanvasオブジェクトから作成します。
設定はBattleシーン内のものと同一ですのでここからコピー&ペーストを行っても構いません。その場合はEventSystemオブジェクトが自動作成されないので忘れずに追加を行ってください。
CanvasコンポーネントのRender CameraパラメータにはこのシーンのMain Cameraを指定します。
GameWindowオブジェクト
こちらもBattleシーンと同様にゲーム画面のサイズを制限するためのGameWindowオブジェクトを用意します。その他のUIオブジェクトは全てこのオブジェクトの子になるように配置していきます。UI > Imageオブジェクトを作成します。
- オブジェクト名:GameWindow
- 親:Canvas
- PosX:0 PosY:0
- Width:1080 Height:540
- Imageコンポーネント・Maskコンポーネントを付与
背景画像
タイトル画面の背景画像です。Battleシーンと違い背景画像を2オブジェクトに分割する必要はありません。
- オブジェクト名:BackGround
- 親:GameWindow
- PosX:0 PosY:0
- Width:1080 Height:540
- (Image)Source Image:Textures/BackGrounds/Title.png
タイトルロゴ画像を日英両対応で作成する
続いて、タイトルロゴの画像を作成します。
日本語用の画像と英語用の画像を言語設定により分けて表示したいので、13章にて用意したSimpleTranslationImageコンポーネントを使用して各言語の画像を指定します。
- オブジェクト名:TitleLogo
- 親:GameWindow
- PosX:0 PosY:156
- Width:800 Height:200
- 日本語用画像:Textures/Logos/TitleLogo_JP.png
- 英語用画像:Textures/Logos/TitleLogo_EN.png
ステージ選択ボタン
ステージ選択ウィンドウを開くボタンを作成します。ボタンクリック時に呼び出す処理は後で作成します。
ボタン上に表示するTextについてはSimpleTranslationTextコンポーネントを使い言語設定に対応させます。UI > Legacy > Buttonで作成。
- オブジェクト名:Button_StageSelect
- 親:GameWindow
- PosX:0 PosY:20
- Width:250 Height:70
- (Image)Source Image:Textures/GUIs/Title/button_0.png(buttonsを開いて選択)
- 子のTextオブジェクトにSimpleTranslationTextをアタッチ:(日本語)ステージ選択 (英語)Stage select
- (任意)文字色の設定やOutlineなど
デッキ編集ボタン
デッキ編集ウィンドウを開くボタンです。
Button_StageSelectオブジェクトをコピー&ペーストして作成します。以下はコピー元から変更する箇所のみ記載しています。
- オブジェクト名:Button_DeckEdit
- PosX:0 PosY:-70
- Width:220 Height:55
- 子のTextオブジェクトのSimpleTranslationText:(日本語)デッキ編集 (英語)Deck edit
- (任意)文字サイズの調整
訓練場ボタン
訓練場ウィンドウを開くボタンです。Button_DeckEditオブジェクトのコピー&ペーストで作成します。
今後ステージ攻略時に経験値とお金を入手できるシステムを実装します。その経験値を消費してプレイヤーを強化できる施設として訓練場を用意していきます。
- オブジェクト名:Button_OpenTraining
- PosX:0 PosY:-140
- 子のTextオブジェクトのSimpleTranslationText:(日本語)訓練場 (英語)Training
術札屋ボタン
術札屋ウィンドウを開くボタンです。Button_DeckEditオブジェクトのコピー&ペーストで作成します。
こちらはお金を消費してプレイヤーのカードを購入できるシステムとして作成予定です。
- オブジェクト名:Button_OpenShopping
- PosX:0 PosY:-210
- 子のTextオブジェクトのSimpleTranslationText:(日本語)術札屋 (英語)Card shop
サブウィンドウ表示時の背景画像
ステージ選択ウィンドウや訓練場ウィンドウ等を開いている時、別のボタンをタップできないようにするためのウィンドウ背景画像を作成します。
全画面に表示させるため、PanelUIオブジェクトとして作成しましょう。
- オブジェクト名:WindowBackPanel
- 親:GameWindow
- (Image)Color:黒の半透明
ステージ選択ウィンドウの作成
ステージを複数の中から選択し、そのステージデータ(StageSO)をBattleシーンに渡しつつシーン切り替えを行う機能を実装します。
まずはステージ選択の操作を行えるウィンドウオブジェクトを用意し、それをボタンで開閉できる所まで作ってみましょう。
ステージ選択ウィンドウ画像
ステージ選択ボタンを押した時に開かれるウィンドウです。UI > Imageで作成。
後ほど職業選択欄を上側に配置するのでウィンドウは下側に移動させます。
- オブジェクト名:StageSelectWindow
- 親:GameWindow
- PosX:0 PosY:-70
- Width:788 Height:450
- (Image)Source Image:Textures/GUIs/Title/window_C.png
ステージ選択ウィンドウを閉じるボタン
ウィンドウ右上に配置する閉じるボタンです。UI > Legacy > Buttonで作成。
- オブジェクト名:CloseButton
- 親:StageSelectWindow
- PosX:328 PosY:162
- Width:60 Height:62
- (Image)Source Image:Textures/GUIs/Title/batu.png
- 子のTextオブジェクトを削除
タイトルシーン管理スクリプト
一旦スクリプトの作成に移り、先ほど用意したウィンドウの開閉を行える所まで実装しましょう。
タイトルシーン全体を管理するTitleManagerクラス、ステージ選択ウィンドウを担当するStageSelectWindowクラスを順番に作っていきます。タイトルシーン用のスクリプトは全てAssets/Scripts/Titleフォルダにまとめていくと良いでしょう。
TitleManager.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 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 |
using System.Collections; using System.Collections.Generic; using UnityEngine; using UnityEngine.UI; using DG.Tweening; /// <summary> /// タイトルシーン管理クラス /// </summary> public class TitleManager : MonoBehaviour { // ステージセレクトウィンドウクラス [SerializeField] private StageSelectWindow stageSelectWindow = null; // アニメーション用UIオブジェクト [SerializeField] private RectTransform titleLogoRectTransform = null; // タイトルロゴRectTransform [SerializeField] private List<RectTransform> titleButtonUIs = null; // 各種ボタン・ボタン背景RectTransformリスト // ウィンドウ背景パネルオブジェクト [SerializeField] private GameObject windowBackObject = null; // Start void Start () { // 管理下コンポーネント初期化 stageSelectWindow.Init (this); // ゲーム起動時のアニメーションを再生 InitAnimation (); // ウィンドウ背景オブジェクトを無効化 SetWindowBackPanelActive (false); } /// <summary> /// ゲーム起動時アニメーション /// </summary> private void InitAnimation () { // タイトルロゴImage Image titleLogoImage = titleLogoRectTransform.GetComponent<Image> (); // 起動アニメーションSequence Sequence initSequence = DOTween.Sequence (); // アニメーション再生前の初期準備 // タイトルロゴを大きく・透明に titleLogoRectTransform.transform.localScale = new Vector2 (1.8f, 1.8f); titleLogoImage.color = new Color (1.0f, 1.0f, 1.0f, 0.0f); // 各種ボタン関連UIを画面下側に退避 int buttonUIsLength = titleButtonUIs.Count; const float ButtonsUIMoveLength_Y = 400.0f; // 各種ボタン関連UIのX方向移動量 for (int i = 0; i < buttonUIsLength; i++) { titleButtonUIs[i].anchoredPosition += new Vector2 (0.0f, -ButtonsUIMoveLength_Y); } // アニメーション設定 const float TitleLogoTweenTime = 3.0f; // タイトルロゴ演出時間 // タイトルロゴの大きさ変更 initSequence.Append ( titleLogoRectTransform.DOScale (1.0f, TitleLogoTweenTime)); // タイトルロゴの非透明化 initSequence.Join ( titleLogoImage.DOFade (1.0f, TitleLogoTweenTime)); // 各種ボタン関連UIを画面下側から移動 const float ButtonsUITweenTime = 1.0f; // 各種ボタン関連UI演出時間 const float ButtonsUITweenDistance = 0.15f; // 各種ボタン関連UIに演出を実行する時間間隔 for (int i = 0; i < buttonUIsLength; i++) { initSequence.Join ( titleButtonUIs[i].DOAnchorPosY (ButtonsUIMoveLength_Y, ButtonsUITweenTime) .SetRelative () // 相対座標指定にする .SetDelay (ButtonsUITweenDistance * i)); // 少しずつ遅延していく } } /// <summary> /// ウィンドウ背景パネルオブジェクトを有効化・無効化する /// </summary> public void SetWindowBackPanelActive (bool mode) { windowBackObject.SetActive (mode); } } |
- タイトルシーンを起動した時に「ロゴ画像の大きさ変更」と「各ボタンの移動」の演出を行うアニメーションをSequenceで再生します。
StageSelectWindow.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 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 |
using System.Collections; using System.Collections.Generic; using UnityEngine; using UnityEngine.UI; using DG.Tweening; /// <summary> /// タイトルシーン・ステージセレクトウィンドウクラス /// </summary> public class StageSelectWindow : MonoBehaviour { // タイトル管理クラス private TitleManager titleManager; // ウィンドウのRectTransform private RectTransform windowRectTransform = null; // ウィンドウ表示・非表示Tween; private Tween windowTween; // ウィンドウ表示アニメーション時間 private const float WindowAnimTime = 0.3f; // 初期化関数(TitleManager.csから呼出) public void Init (TitleManager _titleManager) { // 参照取得 titleManager = _titleManager; windowRectTransform = GetComponent<RectTransform> (); // ウィンドウ非表示 windowRectTransform.transform.localScale = Vector2.zero; windowRectTransform.gameObject.SetActive (true); } /// <summary> /// ウィンドウを表示する /// </summary> public void OpenWindow () { if (windowTween != null) windowTween.Kill (); // ウィンドウ表示Tween windowTween = windowRectTransform.DOScale (1.0f, WindowAnimTime) .SetEase (Ease.OutBack); // ウィンドウ背景パネルを有効化 titleManager.SetWindowBackPanelActive (true); } /// <summary> /// ウィンドウを非表示にする /// </summary> public void CloseWindow () { if (windowTween != null) windowTween.Kill (); // ウィンドウ非表示Tween windowTween = windowRectTransform.DOScale (0.0f, WindowAnimTime) .SetEase (Ease.InBack); // ウィンドウ背景パネルを無効化 titleManager.SetWindowBackPanelActive (false); } } |
スクリプトを組めたらエディターに戻り、StageSelectWindowオブジェクトにStageSelectWindowクラスをアタッチします。
また、ウィンドウ内の閉じるボタン(CloseButton)のButtonコンポーネントのタップ時呼び出し処理設定を追加し、StageSelectWindowのCloseWindowメソッドを呼び出すようにします。
同様にステージ選択ウィンドウを開くボタン(Button_StageSelect)にも同様にタップ時設定を追加します。こちらはStageSelectWindowのOpenWindowメソッドを呼び出すようにします。
そしてTitleManagerクラスもシーン内に配置します。空オブジェクトとしてManagersを新規作成し、そこにTitleManagerをアタッチします。
パラメータの設定としてStageSelectWindow、タイトルロゴ画像、4種類のタイトル画面上のボタン、ウィンドウ背景パネルそれぞれの参照をセットしていきます。
(ウィンドウ背景パネルとステージ選択ウィンドウのアクティブ状態はスクリプトで制御するのでシーン内においてはどちらで設定しても問題ありません。)
この状態ではシーン開始演出とウィンドウの開閉操作ができる所までが確認できます。
ステージ選択システムの実装
ここからはステージ選択操作を行い、Battleシーンへ移動して戦闘を開始するまでの流れを実装していきます。
ステージデータの用意
現状では動作確認用のステージデータ(StageSO)が1つ存在するのみですので、ステージの切り替えを確認するために4つまでステージデータを用意してみましょう。ステージ名や敵出現テーブルは暫定的に入力しておけばOKです。
ステージ選択ウィンドウ上に選択中ステージの難易度について大まかに表示させたいので、難易度を示すstringデータをStageSOに設定できるようにしましょう。
これで選択したステージがBattleシーンにも反映されるようになりました。
BattleシーンからTitleシーンまで戻るスクリプト
最後にステージクリア時およびゲームオーバー時の「タイトルへ戻る」ボタンをタップした時の処理も実装しておきます。
既にStageClear.csとGameOver.csのGoTitleSceneメソッドが呼び出される設定になっているはずですのでここを変更します。
StageClear.csとGameOver.cs内 各GoTitleSceneメソッド
1 2 3 4 5 6 7 8 |
/// <summary> /// タイトル画面へ移動する /// </summary> public void GoTitleScene () { // タイトルシーンに切り替える SceneManager.LoadScene ("Title"); } |
- スクリプトの先頭に以下のusing文も追加してください。
1 |
using UnityEngine.SceneManagement; |
これでTitleシーンとBattleシーン双方の行き来が可能になりました。
まとめ
Unityのシーンの機能を用いて戦闘画面とは独立してタイトル画面の開発を行いました。
また、ステージ選択システムを実装し、複数ダンジョンの中から好きなステージを選んで遊べるようになりました。
SceneManagerを使用すればスクリプトによってゲーム中のシーン切り替えが可能です。その際元々あったシーン内のオブジェクトは全て破壊されてしまいますが、DataManagerオブジェクトにはシングルトンによる非破壊設定が付与されているのでシーン間でのデータのやりとりも実現できています。
次回からはより発展的な内容として、プレイヤーが何度も遊びたくなるようにデッキ編集が行える機能を実装してみましょう。
次の記事:
コメント