Singleton : Implementation in Unity3d C#

F:http://www.unitygeek.com/unity_c_singleton/

Unity_Singleton

Objective :

Singleton is a very complex topic, In this, we try to understand basics and various implementation of Singleton in Unity3d using C#.

Intro:

Singleton is a basic Design Pattern. Classes implementing Singleton pattern will ensure that only one instance of the object ever exists at any one time. It is recommend using Singletons for things that do not need to be copied multiple times during a game.This is great for controller classes like GameManager or AudioController.

Implementation:

There are several ways of implementing Singleton in Unity, we will some of the implementation in this tutorial

  1. Simplest Implementation
?
01
02
03
04
05
06
07
08
09
10
11
public class SingletonController : MonoBehaviour {
public static SingletonController instance;
 
   private void Awake() {
    if (instance != null) {
      Destroy(gameObject);
    } else {
      Instance = this;
    }
  }
}

Above code is the simplest implementation of Singleton, but there are some issues which we have to address

  1. Singleton is not persistent across the Unity scenes.
  2. All the executable code must be attached to GameObject in the hierarchy.
  3. It is not recommended to call SingletonController.Instance in any Awake() method because, since we don’t know the order that Awake() will be executed through all scripts, we can end up with a Null Reference Exception.
  4. This code works only for SingletonController Class, but if you want another singleton controller eg. AudioController, we have to copy paste the same code to AudioController Class and do some minor changes to works, but this leads to boilerplate code .

 

Solution For First Issue:

This one is easy to fix, just add the DontDestroyOnLoad(gameObject)

?
01
02
03
04
05
06
07
08
09
10
11
12
public class SingletonController : MonoBehaviour {
public static SingletonController instance;
 
   private void Awake() {
    if (instance != null) {
      Destroy(gameObject);
    } else {
      Instance = this;
      DontDestroyOnLoad(gameObject);
    }
  }
}
Solution for Second and Third Issue :

For this issue we have to create the Singleton at the time it is required, means we have to lazily instantiate the SingletonController in Unity

?
01
02
03
04
05
06
07
08
09
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
public class SingletonController : MonoBehaviour
{
    

 private static SingletonController instance = null;

    public static SingletonController Instance

     {

       get
      
 {
          if (instance == null)

          {

             instance = FindObjectOfType<SimpleSingleton>();

             if ( instance == null)

             {
              
 GameObject go = new GameObject();
               go.name = "SingletonController" ;
               instance = go.AddComponent<SingletonController>();

               DontDestroyOnLoad(go);

             }
          
 }
           

 return instance;

         }
      
 }
     


 void Awake()

      {

        if (instance == null )

        {
          instance = this;

          DontDestroyOnLoad(this.gameObject);

        }
       else
        {
          Destroy(gameObject);

        }
     }

}

Above code solves two different issues, it first searches for instance of SingletonController  in the scene, If it doesn’t find a SingletonController component, a GameObject is created and a SingletonController component is attached to it, so with this it is not necessary for SingletonController to exist in the scene before hand, and  this code will also destroy any additional copies it finds.

As in this implementation we are lazily instantiating the Singleton, so now we did not worry about Null Reference Exception.

Solution for Fourth Issue : Generic Unity Singleton

The fourth issue was boilerplate code, so we need generic implementation of Singleton to solve this issue

?
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
public class GenericSingletonClass<T> : MonoBehaviour where T : Component
{
     private static T instance;
     public static T Instance {
       get {
         if (instance == null) {
            instance = FindObjectOfType<T> ();
            if (instance == null) {
              GameObject obj = new GameObject ();
              obj.name = typeof(T).Name;
              instance = obj.AddComponent<T>();
            }
         }
        return instance;
       }
     }
 
     public virtual void Awake ()
     {
        if (instance == null) {
          instance = this as T;
          DontDestroyOnLoad (this.gameObject);
     } else {
       Destroy (gameObject);
     }
   }
}

So with this class we can make any class singleton, without duplicating  the code. Just inherit your class fromGenericSingletonClass and it ready to go.

e.g

?
1
2
3
4
public class MyAudioController : GenericSigletonClass<MyAudioController>;
{
  
}

 

Conclusion:

Singleton is bit complex, but it plays very important role in game development. In complex game we may need many Singleton, so it is good to have a generic implementation of Singleton to reduce code duplication. Fourth solution deals with most of the issue.

 

I am happy to hear from you guys, Please share your view in the comment section.


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值