How to make Unity singleton base class to support generics?
In my project, I have a class structure as shown in the image.
The green classes are old codes, that runs very well. The classes in red boxes are newly added codes. There're no compiler errors, however when click play in Unity and runs into the new code, the three classes can't be initialized correctly.
And unity console gives warning that says "The class named 'DataMgrBase`2' is generic. Generic MonoBehaviours are not supported! UnityEngine.GameObject:AddComponent()" at this line: "instance = obj.AddComponent ();"
How can I solve this problem?
Following are some code for your reference, thanks!
Implementation of singleton base class:
using UnityEngine;
using System.Collections;
public class UnitySingletonPersistent<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;
obj.hideFlags = HideFlags.DontSave;
instance = obj.AddComponent<T> ();
}
}
return instance;
}
}
public virtual void Awake ()
{
DontDestroyOnLoad (this.gameObject);
if (instance == null) {
instance = this as T;
} else {
Destroy (gameObject);
}
}
}
Implementation of DataMgrBase:
public class DataMgrBase<TKey, TValue>: UnitySingletonPersistent<DataMgrBase<TKey, TValue>> {
protected Dictionary<TKey, TValue> dataDict;
public override void Awake()
{
base.Awake();
dataDict = new Dictionary<TKey, TValue>();
}
public TValue GetDataForKey(TKey key)
{
TValue data;
if (dataDict.TryGetValue(key, out data))
{
return data;
}
else
{
data = LoadDataForKey(key);
if (data != null)
{
dataDict.Add(key, data);
}
return data;
}
}
virtual protected TValue LoadDataForKey(TKey key)
{
if (dataDict.ContainsKey(key))
{
return GetDataForKey(key);
}
else
{
return default(TValue);
}
}
}
Answer by Sun-Pengfei · Mar 15, 2016 at 01:48 PM
I've solved it by myself as following:
Change of the base class to get a new generic type(of the class that will derive from it, and pass this type to singleton base class)
public class DataMgrBase<TKey, TValue, TClass>: UnitySingletonPersistent<TClass> where TClass: Component
For all the other three classes that want to derive from it, change them as following form:
public class MobSettingDataMgr : DataMgrBase<int, MobSettingData, MobSettingDataMgr>
Your answer
Follow this Question
Related Questions
Singleton Problem 0 Answers
Singleton HELP 1 Answer
How can I handle scripts correctly? What's a good way to apply scripts to GameObjects? 1 Answer