UnityでFPSをつくる その10-2 [ シーン遷移 ]

2020年9月8日

前回までで完成したGameOverSceneへ、MainSceneから遷移するようにします。

No.423

ProjectウィンドウからMainSceneをダブルクリックしてSceneを切り替えます。
GameOverSceneの時同様、空のオブジェクトを作り「SceneManager」にリネーム。
Tag「SceneManager」を新規で作成してSceneManagerオブジェクトに付けます。

No.424

UIのImageを追加して「FadeBoard」にリネーム、Width・Height・Colorを以下のように変更します。

No.425

これを画面暗転用に使います。
スクリプトから、暗転するタイミングを実装していきましょう。
「GameOverSceneChange」と名付けたスクリプトを新たに作り、以下のコードを貼り付けてください。

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
//シーンを扱う為の名前空間
using UnityEngine.SceneManagement;

public class GameOverSceneChange : MonoBehaviour
{
    [SerializeField] Image fadeBoard;

    //色、透明度
    float red, green, blue, alfa;

    // Start is called before the first frame update
    void Start()
    {
        
    }

    // Update is called once per frame
    void Update()
    {
        
    }

    public void ToGameOverScene() 
    {
        StartCoroutine("fadeOut");
    }

    IEnumerator fadeOut() 
    {
        yield return new WaitForSeconds(5f);

        //フェードアウト
        var isFadeOut = true;

        //何秒かけて不透明にするか
        var duration = 5f;

        //colorの個々の値は取得できても変更できない為、変数に代入する
        red = fadeBoard.color.r;

        green = fadeBoard.color.g;

        blue = fadeBoard.color.b;

        alfa = fadeBoard.color.a;

        while (isFadeOut) 
        {
            //durationの時間で暗転するよう、アルファ値を加算
            alfa += Time.deltaTime / duration;
            
            //アルファ値以外は変更せずにcolorに値を代入
            fadeBoard.color = new Color(red, green, blue, alfa);

            //透明度が1(完全に不透明)になったら
            if (alfa >= 1)
            {
                //フェードアウト終了
                isFadeOut = false;
            }

            yield return null;
        }

        yield return new WaitForSeconds(1f);

        //ゲームオーバーシーンに切り替え
        SceneManager.LoadScene("GameOverScene");
    }
}

コードを見ていきます。
UIを扱うのでnamespaceにUnityEngine.UIを追加し、更に今回はSceneを遷移する関数を使うので、UnityEngine.Managementを追加しています。

No.426

13行目では、Colorの値を変更する為に必要な項目分の変数を用意しています。

No.427

27行目で外部クラスからアクセスできるようpublicで関数を宣言し、コルーチンを開始、32行目からコルーチンの定義をしています。

No.428

コルーチン開始後に5秒待機して、フェードアウト処理継続を判断するフラグを立て、継続時間を設定しています。

No.429

new Color(r,g,b,a)の形で値を代入する為に各要素を取得しています。

No.430

whileループをフラグで判断させて開始し、指定した継続時間分かけてアルファ値を上限値である1にします。

No.431
No.432

アルファ値最大でフラグを下ろし、1秒待機後にシーンを切り替えています。

No.433

このスクリプトをSceneManagerにアタッチして、FadeBoardを選択します。

No.434

これで呼び出される側の準備が整いました。
呼び出しはPlayerのスクリプトから行います。
スクリプトPlayerHPへ以下のように追記してください。

No.435

これにより、HPが0になって画面全体が赤くなったタイミングでSceneManagerにアタッチしたスクリプトの関数が呼ばれます。

これで完成のように見えますが、もう一点必要なことがあります、使用するシーンはあらかじめ登録しておかなればいけません。
メニューバーからFile → Build Settingsを開いてください。

No.436
No.437

Add Open Scenes ボタンをクリックすると現在編集中のシーンが追加されました。
右端に「0」と表示されていますが、これは「0」から始まるシーンを実行する順番の数字です。
シーン追加は、画面で編集中のシーンしかできない為、GameOverSceneに切り替えて追加しましょう。

No.438

これでシーン遷移が上手くいくか確認します。
MainSceneから実行してみると

No.439

MainからGameOverへのシーン遷移が完成しました。

同様に、クリア画面への遷移を実装していきます。
Scenesフォルダへ「GameClearScene」と名付けてSceneを作成し、GameClearSceneへ切り替えます。

No.440

GameOverSceneでは背景に黒色のボードを用意しましたが、GameClearSceneではカメラの背景色を変える方法でやってみます。
MainCameraを選択して設定を以下のようにしてください。

No.441

カメラに映る背景が黒になりました。
ここに文字を表示していきます、以下は完成イメージです。

No.442

まずはHierarchyウィンドウにUI → Text を作成し、Inspector項目を以下のように設定してください。

No.443

さらにAdd ComponentからUI → Effects → Outlineを選択して、以下のように設定します。

No.444
No.445

背景をアレンジしていきます。
HierarchyウィンドウにCreateEmptyで空のオブジェクトを作り「Images」とリネーム、Canvas内の並び順をTextの上にします。

No.446

Imagesの子オブジェクトにImageを作り、下図のように設定してください。

No.447

このオブジェクトを「Ctrl + D」で複製します。

No.448
No.449

Textに影付けをしていきます。
Textオブジェクトを「Ctrl + D」で複製して「TextShadow」にリネーム、下図のように設定してください。

No.450

Canvas内の並び順をImagesの下、Textの上にします。

No.451
No.452

影付けができました。
「Congratulations!」と名付けた空オブジェクトを新規作成し、TextとTextShadowをひとまとめにしましょう。

No.453

次に、MainSceneから遷移してきた際にTextを拡大させる演出を加えます。

No.454

「TextScaleUp」と名付けたスクリプトを新規作成し、以下のコードを貼り付けてください。

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

public class TextScaleUp : MonoBehaviour
{
    //拡大にかける時間
    [SerializeField]float duration;

    //元のサイズ保持用
    Vector3 originalSize;

    // Start is called before the first frame update
    void Start()
    {
        //元のサイズを取得
        originalSize = transform.localScale;

        //ローカル座標のサイズを「0」に変更
        transform.localScale = Vector3.zero;
    }

    // Update is called once per frame
    void Update()
    {
        //duration分の時間をかけて元のサイズに近づける
        if (transform.localScale.x < originalSize.x)
        {
            transform.localScale += new Vector3(originalSize.x * Time.deltaTime / duration, originalSize.y * Time.deltaTime / duration);
        }
        else 
        {
            //ローカル座標のサイズを元のサイズに変更
            transform.localScale = new Vector3(originalSize.x, originalSize.y);
        }
    }
}

コードを見ていきます。
8行目で、どのくらいの時間をかけてテキストを拡大するか調整する為の変数を宣言。
11行目で、拡大目標となる現在のサイズ(縮小前のサイズ)を取得する為の変数を宣言しています。

No.455
No.456

17行目で縮小前のサイズを取得してから、20行目でサイズを「0」にしています。

No.457

今回は各方向の値がいずれも等しく、

No.458

同じ値ずつ拡大させる為、XYZいずれか一つの値を比較すれば済むので、27行目のif文ではXの値のみを比較して判定しています。

No.459

localScaleへの加算はXY成分に対して元のサイズにTime.deltaTime(1秒かかって1になる)を掛けてduration分の時間がかかるように割っています。
Z成分は拡大に関係ないので省略しています。

No.460

元のサイズに達したら、拡大のズレ(Time.deltaTimeの値が各フレーム一定でないことによる)を修正する為に元のサイズを代入して値を統一しています。

No.461
No.462

このスクリプトを「Congratulations!」オブジェクトにアタッチ、Durationを「0.5」に設定して完成です。

No.463
No.464

長くなってきたので続きは次回にしたいと思います。おつかれさまでした!

FPS

Posted by kenji