LoginSignup
16
16

More than 5 years have passed since last update.

MonoBehaviourを継承したシングルトンの実装

Last updated at Posted at 2016-01-17

ベースとなるシングルトンクラス

SingletonMonoBehaviour.cs
using UnityEngine;
using System;
using System.Collections;
using System.Collections.Generic;

/// <summary>
/// MonoBehaviourを継承したシングルトン
/// </summary>
public class SingletonMonoBehaviour<T> : MonoBehaviour where T : MonoBehaviour {
    /// <summary>
    /// インスタンス
    /// </summary>
    private static volatile T instance;

    /// <summary>
    /// 同期オブジェクト
    /// </summary>
    private static object syncObj = new object (); 

    /// <summary>
    /// インスタンスのgetter/setter
    /// </summary>
    public static T Instance {
        get {
            // アプリ終了時に,再度インスタンスの呼び出しがある場合に,オブジェクトを生成することを防ぐ
            if(applicationIsQuitting) {
                return null;
            }
            // インスタンスがない場合に探す
            if(instance == null) {
                instance = FindObjectOfType<T>() as T;

                // 複数のインスタンスがあった場合
                if ( FindObjectsOfType<T>().Length > 1 ) {
                    return instance;
                }

                // Findで見つからなかった場合、新しくオブジェクトを生成
                if (instance == null) {
                    // 同時にインスタンス生成を呼ばないためにlockする
                    lock (syncObj) { 
                        GameObject singleton = new GameObject();
                        // シングルトンオブジェクトだと分かりやすいように名前を設定
                        singleton.name = typeof(T).ToString() + " (singleton)";
                        instance = singleton.AddComponent<T>();
                        // シーン変更時に破棄させない
                        DontDestroyOnLoad(singleton);
                    }
                }

            }
            return instance;
        }
        // インスタンスをnull化するときに使うのでprivateに
        private set {
            instance = value;
        }
    }

    /// <summary>
    /// アプリが終了しているかどうか
    /// </summary>
    static bool applicationIsQuitting = false;

    void OnApplicationQuit() {
        applicationIsQuitting = true;
    }

    void OnDestroy () {
        Instance = null;
    }

    // コンストラクタをprotectedにすることでインスタンスを生成出来なくする
    protected SingletonMonoBehaviour () {}
}

このシングルトンを継承するクラスはこんな感じにする

scoreManager.cs
using UnityEngine;
using System.Collections;
public class ScoreManager : SingletonMonoBehaviour<ScoreManager> {
    public int score;
    public void AddScore(int point) {
        score += point;
    }
}

使うときはこんな感じ

Test.cs
using UnityEngine;
using System.Collections;

public class Test : MonoBehaviour {
    void Start () {
        Debug.Log(ScoreManager.Instance.score);
        ScoreManager.Instance.AddScore(100);
        Debug.Log(ScoreManager.Instance.score);
    }
}
16
16
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
16
16