Unity学習サイト

ホーム / 落下判定、Sceneの読み込み

さて、三つ目の講座になりました。前回の講座では鳥を左右、ジャンプまで出来るように なりましたね。
今回は鳥さんが落下したときの処理とクリア時の処理を追加していきます!

今回の講座では下のミニゲームの内容まで作ることができます。

この講座での最終完成形

Missシーン作成

鳥さんが落下したとき今のところずっと落ち続けていきます。それをある程度落ちたら リスタートできるようにしていきましょう!まずは、落ちた時のシーンを作りましょう。 シーンフォルダを開きそこで右クリックしてCreate→Sceneで新しいシーンを作ります。

新しいシーンの名前はMissにしておきましょう。作れたらMissシーンをダブルクリックで 開いてください、何もない新しいシーンができてますね。

学習素材の入手

下記の画像は、クリックすると自動でダウンロードされます。

Scene

上記の画像を保存(クリックで保存できます)して、UnityのItemフォルダに保存してください。 名前はわかりやすいもので適当でいいです。私は、misshaikeiとしました。
その画像をシーン画面にドラックアンドドロップしてください。 すると、画像のサイスがすこし小さくなっていますね。先ほどシーンに登録した 画像をヒエラルキーウィンドウで選択して、インスペクターウィンドウのトランスフォーム コンポーネントの一番上のPsitionをすべて0に次に一番下のScaleの数値をすべて2にしてください。

ちょうどいいサイズ感になりましたね。これが、ミスしたときの背景になります。
次に、シーンを読み込むためのスクリプトを書いていきましょう。スクリプトフォルダ に新しいスクリプトを作ります。右クリック→Create→C# Scriptでスクリプトを作って 名前を、MissシーンをコントロールするのでMisscにしましょう。適当です(笑)

ここにスクリプトを組んでいきます。大したことありません。
まずは、一番上のUsingと書いてあるところに、シーンマネージャーという機能を使いますよと 宣言を追加します。

using UnityEngine.SceneManagement;

次に、Update関数にエンターでMainシーンを読み込むというコードを追加します。
下記のコードはエンターキー(海外ではreturn)が押されてボタンが上がった時に Mainシーンを読み込むというコードになります。

void Update()
    {
        if (Input.GetKeyUp(KeyCode.Return))
        {
            SceneManager.LoadScene("Main");
        }
    }

出来たらUnityにアタッチして、書いたスクリプトをMissシーンのMainCamera にドラックアンドドロップして再生してみてください。そうですね、メインシーンは 何もしていないので最初のシーンには戻れません。次はメインシーンで鳥さんの 落下処理についてやっていきましょう。

鳥落下時

さあ、次は鳥の落下時のシーンの読み込みを学んでいきましょう。
まずは、先ほどMisscスクリプトで行ったスクリプトの最上部usingのところに シーンマネージャーを使いますと、宣言するところから行っていきます。

using UnityEngine.SceneManagement;

宣言ができたら次は落下の判定について記述していきます。 落下の判定の仕方は何種類かありますが。今回はy軸を使って落下の 判定をしていきます。
Update関数内に記述していきましょう。下記のコードになります、if文でトランスフォーム のy軸、つまり縦方向が-20以下になったらMissシーンを読み込むというコードです。

if (transform.position.y < -20)
        {
            SceneManager.LoadScene("Miss");
        }

完成?かと思うのですが実はこのままだとUnityで再生するとエラーが出て Missシーンを読み込みません。
エラーが出ても焦らずにゲームの再生を止めてコンソールウインドウで なぜエラーが出たのか確認しましょう。
今回はコードの問題ではなく、Unityの設計上の問題でのエラーになります。 Unityは新しく作ったシーンをUnityのBuild設定画面というところにシーンの 登録をしないとシーンが読み込めないのです。なので、シーンをbuild画面に 登録してあげましょう。
まずは、Unityの画面の最上部からFile→Build Settingsでビルド画面を開いてください。

次に、開いたビルド画面にアセットウィンドウにあるシーンフォルダの中の Missシーンを下記の画像のようにドラックアンドドロップして登録してください。 ドラックアンドドロップのみで登録は完了していますので×で消してしまって大丈夫 です。

それでは再生して確かめてみましょう。しっかりと出来ていますか?出来ていたらOKです!
下にコードへの理解を深めるための応用編があります。本編とは関係ないので こんなこともできるのかという感じで参考にしてみてください。

コードへの理解を深める応用編

落下の判定で使用しているコードはY軸で落下の判定をしていますね、これを応用して横に行きすぎたら ゲームオーバーになるゲームを作ることができます。上へ上るゲームや、スマッシュブラザーズのようなゲームでこのような 仕組みを見かけますね。
先ほどの落ちるコードのパラメータに手を加えて、Y軸での判定をX軸に変更しIf文をXが-5以下になったとき またはXが5以上になった時というものに変えます。コードは下のようになります。

if (transform.position.x > 5 || transform.position.x<-5)
        {
            SceneManager.LoadScene("Miss");
        }

具体的にどのようになるのか下のプログラムで確認してみましょう。X軸が5と-5になるとゲームオーバーになります。

実際に動かして確認してみましょう

コードへの理解を深められましたか?
次は、ゲームクリアへの変遷 を学んでいきましょう。

ゲームクリア時シーン変遷

お次はゲームクリア時のシーン変遷についてです!
ゲームクリアのシーン変遷の方法は今までやってきた ことを組み合わせるだけです!
行う事は、当たり判定でtagを利用してゴールの識別をする→if文で識別した ものがゴールであればクリアシーンをロードする。
以上になります。なんだかできそうな気がしますね? では、おさらいしながらやっていきましょう!

学習素材の入手

下記の画像は、クリックすると自動でダウンロードされます。

Box Collider 2D

まずは、上の画像をtoriyaという名前で保存してください。(クリックで自動保存されます)それを、Itemフォルダに 入れてシーンウィンドウのいいとこ(鳥さんが到達できるところ)に配置してください。 次に、Add Component→Physics2D→Box Collider 2DをつけてEdit colliderで わかりにくいですが下の画像のように、扉のところに合わせて衝突判定をつけてください。

次に、焼き鳥屋のTagを新しく追加しましょう。インスペクターウィンドウ の最上部Tagの横にあるドロップダウンをクリック→Add Tag→✙でTagの名前を Goalで追加してください。追加したままでは無くTagの変更も忘れずに行ってください。 出来ましたでしょうか?わからなければ、前の講座に 詳しく書いておりますのでご確認ください!

次に、鳥さんがGoalTagを認識するためのスクリプトを書きましょう。鳥の スクリプトの void OnTriggerEnter2D(Collider2D other)関数に ジャンプの時に書いたTagの取得方法のコードをコピペしてTag名の変更 とjamp=falseを削除してはりましょう。あ、あとロードするシーン名 等も追加しないとですね。ひとまずは下記のコードのようにしておきましょう。

if (other.gameObject.CompareTag("Goal"))
        {
            print("Goalしたよ");
        }

次は、クリアシーンの作成をしていきましょう。シーンフォルダで右クリック →Create→Sceneで新しいシーンを作って名前をClearにしてください。
出来たら先に、ビルド画面にシーンを登録しておきましょう。File→Build Settings →Scene in Build画面にClearシーンをドラックアンドドロップで登録完了です。
次に、Missシーンと同じくMainシーンに戻るためのコードを書きましょう。これに関しては Missシーンのコードと全く同じ作業です。
Scriptフォルダで右クリック→create→C#で新しくスクリプトを作ります。 名前はClearcにしましょう。作れたら開いて、必要なコードを書いても いいですし、Misscスクリプトからパーツを取ってきても大丈夫です。 ただ、全部をコピペするとクラス名も変わってしまいますのでパーツをごとに 取り出しましょう。
記述するコードはusingのところのシーンマネージャーを使う宣言 の部位とUpdate関数のエンターでMainシーンをロードするという if文です。

using UnityEngine.SceneManagement;

と以下の文です。

void Update()
    {
        if (Input.GetKeyUp(KeyCode.Return))
        {
            SceneManager.LoadScene("Main");
        }
    }

スクリプトの変更ができたら、先程書き途中だった鳥のスクリプトを 完成させましょう。鳥スクリプトのIf文の中身をClearシーンを読み 込むようにしましょう。簡単ですね。

if (other.gameObject.CompareTag("Goal"))
      {
          SceneManager.LoadScene("Clear");
          print("Goalしたよ");
      }

まだ作業は残っています、UnityにアタッチしてClearシーンのヒエラルキーウィンドウにある メインカメラにClearcスクリプトをドラックアンドドロップでつけてください。
出来たら、再生して動きを確認してみましょう。

実際に動かして確認してみましょう

あれれ、鳥が店の裏口から侵入してますね、、、。2DのUnityだと 多くの画像を扱っているので画像の前後ろの問題が生まれます。 それを直さないとうまくいきません。チャチャっと直しちゃいましょう。
Mainシーンのtoriya(焼き鳥屋)をクリックして、インスペクターウィンドウ を確認してください。そこにSprite Rendererコンポーネントがあります。 このコンポーネントは画像の情報をいじれるコンポーネントになります。 このコンポーネントの最下部Order in Layerというものがあると思います、これは 画像の重なりをどうするかを決めるものになります。0が最初から入っていて0は基準に なるのでこれを-1にしてあげましょう。

出来ましたか?今回の講座はこれで終わりです!お疲れ様でした! 次はネギを卵で捕まえる回になります!?
最後に鳥スクリプトとClearシーンのスクリプトを貼っておきます!

Toriスクリプト

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.SceneManagement;

public class Tori : MonoBehaviour
{
    Rigidbody2D rigid2D;
    float maxWalkSpeed = 2.0f;
    float walkForce = 30.0f;
    float jumpForce = 5.0f;
    public float defScalex;
    public bool jump = false;

    void Start()
    {
        this.rigid2D = GetComponent<Rigidbody2D>();
        this.defScalex = transform.localScale.x;
    }

    void Update()
    {
        //左右移動
        int key = 0;
        if (Input.GetKey(KeyCode.RightArrow))
            key = 1;
        if (Input.GetKey(KeyCode.LeftArrow))
            key = -1;
        //プレイやーの速度
        float speedx = Mathf.Abs(this.rigid2D.velocity.x);
        //スピードで制限
        if (speedx < this.maxWalkSpeed)
        {
            this.rigid2D.AddForce(transform.right * key * this.walkForce);
        }
        //移動時の反転
        if (key != 0)
        {
            transform.localScale = new Vector3(-1 * key * defScalex, transform.localScale.y, 1);
        }
        //ジャンプ
        if (Input.GetKeyDown(KeyCode.Space) && !jump)
        {
            this.rigid2D.AddForce(transform.up * this.jumpForce, ForceMode2D.Impulse);
            jump = true;
        }
        //落下の判定
        if (transform.position.y < -20)
        {
            SceneManager.LoadScene("Miss");
        }
    }

    void OnTriggerEnter2D(Collider2D other)
    {
        if (other.gameObject.CompareTag("Ground"))
        {
            jump = false;
            print("グランドに接地したよ");
        }

        if (other.gameObject.CompareTag("Goal"))
        {
            SceneManager.LoadScene("Clear");
            print("Goalしたよ");
        }
    }
}

Clearcスクリプト

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.SceneManagement;

public class Clearc : MonoBehaviour
{
    void Update()
    {
        if (Input.GetKeyUp(KeyCode.Return))
        {
            SceneManager.LoadScene("Main");
        }
    }
}

次の講座へ

ホームへ