【第7回】超入門!Unityで診断ゲームを作ろう!「診断結果の作成編」

第7回診断結果の作成編
ゆくすぃ

ごきげんよう、Budding Lab.編集部のゆくすぃです!
実は、チラズアートさんのホラー作品も大好きです。新作リリースが待ち遠しいですね!

ゲームが大好きな皆さんなら、一度は「自分でゲームを作ってみたい!」と、思ったことがあるのではないでしょうか?

本連載では、ゲーム開発初心者のゆくすぃが、基礎的なスクリプトだけを使って、超入門・診断ゲームの作り方を解説します!

本記事は、第7回「診断結果の作成編」です。

プログラミングの専門知識がなくたって、画像や音楽作成アプリが使えなくたって、案外、ゲームって作れるものです。興味が湧いたなら、ぜひ挑戦してみてください!

目次

Prefabとは

診断結果を全部で8つ作成します。ゲーム画面(設問画面)同様に、パネルで作成して並べても良いのですが、今回はPrefab(プレファブ)を使ってみようと思います。

Prefabとは、ゲームオブジェクトの設計図のようなものです。量産したいゲームオブジェクトのテンプレートを一つ作り、それをPrefab化すると、PrefabをHierarchyウインドウやエディター画面にドラッグ&ドロップしたり、スクリプトで呼び出したりしてゲームオブジェクトを量産できるようになります。

Prefabは設計図

Prefabを使うメリットは次の通りです。

  • テンプレートを複製するので、同一GameObjectを何度も作る必要がない
  • Prefabに変更をかけると、Prefabを使ったすべてのGameObjectに変更が反映される

・・・というわけで、診断結果のテンプレートをPrefab化して、8つの診断結果を複製してみましょう!

診断結果のテンプレートを作成する

早速、診断結果のテンプレートを作っていきます。
「第1回 ゲームの設計編」で、診断結果を下図のように設計していましたので、その通りに作ります。

リザルト画面の構成

UIの配置方法など、具体的な作り方については以下記事を参考にしてください。

今回、作成しているのはテンプレートなので、診断結果(テキスト)やランチ画像については、配置する場所と大きさを設計通りにしておけば、内容は何でも構いません。
但し「初めからやり直す」のボタンだけはしっかり作り込んでください。

診断結果のテンプレート「パネル:Result」

テンプレートを作る

テンプレートをPrefab化する

まずは、ProjectウィンドウにあるAssetsフォルダの中に、Prefabを保存する「Prefabフォルダ」を作成します。

次に、Hierarchyウインドウにあるテンプレート(=パネル:Result)をドラッグ&ドロップして、Prefabフォルダの中へ放り込みます。

すると「パネル:Result」は下図のような青い立方体のアイコンに変化します。これだけで、テンプレートがPrefab化します。

テンプレートを作る

Prefab化ができたら、Hierarchyウインドウの「パネル:Result」は必要ないので、削除しておきます。

ゆくすぃ

以上で、診断結果を量産するための設計図が完成しました。
次から、Prefabを活用するためのスクリプトを作成していきます!

Prefabを活用するための準備

ここからは、Microsoft Visual Studioを使って、Prefabを活用するためのスクリプトを準備していきます。

Prefabを活用するための準備
  1. 診断結果のデータ構造を定義する。
  2. 診断結果をデータベース化する。
  3. Prefabにデータベースを読み込ませるスクリプトを作成する。
  4. Prefabを実体化(インスタンス化)するスクリプトを作成する。

1.診断結果のデータ構造を定義する

データベースの構造を定義します。
エクセルで列の項目名と表示形式(例「項目名:定価 / 表示形式:通貨」)を定義するようなものです。

スクリプト:ResultBase ・・・ Prefabの基礎データを定義する

1 using System.Collections;
2 using System.Collections.Generic;
3 using UnityEngine;
4
5 [CreateAssetMenu] // Projectウィンドウのコンテキストメニューからデータを作成できるようにする
6 public class ResultBase : ScriptableObject // データ構造を定義するクラス:ResultBase
7 {
8     [SerializeField] Sprite resultimage; // Sprite型の変数:resultimageを定義
9     [TextArea] // Inspectorで文字列を複数行入力できるようにする
10    [SerializeField] string resulttext; // string型の変数:resulttextを定義
11
12    public Sprite Resultimage { get => resultimage; } // プロパティを作成(getメソッド)
13    public string Resulttext { get => resulttext; } // プロパティを作成(getメソッド)
14 }

6行目の「ScriptableObject」は、いつもなら「MonoBehaviour」と記述する部分ですが、今回は診断結果のデータベースを作りたいので「ScriptableObject」というクラスを使用します。
※参考URL:ScriptableObjectとは(Unity Documentation)

8行目で診断結果に表示する画像(Sprite型)の「変数:resultimage」を定義しています。

10行目で診断結果に表示するテキスト(string型)の「変数:resulttext」を定義しています。
また、9行目で変数:resulttextに複数行の文字列を入力できるようにしています。

12行目で「プロパティ」を使って「get」でSprite型の「プロパティ:ResultImage」に「変数:resultimage」を代入しています。
同様に、13行目でstring型の「プロパティ:ResultText」に「変数:resulttext」を代入しています。

プロパティの生成方法:変数 resultimage の場合

STEP
[SerializeField] Sprite resultimage; の resultimage の上で右クリックする

コンテキストメニューが開くので「クイックアクションとリファクタリング」を選択します。

プロパティの作り方
STEP
コンテキストメニューから「フィールドのカプセル化」を選択する
フィールドのカプセル化
STEP
プロパティが生成されるので不要な部分を削除する

プロパティ(get、set)が生成されるので、今回不要な「set」以下を削除します。

不要なsetメソッドを削除する

5行目に [CreateAssetMenu] と追記すると、UnityエディターのProjectウィンドウの「+」から、診断結果データ(Result Base)を作成できるようになります。

ProjectウィンドウからResultBaseを作れるようになる

2.診断結果をデータベース化する

まず、Prefabフォルダ内に診断結果データを保存する「ResultBaseフォルダ」を作成します。

ResultBaseフォルダを開いた状態でProjectウィンドウの「+」をクリックし、コンテキストメニューから「Result Base」を選んでクリックします。
すると、Inspectorウインドウに「プロパティ:ResultImage」と「プロパティ:ResultText」が表示されるので、それぞれに画像とテキストを設定します。

ProjectウィンドウからResultBaseを作れるようになる

これを診断結果0~7まで、8パターン作成します。

Result0から7まで8つ作成する

3.Prefabにデータベースを読み込ませるスクリプトを作成する

診断結果データ(Result)を8つ作成したので、これをPrefabに読み込ませるスクリプトを作成します。

内容としては、Prefabの「変数:rimage(イメージ:ResultImage)」にはResultBaseの「プロパティ:ResultImage(変数:resultimageが代入されている)」を、Prefabの「変数:rtext(テキスト:ResultText)」にはResultBaseの「プロパティ:ResultText(変数:resulttextが代入されている)」を読み込ませる、というものです。

スクリプト:ResultBase

スクリプト:Result ・・・ PrefabにResult Baseのデータを読み込ませる

1 using System.Collections;
2 using System.Collections.Generic;
3 using UnityEngine;
4 using UnityEngine.UI; // ImageやText、ButtonといったUIを扱う場合に必要な名前空間
5 using TMPro; // TextMeshProのテキストなどを扱う場合に必要な名前空間
6
7 public class Result : MonoBehaviour
8 {
9     [SerializeField] Image rimage; // Image型の変数:rimageを定義
10    [SerializeField] TextMeshProUGUI rtext; // TextMeshProUGUI型の変数:rtextを定義
11
12    public void Set(ResultBase resultBase) // 引数:ResultBaseを持つメソッド:Set
13    {
14        rimage.sprite = resultBase.Resultimage; // 変数:rimageへ、引数と対応したResultImageを代入
15        rtext.text = resultBase.Resulttext; // 変数:rtextへ、引数と対応したResultImageを代入
16    }
17 }

4行目に「using UnityEngine.UI;」を追記します。画面上に画像や文字といったUIを表示させる場合に必要です。これがないと、9行目の「[SerializeField] Image rimage;」でエラーが出ます。

5行目に「using TMPro;」を追記します。TextMeshProUGUI型の変数(今回は「変数:rtext」)を扱う場合に必要です。これがないと、10行目の「 [SerializeField] TextMeshProUGUI rtext;」でエラーが出ます。

9行目でImage型の「変数:rimage」を定義。この変数が診断結果データベースの「プロパティ:ResultImage」に対応しています。

10行目でTextMeshProUGUI型の「変数:rtext」を定義。この変数が診断結果データベースの「プロパティ:ResultText」に対応しています。

12行目で「引数:resultBase」を持つ「メソッド:Set」を記述。

14行目で「変数:rimage」へ「引数:resultBase」と対応したResultImageを代入しています。
同様に、15行目で「変数:rtext」へ「引数:resultBase」と対応したResultTextを代入しています。

以上で、診断結果データベース:ResultBaseから対応する診断結果のデータ(テキストと画像)をPrefabに読み込む準備ができました。
最後に、この「スクリプト:Result」をPrefab(Result)にアタッチしてください

「スクリプト:Result」をアタッチすると、Prefab(Result)のInspectorウインドウに「rImage」と「rtext」を指定する欄ができるので、以下のように設定してください。

  • rimage:Prefab(Result)の「ResultImage」をセット
  • rtext:Prefab(Result)の「ResultText」をセット
Prefubにスクリプト:Resultをアタッチする

4.Prefabを実体化(インスタンス化)するスクリプトを作成する

最後に、診断結果データ(0~7)の中から番号でデータを指定し、その内容を読み込んだPrefabを実体化(インスタンス化)するスクリプトを作成します。

1 using System.Collections;
2 using System.Collections.Generic;
3 using UnityEngine;
4
5 public class ResultGenerator : MonoBehaviour
6 {
7    [SerializeField] ResultBase[] resultBases; // 診断結果データの配列(0~7)
8    [SerializeField] Result resultprefab; // インスタンス化するPrefabを指定する変数
9    [SerializeField] Transform spawnplace; // インスタンス化する場所を指定する変数
10   public GameObject ParentPanel;
11
12   public void Spawn(int number) // 引数:numberに対応するprefabを生成
13   {
14       Result result = Instantiate(resultprefab,spawnplace,false); // 引数に生成するPrefab、生成場所を指定
15       result.Set(resultBases [number]); // 生成したPrefabに引数:numberに応じた診断結果データを反映
16       ParentPanel.transform.localPosition = new Vector2(0, 0); // 親パネルの位置を(0, 0)に移動
17   }
18 }

7行目で診断結果データの個数を指定する「変数:resultBases」を配列で定義。

8行目でインスタンス化するゲームオブジェクト(今回は「Prefab:Result」)を指定する変数を定義。
また、9行目でゲームオブジェクトをインスタンス化する場所(今回は「親パネル:ParentPanel」)を指定する変数を定義しています。

10行目では「親パネル:ParentPanel」を操作するオブジェクトとして読み込んでいます。

14行目で「Prefab:Result」をインスタンス化し、15行目でそのPrefabに診断結果データを反映しています。その際、7行目で定義した「変数:resultBases」の番号と「引数:number」を対応させています。

16行目では「はい / いいえ」のボタンをクリックする度に移動していた親パネル:ParentPanelを、ゲーム開始位置(0,0)に戻しています。こうすることで「初めからやり直す」ボタンをクリックした際に、また一番最初の設問が表示されるようになります。

最後に、空のゲームオブジェクト(今回は「ResultGenerator」)を作成し、この「スクリプト:ResultGenerator」をアタッチしてください

「スクリプト:ResultGenerator」をアタッチしたら、Inspectorウインドウに以下のように設定してください。

ResultGeneratorのInspectorウインドウ
  • Result Bases:8(診断結果データの数)
  • Element 0~7:診断結果データをすべて参照
  • Resultprefab:Prefab:Resultをセット
  • Spawnplace:Canvasをセット
  • Parent Panel:親パネル:ParentPanelをセット

空のゲームオブジェクト:ResultGeneratorのInspectorウインドウ

空のゲームオブジェクトにスクリプト:ResultGeneratorをアタッチ
ゆくすぃ

以上で、Prefabを利用して診断結果を表示させる準備が整いました!早速、ボタンにOnClickイベントを設定していきましょう!

診断結果を表示させる

「パネル:Question3~6」の「ボタン:Yes3~6」と「ボタン:No3~6」のOnClickイベントに「スクリプト:ResultGenerator」の「メソッド:Spawn」をセットしていきます。

Hierarchyウインドウで任意のボタンを選択し、InspectorウインドウのOnClickイベントを下図のように設定します。

OnClickイベント
  1. 空のゲームオブジェクト:ResultGenerator」をセット
  2. 「スクリプト:ResultGenerator」の「メソッド:Spawn」をセット
  3. 表示させたい診断結果データの番号(Result番号)を入力
ボタンのOnClickイベントを設定する

再生モードでプロジェクトを実行する

エディター画面のツールバーにある「▶(再生ボタン)」をクリックすると、Gameビューに切り替わり、再生モードでプロジェクトが実行されます。

再生モードでプロジェクトを実行する

再生モードに入ると、ゲーム画面の外側が暗くなります。この状態で設問に答えていき、最後に診断結果が表示されればOKです!
※「初めからやり直す」ボタンには、まだスクリプトをアタッチしていないので、クリックしても反応はありません。

GameビューからSceneビューに戻るには、もう一度、再生ボタンをクリックします。

まとめ

今回の記事では、診断結果の作成について解説しました。
「クラス:ScriptableObject」でデータベースを作って、それをPrefabに読み込ませ、引数を渡して狙った結果を表示させる・・・という手順は少しややこしいですが、活用できるようになるとゲーム開発が楽になります。コツを掴むまで何度も挑戦してください!

次回は、【最終回】超入門!Unityで診断ゲームを作ろう!「Prefabの削除、SEの設定編」です。

以上、最後まで読んでいただき有難うございました!

よかったらシェアしてね!
  • URLをコピーしました!
目次