-
Notifications
You must be signed in to change notification settings - Fork 0
/
AutoInstanceMonoBehaviour.cs
87 lines (75 loc) · 1.62 KB
/
AutoInstanceMonoBehaviour.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
using UnityEngine;
namespace Custom.Singleton
{
///
/// Provides static access to MonoBehaviour of type <typeparam name="T">
/// Creates persistent game object if none is present
///
/// Use <see cref="destroyed"> to protect against unwanted instantiations
/// Like when accessing <see cref="instance"> inside OnDisable method
///
/// Please note that auto created instances will be marked DontDestroyOnLoad
/// Thus consequently be placed into the very same named scene
///
/// Intended to be used like
/// public class ClassName : AutoInstanceMonoBehaviour<ClassName> { ... }
///
public abstract class AutoInstanceMonoBehaviour<T> : MonoBehaviour
where T : AutoInstanceMonoBehaviour<T>
{
//
// API
//
public static bool destroyed { get; private set; }
private static T _instance;
public static T instance
{
get
{
if (_instance)
{
return _instance;
}
_instance = GetAutoMonoBehaviour(dontDestroyOnLoad: true);
destroyed = false;
return _instance;
}
}
//
// Callbacks from Unity
//
protected void Awake()
{
if (!_instance || destroyed)
{
_instance = (T)this;
destroyed = false;
}
}
protected void OnDestroy()
{
if (ReferenceEquals(this, _instance))
{
destroyed = true;
}
}
//
//
//
public static T GetAutoMonoBehaviour(bool dontDestroyOnLoad = false)
{
var result = FindObjectOfType<T>();
if (!result)
{
result = new GameObject(
$"Auto instance: {typeof(T).Name}"
).AddComponent<T>();
}
if (dontDestroyOnLoad)
{
DontDestroyOnLoad(result.gameObject);
}
return result;
}
}
}