Unity3d中C#单例模式实现
为什么要使⽤单例模式
在我们的整个游戏⽣命周期当中,有很多对象从始⾄终有且只有⼀个。这个唯⼀的实例只需要⽣成⼀次,并且直到游戏结束才需要销毁。 单例模式⼀般应⽤于管理器类,或者是⼀些需要持久化存在的对象。
Unity3d中单例模式的实现⽅式
(⼀)c#当中实现单例模式的⽅法
因为单例本⾝的写法不是重点,所以这⾥就略过,直接上代码。
以下代码来⾃于MSDN。
[csharp]
1. public sealed class Singleton
2. {
3. private static volatile Singleton instance;
4. private static object syncRoot = new Object();
5. public static Singleton Instance
6. {
7. get
8. {
9. if (instance == null)
10. {
11. lock (syncRoot)
12. {
13. if (instance == null)
14. instance = new Singleton();
15. }
16. }
17. return instance;
18. }
19. }
20. }
public sealed class Singleton
{
private static volatile Singleton instance;
private static object syncRoot = new Object();
public static Singleton Instance
{
get
{
if (instance == null)
{
lock (syncRoot)
{
if (instance == null)
instance = new Singleton();
}
}
return instance;
}
}
}
以上代码是⽐较完整版本的c#单例。在unity当中,如果不需要使⽤到monobeheviour的话,可以使⽤这种⽅式来构建单例。
(⼆)如果是MonoBeheviour呢?
MonoBeheviour和⼀般的类有⼏个重要区别,体现在单例模式上有两点。
第⼀,MonoBehaviour不能使⽤构造函数进⾏实例化,只能挂载在GameObject上。
第⼆,当切换场景时,当前场景中的GameObject都会被销毁(LoadLevel带有additional参数时除外),这种情况下,我们的单例对象也会被销毁。
为了使之不被销毁,我们需要进⾏DontDestroyOnLoad的处理。同时,为了保持场景当中只有⼀个实例,我们要对当前场景中的单例进⾏判断,如果存在其他的实例,则应该将其全部删除。
因此,构建单例的⽅式会变成这样。
[csharp]
1. public sealed class SingletonMoBehaviour: MonoBehaviour
2. {
3. private static volatile SingletonBehaviour instance;
4. private static object syncRoot = new Object();
5. public static SingletonBehaviour Instance
6. {
7. get
8. {
9. if (instance == null)
10. {
11. lock (syncRoot)
12. {
13. if (instance == null) {
14. SingletonBehaviour[] instances = FindObjectsOfType<SingletonBehaviour>();
15. if (instances != null){
16. for (var i = 0; i < instances.Length; i++) {
17. Destroy(instances[i].gameObject);
18. }
19. }
20. GameObject go = new GameObject(“_SingletonBehaviour”);
21. instance = go.AddComponent<SingletonBehaviour>();
22. DontDestroyOnLoad(go);
23. }
24. }
25. }
26. return instance;
27. }
28. }
29. }
public sealed class SingletonMoBehaviour: MonoBehaviour
{
private static volatile SingletonBehaviour instance;
private static object syncRoot = new Object();
public static SingletonBehaviour Instance
{
get
{
if (instance == null)
{
lock (syncRoot)
{
if (instance == null) {
SingletonBehaviour[] instances = FindObjectsOfType<SingletonBehaviour>();
if (instances != null){
for (var i = 0; i < instances.Length; i++) {
Destroy(instances[i].gameObject);
}
}
GameObject go = new GameObject("_SingletonBehaviour");
instance = go.AddComponent<SingletonBehaviour>();
DontDestroyOnLoad(go);
}
}
}
return instance;
}
}
}
这种⽅式并⾮完美。其缺陷⾄少有:
* 如果有许多的单例类,会需要复制粘贴这些代码
* 有些时候我们也许会希望使⽤当前存在的所有实例,⽽不是删除全部新建⼀个实例。(这个未必是缺陷,只是设计的不同)
在本⽂后⾯将会附上这种单例模式的代码以及。
(三)使⽤模板类实现单例
为了避免重复代码,我们可以使⽤模板类的⽅式来⽣成单例。⾮MonoBehaviour的实现⽅式这⾥就不赘述,只说monoBehaviour的。 代码
单例模式的几种实现方式[csharp]
1. public sealed class SingletonTemplate<T> : MonoBehaviour where T : MonoBehaviour
2. {
3. private static volatile T instance;
4. private static object syncRoot = new Object();
5. public static T Instance
6. {
7. get
8. {
9. if (instance == null)
10. {
11. lock (syncRoot)
12. {
13. if (instance == null)
14. {
15. T[] instances = FindObjectsOfType<T>();
16. if (instances != null)
17. {
18. for (var i = 0; i < instances.Length; i++)
19. {
20. Destroy(instances[i].gameObject);
21. }
22. }
23. GameObject go = new GameObject();
24. go.name = typeof(T).Name;
25. instance = go.AddComponent<T>();
26. DontDestroyOnLoad(go);
27. }
28. }
29. }
30. return instance;
31. }
32. }
33. }
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论