【第6回】超入門!Unityで2D脱出ゲームを作ろう!「部屋の移動編」

第6回部屋の移動編
ゆくすぃ

ごきげんよう、Budding Lab.編集部のゆくすぃです!
複数のモバイルゲームを同時進行するのが苦手で、ログイン報酬すら受け取れないことが多いです・・・。

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

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

本記事は、第6回「部屋の移動編」です。

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

目次

ゲーム画面の見え方を設定、カメラを指定する

今回作成するゲームでは、ゲーム画面を映し出しているカメラの位置を座標(0,0)に固定します。
そして、部屋1(=パネル:Room1)/ 部屋2(=パネル:Room2)/ 部屋3(=パネル:Room3)を子とするパネルグループ(=親パネル:ParentPanel)を左右に動かして、カメラに映るパネルを切り替えます。

ゲーム画面上で部屋を移動しているように見えている仕組み

部屋を移動する仕組みについて

まずは、HierarchyウインドウでCanvasを選択します。
※これまで作成してきたパネルやボタン・画像といったUI要素は、すべてCanvas(Canvasコンポーネントがアタッチされたゲームオブジェクト)の子要素となっています。UI要素はCanvasの子要素でなければゲーム画面に描画されません。

HierarchyウインドウでCanvasを選択する

次に、Inspectorウインドウで「Canvasコンポーネント」と「Canvas Scalerコンポーネント」を設定します。CanvasコンポーネントではUI要素の描画方法とカメラの指定を、Canvas Scalerコンポーネントではゲームの画面サイズ(解像度)が変わった時の対応方法を設定します。

CanvasコンポーネントとCanvas Scalerコンポーネントの設定

Canvasコンポーネント

  • Render Mode:Canvasをシーンに描画する方法を指定
    Screen Space – Camera:指定したカメラによって正面から描画される
  • Render Camera:カメラを指定する
    Main Camera(Camera):HierarchyウインドウでCanvasの上にあるMain Cameraを指定

Canvas Scalerコンポーネント

  • UI Scale Mode:Canvas 内の UI 要素をどのようにスケーリングするかを決める
    Scale With Screen Size:画面サイズに依存、倍率が変わっても見た目が変わらない
  • Reference Resolution:UI要素をレイアウトした時の解像度(設計時の画面サイズ)
    今回は「X 1080 / Y 1920」と入力
InspectorウインドウでRender Modeなどを設定する

以上で、GameSceneの見え方・カメラの指定ができました。
TitleScene・ClearSceneでも同様の設定をしてください。

Room1から移動するスクリプトを書く

まずは、エクセルやパワーポイントでブックやプレゼンテーションを新規作成するように「C# スクリプト」を新規作成します。

Scriptsフォルダを開き、Projectウインドウで右クリックすると、コンテキストメニューが表示されます。その中から「Create」を選び、追加で展開されるメニューの中から「C# Script(C# スクリプト)」を選んでクリックします。

スクリプトを新規作成する

Scriptsフォルダ内に新しいスクリプトが作成されるので、名前を付けて確定します。今回は「PanelChanger」としました。

この「スクリプト:PanelChanger」を「パネルグループ:ParentPanel」にアタッチします

ParentPanelのinspectorウインドウで「Add Component」からPanelChangerをアタッチする

PanelChangerをParentPanelにアタッチする

基本となる左右移動のスクリプトを書く

スクリプト:PanelChanger」を開いて、以下のようにスクリプトを書いてみましょう。
これは、Room1に表示された「RightArrow(右向き矢印)」と「LeftArrow(左向き矢印)」をクリックしたときの部屋の移動(ParentPanelの動き)を記述したものです。
※Room2・Room3に移動したの矢印の動きについては、後ほど説明します。

1 using System.Collections;
2 using System.Collections.Generic;
3 using UnityEngine;
4
5 public class PanelChanger : MonoBehaviour
6 {
7    public void OnRightArrow() // 右向き矢印をクリックした時の動き
8    {
9        // Room2(1500,0)を表示する
10        this.transform.localPosition = new Vector2(-1500, 0);
11   }
12
13   public void OnLeftArrow() // 左向き矢印をクリックした時の動き
14   {
15       // Room3(-1500,0)を表示する
16       this.transform.localPosition = new Vector2(1500, 0);
17   }
18 }

「7行目:Public void OnRightArrow()」が、RightArrowをクリックした時に呼び出される(=実行される)メソッド、その中身(=処理)が「10行目:this.transform.localPosition = new Vector2(-1500, 0); 」です。

this.transform.localPosition = new Vector2(-1500, 0);
  • this.transform.localPosition:このスクリプト(=PanelChanger)の親(=ParentPanel)から見た相対的な位置
  • new Vector2(-1500, 0);:位置を(-1500, 0)へ変更

「13行目: public void OnLeftArrow()」が、LeftArrowをクリックした時に呼び出される(=実行される)メソッド、その中身(=処理)が「16行目:this.transform.localPosition = new Vector2(1500, 0); 」です。

this.transform.localPosition = new Vector2(1500, 0);
  • this.transform.localPosition:このスクリプト(=PanelChanger)の親(=ParentPanel)から見た相対的な位置
  • new Vector2(1500, 0);:位置を(1500, 0)へ変更

左右移動のスクリプトをアタッチする

RightArrow・LeftArrowをクリックした時に、それぞれ「スクリプト:PanelChanger」の OnRightArrowメソッドOnLeftArrowメソッドが呼び出されるようにアタッチしましょう。

まずは、RightArrowのinspectorウインドウで「Add Component」からButtonコンポーネントを追加します。これで、OnClickイベントを使えるようになります。

次に、OnClickイベントの右下にある「+(Add to the list)」をクリックし「None (Object)」と表示されている場所へ「ParentPanel」をドラッグ&ドロップします。「No Function」のドロップダウンリストで「クラス:PanelChanger」を選択できるので「OnRightArrow」を選んでクリックします。

RightArrowにButtonコンポーネントを付ける

Buttonコンポーネントがを付ける

OnClickイベントにOnRightArrowを設定

ParentPanelのPanelChangerのOnRightArrowをアタッチする

以上で、Room1に表示されているRightArrowをクリックすると、Room3へ移動する仕組みができました!

同様に、LeftArrowにも「クラス:PanelChanger」のOnLeftArrowメソッドをアタッチしてみてください。すると、Room1に表示されているLeftArrowをクリックすると、Room2へ移動する仕組みができます。

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

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

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

再生モードに入ると、ゲーム画面の外側が暗くなります。この状態で「RightArrow」をクリックしてみましょう。画面が以下のような「Room3」に切り替わればOKです!
GameビューからSceneビューに戻るには、もう一度、再生ボタンをクリックします。

Room1に表示されたRightArrowをクリックすると、Room3に移動する

Room3へ移動

同様に「LightArrow」の方もクリックしてみてください。
画面が以下のような「Room2」に切り替わればOKです!

Room1に表示されたLeftArrowをクリックすると、Room2に移動する

Room2に移動

Room2・Room3から移動するスクリプトを追加する

現在地を把握して、移動先を条件分岐させる

Room1に表示されているRightArrowとLeftArrowは、Room2・Room3でも使い回すことになります。
そのため「どの部屋でRightArrow・LeftArrowがクリックされたのか?」という位置情報をもとに、クリック時の移動先を変化させる(=条件分岐させる)必要があります。

現在地によって、RightArrow・LeftArrowクリック時の移動先を変える

現在地を示す「変数:_currentRoom」を定義して位置情報を把握し、条件分岐させる。

  • Room1にいる時(_currentRoomがRoom1の時)
    RightArrow:表示 / クリックするとRoom3に移動する(_currentRoomがRoom3になる)
    LeftArrow:表示 / クリックするとRoom2に移動する(_currentRoomがRoom2になる)
  • Room2にいる時(_currentRoomがRoom2の時)
    RightArrow:表示 / クリックするとRoom1に移動する(_currentRoomがRoom1になる)
    LeftArrow:非表示
  • Room3にいる時(_currentRoomがRoom3の時)
    RightArrow:非表示
    LeftArrow:表示 / クリックするとRoom1に移動する(_currentRoomがRoom1になる)
1 using System.Collections;
2 using System.Collections.Generic;
3 using UnityEngine;
4
5 public class PanelChanger : MonoBehaviour
6 {
7    public enum Room // Room1, Room2, Room3を列挙型に定義
8    {
9        Room1,
10       Room2,
11       Room3
12   }
13   Room _currentRoom = Room.Room1; // 現在地を示す変数:_currentRoomを設定し、初期値にRoom1をセット
14   public void OnRightArrow() // 右向き矢印をクリックした時の動き
15   {
16       // Room2が表示されていたら
17       if (_currentRoom == Room.Room2)
18       {
19           this.transform.localPosition = new Vector2(0, 0); // Room1(0,0)を表示する
20           _currentRoom = Room.Room1; // 現在地を更新
21       }
22       // Room1が表示されていたら
23       else if(_currentRoom == Room.Room1)
24       {
25           this.transform.localPosition = new Vector2(-1500, 0); // Room3(1500,0)を表示する
26           _currentRoom = Room.Room3; // 現在地を更新
27       }
28   }
29   public void OnLeftArrow() // 左向き矢印をクリックした時の動き
30   {
31      // Room3が表示されていたら
32      if (_currentRoom == Room.Room3)
33      {
34          this.transform.localPosition = new Vector2(0, 0); // Room1(0,0)を表示する
35          _currentRoom = Room.Room1; // 現在地を更新
36      }
37      // Room1が表示されていたら
38      else if(_currentRoom == Room.Room1)
39      { 
40          this.transform.localPosition = new Vector2(1500, 0); // Room2(1500,0)を表示する
41          _currentRoom = Room.Room2; // 現在地を更新
42      }
43   }
44 }

オレンジの文字7行目から12行目で、Room1・Room2・Room3を選択肢とする「グループ:Room(列挙型)」を定義しています。
更に、13行目で現在地を示す「変数:_currentRoom」を設定し、初期値をRoom1にして、ゲームがRoom1から開始するようにしています。

グリーンの文字16行目から41行目で「if文」と呼ばれる制御文を使って、移動先を条件分岐させています。
更に、移動が完了したら「変数:_currentRoom」の値を変更して、現在地を更新しています。

if文
  • 条件式がtrue(真)の時のみ{}内の処理を実行する。
    if(条件式){条件式がtrueの時に実行される処理}※falseの時は処理されない
  • 条件式がfalse(偽)の時の処理を付け足すと、条件分岐できる。
    if(条件式){条件式がtrueの時に実行される処理}
    else {条件式がfalseの時に実行される処理}
  • if else文では、複数の条件分岐が可能。
    if(条件式1){条件式1がtrueの時に実行される処理}
    else if(条件式2){条件式2がtrueの時に実行される処理}
    else if(条件式3){条件式3がtrueの時に実行される処理}※falseの時は処理されない
  • if else文の最後にelseを付けると、どの条件も満たさない場合の処理が可能。
    if(条件式1){条件式1がtrueの時に実行される処理}
    else if(条件式2){条件式2がtrueの時に実行される処理}
    else if(条件式3){条件式3がtrueの時に実行される処理}
    else {条件式がfalseの時に実行される処理}

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

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

  • ゲームがRoom1から開始している
  • Room1でRightArrowをクリックすると、Room3へ移動する。
  • Room3でLeftArrowをクリックすると、Room1へ移動する。
  • Room1でLeftArrowをクリックすると、Room2へ移動する。
  • Room2でRightArrowをクリックすると、Room1へ移動する。

以上が確認できればOKです!
GameビューからSceneビューに戻るには、もう一度、再生ボタンをクリックします。

RightArrow・LeftArrowの表示・非表示を設定する

「クラス:PanelChanger」にスクリプトを追加する

部屋の移動を確認した際にお気付きだと思いますが、Room2・Room3に移動した際、それぞれ不要なLeftArrow・RightArrowが表示されたままになっています。

移動先がないためRoom2にLeftArrowは不要

不要なLeftArrow

移動先がないためRoom3にRightArrowは不要

不要なRightArrow

そこで、位置情報をもとに、RightArrow・LeftArrowの表示・非表示を切り替えることにします。

  1. 一旦、RightArrow・LeftArrowの両方を非表示
  2. 必要に応じてRightArrow・LeftArrowを表示

部屋を移動するごとに、上記の流れでRightArrow・LeftArrowの表示・非表示を切り替える考え方です。

1 using System.Collections;
2 using System.Collections.Generic;
3 using UnityEngine;
4
5 public class PanelChanger : MonoBehaviour
6 {
7    // このスクリプトでRightArrowとLeftArrowのコンポーネントを操作できるようにする
8    public GameObject RightArrow; // GameObject変数:RightArrowを定義
9    public GameObject LeftArrow; // GameObject変数:LeftArrowを定義
10
11   public enum Room // Room1, Room2, Room3を列挙型に定義
12   {
13       Room1,
14       Room2,
15       Room3
16   }
17   Room _currentRoom = Room.Room1; // 現在地を示す変数:_currentRoomを設定し、初期値にRoom1をセット
18
19   private void Start() // Room1が表示された時のRightArrowとLeftArrowの状態(=初期化)
20   {
21       HideArrows(); // RightArrowとLeftArrowを非表示
22       RightArrow.SetActive(true); // RightArrowを表示
23       LeftArrow.SetActive(true); // LeftArrowを表示
24   }
25   public void OnRightArrow() // 右向き矢印をクリックした時の動き
26   {
27       HideArrows(); // RightArrowとLeftArrowを非表示
28
29       // Room2が表示されていたら
30       if (_currentRoom == Room.Room2)
31       {
32           this.transform.localPosition = new Vector2(0, 0); // Room1(0,0)を表示する
33           _currentRoom = Room.Room1; // 現在地を更新
34           RightArrow.SetActive(true); // RightArrowを表示
35           LeftArrow.SetActive(true); // LeftArrowを表示
36       }
37       // Room1が表示されていたら
38       else if(_currentRoom == Room.Room1)
39       {
40           this.transform.localPosition = new Vector2(-1500, 0); // Room3(1500,0)を表示する
41           _currentRoom = Room.Room3; // 現在地を更新
42           LeftArrow.SetActive(true); // LeftArrowを表示
43       }
44   }
45
46   public void OnLeftArrow() // 左向き矢印をクリックした時の動き
47   {
48       HideArrows(); // RightArrowとLeftArrowを非表示
49
50       // Room3が表示されていたら
51       if (_currentRoom == Room.Room3)
52       {
53           this.transform.localPosition = new Vector2(0, 0); // Room1(0,0)を表示する
54           _currentRoom = Room.Room1; // 現在地を更新
55           RightArrow.SetActive(true); // RightArrowを表示
56           LeftArrow.SetActive(true); // LeftArrowを表示
57       }
58       // Room1が表示されていたら
59       else if(_currentRoom == Room.Room1)
60       { 
61           this.transform.localPosition = new Vector2(1500, 0); // Room2(1500,0)を表示する
62           _currentRoom = Room.Room2; // 現在地を更新
63           RightArrow.SetActive(true); // RightArrowを表示
64       }
65   }
66
67   void HideArrows() // RightArrowとLeftArrowを非表示
68   {
69       RightArrow.SetActive(false); // RightArrowを非表示
70       LeftArrow.SetActive(false); // LeftArrowを非表示
71   }
72 }

オレンジの文字7行目から9行目で、RightArrowとLeftArrowのコンポーネントを操作できるように(=表示・非表示を操作できるように)「GameObject変数」として設定しています。

パープルの文字67行目から71行目で、ゲーム画面上のRightArrowとLeftArrowをすべて非表示にする「HideArrowsメソッド」を書いています。RightArrowとLeftArrowを非表示にする処理が何度も登場するので、メソッドとして纏めました。

グリーンの文字19行目から24行目で、ゲーム開始時に1度だけ呼び出されるStartメソッドを利用して、RightArrowとLeftArrowの初期化を行っています。HideArrowsメソッドを使ってRightArrowとLeftArrowを非表示にしてから、改めてRightArrowとLeftArrowを表示しています。

ブルーの文字27行目から63行目で、現在地をもとにRightArrowとLeftArrowの表示を制御しています。

GameObject変数を設定する

「クラス:PanelChanger」でRightArrowとLeftArrowのコンポーネントを操作するために、それぞれを「GameObject変数」として定義しました。
すると、パネル:ParentPanelのInspectorウインドウに「変数:Right Arrow」「変数:Left Arrow」を入力できるようになります

  • 変数:Right Arrow」:RightArrow
  • 変数:Left Arrow」:LeftArrow

以上のように入力してください。これで、RightArrowとLeftArrowの表示・非表示を操作できるようになります。

パネル:ParentPanelのInspectorウインドウに「変数:Right Arrow・Left Arrow」が追加される

ParentPanelのInspectorウインドウにGameObject変数が追加される

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

再生モードで、RightArrowとLeftArrowの表示・非表示が正しく制御されるか確認します。

  • Room1では、RightArrowとLeftArrowが表示されている。
  • Room2では、RightArrowのみ表示されている。
  • Room3では、LeftArrowのみ表示されている。

以上が確認できればOKです!
GameビューからSceneビューに戻るには、もう一度、再生ボタンをクリックします。

ゆくすぃ

遂に、部屋を移動してお菓子を探せるようになりました!
着々とゲームは完成に近付いていますょ!

まとめ

今回の記事では、部屋の移動について解説しました。
位置情報をもとに「画像の表示・非表示の切替」や「クリック時の処理の分岐」を「if文」を使って制御しました。こうした条件分岐の仕組みは頻繁に利用するので、この機会に習得しておいて損はないです!他にも様々な「制御文」がありますので、勉強しておくと、できることが増えて楽しいと思います!

次回は、【第7回】超入門!Unityで2D脱出ゲームを作ろう!「BGM・SEの設定編」です。

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

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