
ごきげんよう、Budding Lab.編集部のゆくすぃです!
実は、チラズアートさんのホラー作品も大好きです。新作リリースが待ち遠しいですね!
ゲームが大好きな皆さんなら、一度は「自分でゲームを作ってみたい!」と、思ったことがあるのではないでしょうか?
本連載では、ゲーム開発初心者のゆくすぃが、基礎的なスクリプトだけを使って、超入門・診断ゲームの作り方を解説します!
本記事は、第7回「診断結果の作成編」です。
プログラミングの専門知識がなくたって、画像や音楽作成アプリが使えなくたって、案外、ゲームって作れるものです。興味が湧いたなら、ぜひ挑戦してみてください!
Prefabとは
診断結果を全部で8つ作成します。ゲーム画面(設問画面)同様に、パネルで作成して並べても良いのですが、今回はPrefab(プレファブ)を使ってみようと思います。
Prefabとは、ゲームオブジェクトの設計図のようなものです。量産したいゲームオブジェクトのテンプレートを一つ作り、それをPrefab化すると、PrefabをHierarchyウインドウやエディター画面にドラッグ&ドロップしたり、スクリプトで呼び出したりしてゲームオブジェクトを量産できるようになります。


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にデータベースを読み込ませるスクリプトを作成する。
- 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 の場合
コンテキストメニューが開くので「クイックアクションとリファクタリング」を選択します。




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


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


2.診断結果をデータベース化する
まず、Prefabフォルダ内に診断結果データを保存する「ResultBaseフォルダ」を作成します。
ResultBaseフォルダを開いた状態でProjectウィンドウの「+」をクリックし、コンテキストメニューから「Result Base」を選んでクリックします。
すると、Inspectorウインドウに「プロパティ:ResultImage」と「プロパティ:ResultText」が表示されるので、それぞれに画像とテキストを設定します。


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


3.Prefabにデータベースを読み込ませるスクリプトを作成する
診断結果データ(Result)を8つ作成したので、これをPrefabに読み込ませるスクリプトを作成します。
内容としては、Prefabの「変数:rimage(イメージ:ResultImage)」にはResultBaseの「プロパティ:ResultImage(変数:resultimageが代入されている)」を、Prefabの「変数:rtext(テキスト:ResultText)」にはResultBaseの「プロパティ:ResultText(変数:resulttextが代入されている)」を読み込ませる、というものです。


スクリプト: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」をセット


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ウインドウに以下のように設定してください。
- Result Bases:8(診断結果データの数)
- Element 0~7:診断結果データをすべて参照
- Resultprefab:Prefab:Resultをセット
- Spawnplace:Canvasをセット
- Parent Panel:親パネル:ParentPanelをセット
空のゲームオブジェクト:ResultGeneratorのInspectorウインドウ





以上で、Prefabを利用して診断結果を表示させる準備が整いました!早速、ボタンにOnClickイベントを設定していきましょう!
診断結果を表示させる
「パネル:Question3~6」の「ボタン:Yes3~6」と「ボタン:No3~6」のOnClickイベントに「スクリプト:ResultGenerator」の「メソッド:Spawn」をセットしていきます。
Hierarchyウインドウで任意のボタンを選択し、InspectorウインドウのOnClickイベントを下図のように設定します。
- 「空のゲームオブジェクト:ResultGenerator」をセット
- 「スクリプト:ResultGenerator」の「メソッド:Spawn」をセット
- 表示させたい診断結果データの番号(Result番号)を入力


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


再生モードに入ると、ゲーム画面の外側が暗くなります。この状態で設問に答えていき、最後に診断結果が表示されればOKです!
※「初めからやり直す」ボタンには、まだスクリプトをアタッチしていないので、クリックしても反応はありません。
GameビューからSceneビューに戻るには、もう一度、再生ボタンをクリックします。
まとめ
今回の記事では、診断結果の作成について解説しました。
「クラス:ScriptableObject」でデータベースを作って、それをPrefabに読み込ませ、引数を渡して狙った結果を表示させる・・・という手順は少しややこしいですが、活用できるようになるとゲーム開発が楽になります。コツを掴むまで何度も挑戦してください!
次回は、【最終回】超入門!Unityで診断ゲームを作ろう!「Prefabの削除、SEの設定編」です。
以上、最後まで読んでいただき有難うございました!