UnityでFPSをつくる その10-2 [ シーン遷移 ]
前回までに完成したGameOverSceneへ、MainSceneから遷移するようにします。

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

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

これを画面暗転用に使います。
スクリプトから、暗転するタイミングを実装していきましょう。
「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.SceneManagement」を追加しています。

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

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

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

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

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


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

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

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

これにより、HPが0になって画面全体が赤くなったタイミングで、SceneManagerにアタッチしたスクリプトから、シーン遷移をする関数が呼ばれます。
これで完成のように見えますが、もう一点必要なことがあります。
使用するシーンは、あらかじめ登録しておかなればいけません。
メニューバーからFile → Build Settingsを開いてください。


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

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

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

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

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

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

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


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

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

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


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

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


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

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

「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行目で、拡大目標となる現在のサイズ(縮小前のサイズ)を取得する為の変数を宣言しています。


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

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

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

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

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


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


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