@@ -8,28 +8,41 @@ namespace HoloToolkit.Unity
88 /// <summary>
99 /// Singleton behaviour class, used for components that should only have one instance
1010 /// </summary>
11- /// <typeparam name="T"></typeparam>
11+ /// <typeparam name="T">The Singleton Type </typeparam>
1212 public class Singleton < T > : MonoBehaviour where T : Singleton < T >
1313 {
1414 private static T instance ;
15+
16+ /// <summary>
17+ /// Returns the Singleton instance of the classes type.
18+ /// If no instance is found, then we search for an instance
19+ /// in the scene.
20+ /// If more than one instance is found, we throw an error and
21+ /// no instance is returned.
22+ /// </summary>
1523 public static T Instance
1624 {
1725 get
1826 {
19- if ( instance == null )
27+ if ( instance == null && searchForInstance )
2028 {
21- Debug . LogErrorFormat (
22- "The {0} singleton instance is being accessed while it's null. Make sure it's included in"
23- + " the scene, and your initialization/deinitialization sequence is compatible with"
24- + " singletons." ,
25- typeof ( T ) . Name
26- ) ;
29+ searchForInstance = false ;
30+ T [ ] objects = FindObjectsOfType < T > ( ) ;
31+ if ( objects . Length == 1 )
32+ {
33+ instance = objects [ 0 ] ;
34+ }
35+ else if ( objects . Length > 1 )
36+ {
37+ Debug . LogErrorFormat ( "Expected exactly 1 {0} but found {1}." , typeof ( T ) . ToString ( ) , objects . Length ) ;
38+ }
2739 }
28-
2940 return instance ;
3041 }
3142 }
3243
44+ private static bool searchForInstance = true ;
45+
3346 public static void AssertIsInitialized ( )
3447 {
3548 Debug . Assert ( IsInitialized , string . Format ( "The {0} singleton has not been initialized." , typeof ( T ) . Name ) ) ;
@@ -47,25 +60,44 @@ public static bool IsInitialized
4760 }
4861
4962 /// <summary>
50- /// Base awake method that sets the singleton's unique instance.
63+ /// Base Awake method that sets the Singleton's unique instance.
64+ /// Called by Unity when initializing a MonoBehaviour.
65+ /// Scripts that extend Singleton should be sure to call base.Awake() to ensure the
66+ /// static Instance reference is properly created.
5167 /// </summary>
5268 protected virtual void Awake ( )
5369 {
54- if ( instance != null )
70+ if ( IsInitialized && instance != this )
5571 {
56- Debug . LogErrorFormat ( "Trying to instantiate a second instance of singleton class {0}" , GetType ( ) . Name ) ;
72+ if ( Application . isEditor )
73+ {
74+ DestroyImmediate ( this ) ;
75+ }
76+ else
77+ {
78+ Destroy ( this ) ;
79+ }
80+
81+ Debug . LogErrorFormat ( "Trying to instantiate a second instance of singleton class {0}. Additional Instance was destroyed" , GetType ( ) . Name ) ;
5782 }
58- else
83+ else if ( ! IsInitialized )
5984 {
6085 instance = ( T ) this ;
6186 }
6287 }
6388
89+ /// <summary>
90+ /// Base OnDestroy method that destroys the Singleton's unique instance.
91+ /// Called by Unity when destroying a MonoBehaviour. Scripts that extend
92+ /// Singleton should be sure to call base.OnDestroy() to ensure the
93+ /// underlying static Instance reference is properly cleaned up.
94+ /// </summary>
6495 protected virtual void OnDestroy ( )
6596 {
6697 if ( instance == this )
6798 {
6899 instance = null ;
100+ searchForInstance = true ;
69101 }
70102 }
71103 }
0 commit comments