マルチシーン間のアクセスサンプル(その1)

ゲームを実行するMainSceneとUIをコントロールするUISceneを作ります
MainSceneからUISceneのオブジェクトへアクセスします

MainScene

GameController

テキストの表示対応

using UnityEngine;

public class GameController : MonoBehaviour
{
    private void Start()
    {
        // シーンがロードされた後、UIManagerにアクセスしテキストを更新します
        if (UIManager.Instance != null)
        {
            // UIManagerを通じてテキストを更新します
            UIManager.Instance.UpdateText("Displayed from the game controller's side!");
        }
    }
}

ボタンのクリック対応

using UnityEngine;

public class GameController : MonoBehaviour
{
    private void Start()
    {
        // シーンがロードされた後、UIManagerにアクセスしテキストを更新します
        if (UIManager.Instance != null)
        {
            // ボタンクリック時のリスナーを追加します
            UIManager.Instance.button.onClick.AddListener(OnButtonClick);
        }
    }

    private void OnButtonClick()
    {
        // ボタンがクリックされたときにログにメッセージを出力します
        Debug.Log("ボタンがクリックされました(メインシーン側メソッド)"); // コンソールにログを出力
    }
}

両方対応

using UnityEngine;

public class GameController : MonoBehaviour
{
    private void Start()
    {
        // シーンがロードされた後、UIManagerにアクセスしテキストを更新します
        if (UIManager.Instance != null)
        {
            // UIManagerを通じてテキストを更新します
            UIManager.Instance.UpdateText("Displayed from the game controller's side!");
            // ボタンクリック時のリスナーを追加します
            UIManager.Instance.button.onClick.AddListener(OnButtonClick);
        }
    }

    private void OnButtonClick()
    {
        // ボタンがクリックされたときにログにメッセージを出力します
         Debug.Log("ボタンがクリックされました(メインシーン側メソッド)"); // コンソールにログを出力
    }
}

UIScene

UIManager

テキストの表示対応

using UnityEngine;
using TMPro;

public class UIManager : MonoBehaviour
{
    public static UIManager Instance; // シングルトンインスタンスの参照

    [SerializeField]
    private TextMeshProUGUI textDisplay; // TextMeshPro UI コンポーネントの参照

    private void Awake()
    {
        // シングルトンパターンの確立
        if (Instance == null)
        {
            Instance = this; // このインスタンスをグローバルに設定
        }
        else
        {
            Destroy(gameObject); // 重複インスタンスがあれば削除
        }
    }

    // テキストを更新するメソッド
    public void UpdateText(string text)
    {
        textDisplay.text = text; // テキスト表示の更新
    }
}

ボタンのクリック対応

using UnityEngine;
using TMPro;
using UnityEngine.UI;

public class UIManager : MonoBehaviour
{
    public static UIManager Instance; // シングルトンインスタンスの参照

    public Button button; // UI ボタンの参照

    private void Awake()
    {
        // シングルトンパターンの確立
        if (Instance == null)
        {
            Instance = this; // このインスタンスをグローバルに設定
        }
        else
        {
            Destroy(gameObject); // 重複インスタンスがあれば削除
        }

        // ボタンのクリックイベントにメソッドを紐づける
        button.onClick.AddListener(OnButtonClicked);
    }

    // ボタンクリック時の処理
    private void OnButtonClicked()
    {
        Debug.Log("ボタンがクリックされました(UIシーン側メソッド)"); // コンソールにログを出力
    }
}

両対応

using UnityEngine;
using TMPro;
using UnityEngine.UI;

public class UIManager : MonoBehaviour
{
    public static UIManager Instance; // シングルトンインスタンスの参照

    [SerializeField]
    private TextMeshProUGUI textDisplay; // TextMeshPro UI コンポーネントの参照

    public Button button; // UI ボタンの参照

    private void Awake()
    {
        // シングルトンパターンの確立
        if (Instance == null)
        {
            Instance = this; // このインスタンスをグローバルに設定
        }
        else
        {
            Destroy(gameObject); // 重複インスタンスがあれば削除
        }

        // ボタンのクリックイベントにメソッドを紐づける
        button.onClick.AddListener(OnButtonClicked);
    }

    // テキストを更新するメソッド
    public void UpdateText(string text)
    {
        textDisplay.text = text; // テキスト表示の更新
    }

    // ボタンクリック時の処理
    private void OnButtonClicked()
    {
        Debug.Log("ボタンがクリックされました(UIシーン側メソッド)"); // コンソールにログを出力
    }
}

タイトルシーンなどからサンプル制作のマルチシーンをロードしたい時

LoadScene メソッドを使用してタイトルシーンからマルチシーン構成のゲームシーンに遷移する場合、以下のステップを踏んでコードを記述します。

  1. シーンの非同期読み込み: SceneManager.LoadSceneAsync を使用して、新しいシーンを非同期で読み込みます。これにより、シーンのロード中にゲームのフレームレートが低下することが防げます。
  2. UIシーンの追加: ゲームシーンをロードする際に、UI シーンも一緒にロードされるように SceneManager.LoadSceneAsyncLoadSceneMode.Additive を指定します。
  3. ロードの完了待ち: AsyncOperation オブジェクトを使用して、シーンのロードが完了するまで待ちます。完了したかどうかは、AsyncOperation.isDone プロパティで確認できます。
  4. イベントハンドラの設定: ロードが完了した際に実行したい処理がある場合、AsyncOperation.completed イベントにハンドラを追加します。

ここに具体的なコード例を示します。

using UnityEngine;
using UnityEngine.SceneManagement;

public class SceneLoader : MonoBehaviour
{
    void Start()
    {
        // タイトルシーンからゲームシーンへ遷移
        LoadGameScene();
    }

    void LoadGameScene()
    {
        // メインシーンを非同期でロード
        AsyncOperation gameSceneLoad = SceneManager.LoadSceneAsync("MainScene", LoadSceneMode.Single);
        
        // UIシーンを追加的にロード
        SceneManager.LoadSceneAsync("UIScene", LoadSceneMode.Additive);

        gameSceneLoad.completed += (AsyncOperation operation) =>
        {
            // シーンのロードが完了した後の処理をここに記述
            Debug.Log("メインシーンとUIシーンのロード");
        };
    }
}

このコードでは、ゲームのメインシーンとUIシーンが同時に非同期で読み込まれ、両方のシーンが完全にロードされた後にログが出力されます。この方法により、シームレスなシーン遷移と優れたユーザーエクスペリエンスを実現できます。

Unity

Posted by hidepon