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

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

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

シーンごとに別の動作をする

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

しかし、セーブ・ロード機能のようにSceneAでセーブボタンを押すと、SceneBに遷移してセーブをする。SceneAでロードボタンを押すと、SceneBに遷移して、ロードをする。つまり、2つのボタンともに同じシーンに切り替えるが、それぞれ動作が異なります。

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

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

シーン切り替え

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

そもそも、ゲームを開発する際に、シーン切り替えはゲーム開始シーン(タイトル画面)ゲームプレイシーンそれからゲームオーバーシーンの最低でも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」のボタンを押すと数字が減る

今回の動作はスクリプトを2つ使用します。

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--;
        }
    }
}

思い通りのゲームが作れない

Unityでゲーム開発しているけど完成しない。
技術的な壁や知識不足が原因で、思い描いたゲームを実現するのは難しいです。

しかし、Udemyは動画で実践的なゲーム開発を解説していて、
購入した講座は再生・停止・スキップなどが可能なオンデマンド形式なので、
専門的な内容を自分のペースで学習できます。

Udemyの特徴
  • プロのエンジニアによる講習が受けられる
  • 自分のペースで学習を進められる
  • オンデマンド形式だから何度でも視聴可能
  • 不満足なコースは視聴していても返金可能返金ポリシー

Unityの機能を網羅したいや作りたいゲームがある人はUdemy学習を取り入れましょう。
数多くある講座の中から特におすすめな講座を3つ紹介します。

Unityのはじめの一歩としておすすめ。開発例に物理挙動やアニメーションを使用しているので、今後の開発が円滑になる。

トランプを題材にした講座。カードゲームやボードゲーム開発に応用可能

UnityエンジンのインストールやC#の文法に加えて、App StoreとGoogle Playにゲームをリリース方法を解説。

容量不足を解消

Unityのプロジェクトは1.5GB~3.5GBと大きく、クリエイターはHDD・SSD増設が必要です。

価格耐久性静音性読み書きサイズ
HDD
SSD

注目点は、HDDは安価だけど壊れやすい。SSDは丈夫だけど高価。
したがって、データの持ち運びをしない場合はHDD、持ち運びする場合はSSDがおすすめです。

  • 据え置きHDD
  • 外付けSDD
  • 内蔵SSD

ぜひ、あなたのクリエイティブな作業環境に兼ね備えたストレージをお役立てください。

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でプラスかマイナスかを表示します。
「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

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をコピーしました