【Unity】複数のUIボタンでシーン切り替え、別の処理をする

当サイトで紹介する商品・サービス等の外部リンクは、アフィリエイト広告を含む場合があります。
スポンサーリンク
本記事を読むと以下の実行ができます

SceneAでボタン1(plus)、2(minus)があり、plusを押すとSceneBに移動して加算する。minusを押すと移動して、減算する。

複数シーンをボタン操作の実装

UnityのUIボタンを使って、シーン遷移する方法は理解できている。

例えばSceneAでセーブボタンを押すと、SceneBに遷移してセーブをする。
SceneAでロードボタンを押すと、SceneBに遷移してロードをする。

セーブとロード機能の追加を紹介しています。

2つのボタンともに同じシーンに切り替えるが、それぞれ動作が異なる機能を実装します。

本記事では、このような複数のボタンを押していずれも同じ画面に遷移して、
別々の処理を実行する方法を紹介します。

本記事は次の人におすすめ
  • Unityでシーン切り替えのやり方を知りたい。
  • 複数ボタンで同じシーンに切り替えるが、それぞれ動作が異なるプログラムを作りたい。
スポンサーリンク

シーン切り替え

UnityでSceneの切り替え

初めにシーン切り替えについて紹介します。

そもそもゲームを開発する際に、シーン切り替えはゲーム開始シーン(タイトル画面)ゲームプレイシーンそれからゲームオーバーシーンの最低でも3つが必要になります。

シーン切り替えに必要なコードは、次の通りになります。

using UnityEngine.SceneManagement; //シーン切り替えに必要な名前空間

SceneManager.LoadScene("シーン名");

シーン切り替えには「using UnityEngine.SceneManagement;」の名前空間が必要です。
そして、「SceneManager.LoadScene(“シーン名”);」にシーン名を入力してシーン遷移をします。

ここではUIボタンを押して「SceneA」・「SceneB」のシーン切り替える汎用的な動作を実装します。

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;//追加
using UnityEngine.SceneManagement;//シーン切り替えに必要

public class SceneMove : MonoBehaviour
{
    public Button SceneA;
    public Button SceneB;

    public void MoveA()
    {
        SceneManager.LoadScene("SceneA");
    }

    public void MoveB()
    {
        SceneManager.LoadScene("SceneB");
    }
}

UIボタンを使用するので、「using UnityEngine.UI;」を追加します。
また、メソッド「MoveA」・「MoveB」の定義をして、シーン切り替えをします。

スクリプト「SceneMove」をHierarchyウインドウの項目にアタッチして、ボタンを適用します。

さらに、ボタン「SceneA」にはMoveB。
ボタン「SceneB」にはMoveAをInspectorウインドウのOn Click()に紐づけて下さい。

実際の動作はこちらになります。

UIボタンでシーンを切り替える

2つのボタンはともに1つのシーンに切り替え、別の動作(足し算・引き算)

先ほどは、ボタンを使ってシーン移動を確認しました。
ここからは、本記事の最終目標の動作を作成していきます。

最終目標

2つのボタンを「SceneA」に用意し、どちらも「SceneB」に切り替える。
「SceneA」の片方のボタンを押して、「SceneB」のボタンを押すと数字が加わる
「SceneA」のもう一方のボタンを押して、「SceneB」のボタンを押すと数字が減る

1.1.ソースコード

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;//UIボタンとUIテキストで必要
using UnityEngine.SceneManagement;//シーン切り替えに必要

public class SceneMove : MonoBehaviour
{
    static int i;
    static bool flag;
    public Text num;
    public Text Situ;
    public Button Plusbtn;
    public Button Minusbtn;
    public Button Counter;

    void Update()
    {
        num.text= i.ToString();
        if (SceneManager.GetActiveScene().name == "SceneB" && flag == true)
        {
            Situ.text = "Plus";
        }
        else if (SceneManager.GetActiveScene().name == "SceneB" && flag == false)
        {
            Situ.text = "Minus";
        }
    }

    public void MoveA()
    {
        SceneManager.LoadScene("SceneA");
    }

    public void Plus()
    {
        SceneManager.LoadScene("SceneB");
        flag = true;
    }

    public void Minus()
    {
        SceneManager.LoadScene("SceneB");
        flag = false;
    }

    public void Count()
    {
        if(flag == true)
        {
            i++;
        }
        else if(flag == false)
        {
            i--;
        }
    }
}

UdemyでUnityを学習

Udemyは、オンデマンド式の学習講座です。
趣味から実務まで使えるおすすめの講座を紹介します。

ビックセール開催中(10月25日まで)
対象のコースが1800円から(最大95%OFF)

多彩な講座から自分に合った講座を探そう!

最大94%OFF

終了まで

時間

1.2.解説

初めに、名前空間に、UIボタンとUIテキストを作るための「using UnityEngine.UI;」・シーン切り替えするための「using UnityEngine.SceneManagement;」を追加します。
これらを入力を忘れると使用できないので、注意してください。

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;//UIボタンとUIテキストで必要
using UnityEngine.SceneManagement;//シーン切り替えに必要

続いて、変数を定義します。

「i」は、静的(static)なint型変数で、後にこの変数を文字列に変換します。
「flag」は、TrueFalseの真偽値を代入する静的(static)なbool型変数です。int型で変数を0,1にして真偽を分ける方法でも代用可能です。
※変数を静的(static)にすることで、シーン切り替えをしてもその値をそのまま引き継ぐことができます。
「num」・「Situ」はUIテキストで、「num」はSceneAで数字を表示します。「Situ」はSceneBでプラスかマイナスかを表示します。

Unityでのテキストはtextmeshproを使うことが推奨されています。


「Plusbtn」・「Minusbtn」・「Counter」「Back」はUIボタンで、「Plusbtn」・「Minusbtn」はそれぞれ数字の加算・減算をします。「Counter」は押すと、数字を1ずつ加減をします。「Back」は、SceneBからSceneAにシーン切り替えをします。

文字と数字をリアルタイムで切り替える方法を紹介しています。
static int i;
static bool flag;
public Text num;
public Text Situ;
public Button Plusbtn;
public Button Minusbtn;
public Button Counter;
public Button Back;

ここで、ボタンそれぞれに要素を追加します。

関数Plus()・Minus()はSceneBに遷移して、Plus()はbool型変数「flag」をTrue(真)にして、Minus()はFalse(偽)にします。各関数はそれぞれ、UIボタン「Plusbtn」・「Minusbtn」に紐づけます。
関数Count()はbool型変数「flag」がTrue(真)つまり、SceneAで「Plusbtn」が押されたときに加算して、「flag」がFalse(偽)つまり、SceneAで「Minusbtn」が押されたときに減算します。関数Count()はUIボタン「Counter」に紐づけます。
関数MoveA()はSceneBからSceneAに遷移します。

    public void Plus()
    {
        SceneManager.LoadScene("SceneB");
        flag = true;
    }

    public void Minus()
    {
        SceneManager.LoadScene("SceneB");
        flag = false;
    }

    public void Count()
    {
        if(flag == true)
        {
            i++;
        }
        else if(flag == false)
        {
            i--;
        }
    }

    public void MoveA()
    {
        SceneManager.LoadScene("SceneA");
    }

最後に、Update()内にて、UIテキスト「num」に変換したint型変数「i」を表示します。

また、SceneBが加算なのか、減算なのか一目で分かるようにします。
次のコードはif文と組み合わせることで、そのシーンのみでしか処理されないようになります。

SceneManager.GetActiveScene().name == "シーン名"

SceneBかつbool型変数「flag」がTrue(真)であるとき、UIテキスト「Situ」は”Plus”と表示されます。
SceneBかつbool型変数「flag」がfalse(偽)であるとき、UIテキスト「Situ」は”Minus”と表示されます。

    void Update()
    {
        num.text= i.ToString();
        if (SceneManager.GetActiveScene().name == "SceneB" && flag == true)
        {
            Situ.text = "Plus";
        }
        else if (SceneManager.GetActiveScene().name == "SceneB" && flag == false)
        {
            Situ.text = "Minus";
        }
    }

以上までが1つ目のスクリプトになります。Hierarchyウインドウの項目にアタッチしてください。
さらに、InspectorウインドウのOn Click()に紐づけて下さい。

「1.1.ソースコード」での不具合を改善

上記のスクリプトのみでプログラムを稼働するとシーンを切り替えても、前のUIが残ってしまいます。

そこで、本スクリプトは「DontDestroyOnLoad」を使用して、
シーンを切り替えてもUIと変数を保持しつつ適切な表示を実装します。

DontDestroyOnLoad

シーン切り替えてもUIと変数を保持する

DontDestroyOnLoad」はオブジェクトがシーンの切り替え(ロード)時に破棄されないようにするために使用されます。

通常新しいシーンがロードされると、現在のシーンに存在するすべてのオブジェクトは破棄されますが、
DontDestroyOnLoadを使用すると、特定のオブジェクトを破棄せずに次のシーンに持ち越すことができます。

以下にDontDestroyOnLoadの簡単なコードを示します。

using UnityEngine;

public class MyScript : MonoBehaviour
{
    private void Start()
    {
        // このオブジェクトをシーンの切り替え時に破棄しないように設定する
        DontDestroyOnLoad(this.gameObject);
    }
}

このスクリプトは、Startメソッドで現在のゲームオブジェクトを取得し、
DontDestroyOnLoadメソッドを呼び出しています。

これにより、現在のゲームオブジェクトはシーンの切り替え時に破棄されず、
次のシーンでも存在し続けます。

2.1.ソースコード

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

public class DontDestroyOnLoad: MonoBehaviour
{
    public GameObject Obj;

    void Start()
    {
        DontDestroyOnLoad(Obj);
    }

    void Update()
    {
        if (SceneManager.GetActiveScene().name == "SceneA")
        {
            Obj.gameObject.SetActive(false);
        }
        if (SceneManager.GetActiveScene().name == "SceneB")
        {
            Obj.gameObject.SetActive(true);
        }
    }

    static public  DontDestroyOnLoad instance = null;

    void Awake()
    {
        if (instance == null)
        {
            instance = this;
            DontDestroyOnLoad(gameObject);
        }
        else
        {
            Destroy(gameObject);
        }
    }
}

2.2.解説

初めに、名前空間へ同様にシーン切り替えするための
「using UnityEngine.SceneManagement;」を追加します。

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

続いて、変数を定義します。

ゲームオブジェクト「Obj」を作り、関数Start()に「DontDestroyOnLoad(Obj)」として、
ゲームオブジェクト「Obj」をシーン遷移で消えないようにします。

public GameObject Obj;

void Start()
{
    DontDestroyOnLoad(Obj);
}

ここで、インスタンスを作ります。

「instance = null」として関数Awake()にて、
「instance == null」の時は「gameObject」は消さず、それ以外は消します。

    static public DontDestroyOnLoad instance = null;

    void Awake()
    {
        if (instance == null)
        {
            instance = this;
            DontDestroyOnLoad(gameObject);
        }
        else
        {
            Destroy(gameObject);
        }
    }

最後に関数Update()にて、
ゲームオブジェクト「Obj」をSceneAの時は非表示、SceneBの時は表示にします。

    void Update()
    {
        if (SceneManager.GetActiveScene().name == "SceneA")
        {
            Obj.gameObject.SetActive(false);
        }
        if (SceneManager.GetActiveScene().name == "SceneB")
        {
            Obj.gameObject.SetActive(true);
        }
    }

以上までが2つ目のスクリプトになります。

Hierarchyウインドウの項目に新しいGameObjectを作成してアタッチしてください。
ゲームオブジェクト「Obj」にUIをアタッチすると、適応されます。

まとめ

今回は、複数のUIボタンで1つのシーンに切り替えて、それぞれ別の動作を作りました。
シーンを切り替えても変数を保持するためには静的な(static)変数を使う必要があります。

また、UIテキスト・UIボタンをシーン遷移しても保持するには、
DontDestroyOnLoadを使う必要があります。

この記事を書いた人

プロフィール

アリッシア

                 

大学4年間で何か胸を張れるスキルを身に着けたくて当サイト運営を始めました。
現在、大学院に進学するか就職するか迷いながら勉強しています。
詳しいプロフィールはこちら

Contact icon

contact

X icon

X

Instagram icon

Instagram

Note icon

Note

スポンサーリンク
Unity
フォローする
タイトルとURLをコピーしました