MySceneControllerを作ってみた（自分用データの受け渡し方法まとめ）

# 前提
シーン遷移をするとデータが失われてしまう問題がある
データの受け渡し方法
シーン遷移をせずに1シーンで演出ができないか考えました


・static変数
C# 
```
using UnityEngine;

public class Sample1 : MonoBehaviour
{
    public static int sharedData;
}

```
問題点
Sample1.cs - Staticな変数に保持しておく
依存関係の隠蔽が難しい: 静的な変数を利用すると、クラス間の依存関係が隠蔽されず、コードが複雑になりやすい。

・シングルトン
C# 
```
using UnityEngine;

public class Sample2 : MonoBehaviour
{
    public static Sample2 Instance;

    public int sharedData;

    private void Awake()
    {
        if (Instance == null)
        {
            Instance = this;
        }
        else
        {
            Destroy(gameObject);
        }
    }
}

```
問題点
Sample2.cs - シングルトンを利用
グローバル状態への依存: シングルトンパターンはグローバルな状態を導入しやすく、コードの理解とテストが難しくなる可能性がある。
ライフサイクル管理の複雑さ: シングルトンはライフサイクルの管理が複雑になりがちで、適切な初期化や破棄が保証されない場合がある。

・(非推奨)DontDestroyOnLoad
C# 
```
using UnityEngine;

public class Sample3 : MonoBehaviour
{
    public int sharedData;

    private void Awake()
    {
        DontDestroyOnLoad(gameObject);
    }
}

```
問題点
Sample3.cs - (非推奨) DontDestroyOnLoadを利用
メモリリークの可能性: DontDestroyOnLoad を使用すると、不要なオブジェクトがメモリ内に残りやすくなり、メモリリークの原因となる可能性がある。
オブジェクトの管理が困難: DontDestroyOnLoad を使用すると、オブジェクトの管理が難しくなり、意図しない挙動が生じる可能性がある。

・マルチシーン
C# 
```
using UnityEngine;

public class Sample4 : MonoBehaviour
{
    public static int sharedData;
}

```
問題点
Sample4.cs - マルチシーンを利用
複雑なデータ共有: マルチシーンを利用する場合、データの共有と同期が複雑になりがちで、コードの複雑性が増す可能性がある。

・ScriptableObject
C# 
```
using UnityEngine;

[CreateAssetMenu(fileName = "NewData", menuName = "Data")]
public class Sample5 : ScriptableObject
{
    public int sharedData;
}

```
問題点
Sample5.cs - ScriptableObjectを利用
外部アセットへの依存: ScriptableObjectを使う場合、外部アセットに依存するため、プロジェクト内でコードと設定が分散しやすくなる。

・ストレージに値を保存
C# 
```
using UnityEngine;

public class Sample6 : MonoBehaviour
{
    private const string Key = "SharedData";

    public void SaveData(int data)
    {
        PlayerPrefs.SetInt(Key, data);
        PlayerPrefs.Save();
    }

    public int LoadData()
    {
        return PlayerPrefs.GetInt(Key);
    }
}

```
問題点
Sample6.cs - ストレージに値を保存
データの永続化とセキュリティ: ストレージにデータを保存する場合、データの永続化とセキュリティ上の懸念があり、機密性の高いデータの場合は注意が必要です。また、プラットフォームによっては保存できる容量に制限があります。

##### 最後に自分の解決方法?.(演出までは未完成)を載せておきます。
##### まず各シーンの分けて作ってある機能があることが前提です
##### 次にCreateEmptyで空のGameObjectを各シーンに作ります
##### 次に空のGameObjectの配下にシーン内のオブジェクトをすべて移動します
##### 次にマルチシーンを利用して全てのシーンの管理シーンのヒエラルキーに全てのGameObjectを 
##### Drag&Dropします
##### 次にヒエラルキーの各シーンを右クリック>UnloadSceneを選択します（間違ってシーンを消さないように）
##### 次に管理シーンに空のGameObjectを作成し以下のスクリプトをアタッチします
##### インスペクターでシーンの数に応じて配列を増やし、enumの値をDropDownから選びます
##### 最後にSetActive(true);したいシーン部品オブジェクトをセットすれば完成です
サンプルではSpaceキーを押すとGameObjectが連番でSetActiveされていきます
実質シーン遷移が実装できました
最終的にはおしゃれなフェードを1シーンで実現したいのでまた更新します


C# 
```
using UnityEngine;

public class SceneController : MonoBehaviour
{
    [System.Serializable]
    public class SceneCtrl
    {
        public enum SCENETYPE
        {
            TITLE,
            PROLOG,
            GAME,
            END_1,
            END_2,
            SAVE,
            SETTING,
        }

        public SCENETYPE sceneType = SCENETYPE.TITLE;
    }

    [SerializeField] SceneCtrl[] scenes;

    void Start()
    {
        // 初期のシーンを設定
        SwitchScene(SceneCtrl.SCENETYPE.TITLE);
    }

    void Update()
    {
        // シーンの切り替えなど、必要な処理をUpdate内に記述
        if (Input.GetKeyDown(KeyCode.Space))
        {
            // 例えばスペースキーを押したら次のシーンに切り替える
            SwitchToNextScene();
        }
    }

    void SwitchToNextScene()
    {
        // 現在のシーンを取得
        SceneCtrl currentScene = GetCurrentScene();

        // 現在のシーンの次のシーンを取得
        int currentIndex = System.Array.IndexOf(scenes, currentScene);
        int nextIndex = (currentIndex + 1) % scenes.Length;
        SceneCtrl nextScene = scenes[nextIndex];

        // 次のシーンに切り替え
        SwitchScene(nextScene.sceneType);
    }

    void SwitchScene(SceneCtrl.SCENETYPE sceneType)
    {
        // すべてのシーンを非アクティブにする
        foreach (SceneCtrl scene in scenes)
        {
            SetSceneActive(scene.sceneType, false);
        }

        // 指定されたシーンをアクティブにする
        SetSceneActive(sceneType, true);
    }

    void SetSceneActive(SceneCtrl.SCENETYPE sceneType, bool isActive)
    {
        switch (sceneType)
        {
            case SceneCtrl.SCENETYPE.TITLE:
                title_Object.SetActive(isActive);
                break;
            case SceneCtrl.SCENETYPE.PROLOG:
                prolog_Object.SetActive(isActive);
                break;
            case SceneCtrl.SCENETYPE.GAME:
                game_Object.SetActive(isActive);
                break;
            case SceneCtrl.SCENETYPE.END_1:
                end_1_Object.SetActive(isActive);
                break;
            case SceneCtrl.SCENETYPE.END_2:
                end_2_Object.SetActive(isActive);
                break;
            case SceneCtrl.SCENETYPE.SAVE:
                save_Object.SetActive(isActive);
                break;
            case SceneCtrl.SCENETYPE.SETTING:
                settingObject.SetActive(isActive);
                break;
        }
    }

    SceneCtrl GetCurrentScene()
    {
        // アクティブなシーンを検索して返す
        foreach (SceneCtrl scene in scenes)
        {
            GameObject sceneObject = GetSceneObject(scene.sceneType);
            if (sceneObject.activeSelf)
            {
                return scene;
            }
        }
        return null;
    }

    GameObject GetSceneObject(SceneCtrl.SCENETYPE sceneType)
    {
        switch (sceneType)
        {
            case SceneCtrl.SCENETYPE.TITLE:
                return title_Object;
            case SceneCtrl.SCENETYPE.PROLOG:
                return prolog_Object;
            case SceneCtrl.SCENETYPE.GAME:
                return game_Object;
            case SceneCtrl.SCENETYPE.END_1:
                return end_1_Object;
            case SceneCtrl.SCENETYPE.END_2:
                return end_2_Object;
            case SceneCtrl.SCENETYPE.SAVE:
                return save_Object;
            case SceneCtrl.SCENETYPE.SETTING:
                return settingObject;
            default:
                return null;
        }
    }
}

```