【Unity】シーン切り替えの前に簡単にテキストや画像を表示する

投稿者: | 2021-04-13

ゲームオーバーでシーンを再読み込みする前に、テキストや画像を表示するためのオブジェクトを簡単に作ってみました。

まずシーンにCanvasを新規作成しました。これを後でプレハブ化して、シーン切り替えをしたいときにインスタンス化することにします。

なので、他のCanvasよりもSort Orderの値を大きくして、一番手前に表示されるようにしました。また、UI Scale Modeを「Scale With Screen Size」にします。

このCanvasの子として画像やテキストを配置します。画像は中央に表示して、縦横サイズをReference Resolutionの値にすると画面いっぱいに表示されます。色を黒にすると画面が真っ暗になります。

テキストも中央に表示します。

また、このCanvasにスクリプトを付けました。インスタンス化されると数秒おきにテキストや画像が表示されます。

using UnityEngine;
using UnityEngine.UI;
using UnityEngine.SceneManagement;

public class GameOver : MonoBehaviour
{
    Text text;
    Image image;
    static GameOver instance;

    // インスタンスを取得
    public static GameOver GetInstance()
    {
        // 無い時
        if (instance == null)
        {
            Debug.Log("インスタンスがありません");
        }
        // 既にある時
        else
        {
            Debug.Log(instance);
        }

        return instance;
    }

    private void Awake()
    {
        // インスタンスが既にある場合
        if (instance != null)
        {                      
            // 新規作成されたものは削除
            Destroy(gameObject);
            Debug.Log("削除されました");
        }
        // 無い時
        else
        {
            instance = this;
            Debug.Log("インスタンスが作成されました");

            // 子のテキストを取得
            text = GetComponentInChildren<Text>();

            // テキストが無い時
            if (text == null)
            {
                // 削除
                Destroy(gameObject);
                Debug.Log("削除されました");
                return;
            }

            // テキストを非表示
            text.enabled = false;

            // 画像を取得
            image = GetComponentInChildren<Image>();

            // 画像が無い時
            if (image == null)
            {
                // 削除
                Destroy(gameObject);
                Debug.Log("削除されました");
                return;
            }
            // 画像を非表示
            image.enabled = false;

            // 1秒後にテキストを表示
            Invoke("EnableText", 1f);
        }
    }

    void EnableText()
    {
        // テキストを表示
        text.enabled = true;

        // 2秒後に画像を表示
        Invoke("EnableImage", 2f);
    }

    void EnableImage()
    {
        // 画像を表示
        image.enabled = true;

        // 2秒後にシーンを再読み込み
        Invoke("LoadScene", 2f);
    }

    void LoadScene()
    {
        // 現在のシーンをロード
        SceneManager.LoadScene(SceneManager.GetActiveScene().name);
    }
}

シングルトンにして、既にインスタンスがある場合は削除されるようにしています。

private void Awake()
{
    // インスタンスが既にある場合
    if (instance != null)
    {                      
        // 新規作成されたものは削除
        Destroy(gameObject);
        Debug.Log("削除されました");
    }

また、空のゲームオブジェクトを新規作成して、AddComponentでこのスクリプトを付けた場合など、子オブジェクトがテキストや画像を持たないときも削除されます。

// 子のテキストを取得
text = GetComponentInChildren<Text>();

// テキストが無い時
if (text == null)
{
    // 削除
    Destroy(gameObject);
    Debug.Log("削除されました");
    return;
}

後は、Invokeメソッドを使って、数秒おきにテキストや画像の表示、シーンの再読み込みをします。

インスタンス化は他のスクリプトで行います。キー入力して以降、毎フレーム、インスタンスの取得とインスタンス化を繰り返すようにしてみました。

using UnityEngine;

public class GameScript5 : MonoBehaviour
{
    [SerializeField] GameOver gameOverCanvas;
    bool gameOver;

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

    // Update is called once per frame
    void Update()
    {
        if(Input.GetKeyDown(KeyCode.E))
        {
            gameOver = true;
        }

        if(gameOver)
        {
            GameOver go = GameOver.GetInstance();
            Instantiate(gameOverCanvas.gameObject);

            // GameObject obj = new GameObject();
            // obj.AddComponent<GameOver>();

            //new GameOver();
        }
    }
}

Canvasをプレハブ化してこのスクリプトにアタッチします。

これで簡単に、シーンの再読み込みと、その直前のテキストや画像の表示などを行うオブジェクトが作れました。

一度インスタンス化されると、それ以降はすぐに削除されます。

また、テキストや画像を含まないときも削除されます。

GameObject obj = new GameObject();
obj.AddComponent();

MonoBehaviourを継承しているので、newキーワードでのインスタンス化は禁止されています。

コメントを残す

メールアドレスが公開されることはありません。