在Unity3D中使用Singleton

时间:2015-02-28 22:20:02

标签: c# unity3d singleton unity3d-2dtools

我目前正在尝试使用Singleton作为我在Unity中制作的游戏中的任务组织的全局数据结构。

My Singleton类代码如下:

public class TaskManager : MonoBehaviour 
{
    private List<Task> Tasks;

    private static TaskManager instance;
    private TaskManager() 
    {
        Tasks = new List<Task>();
    }

    public static TaskManager Instance
    {
        get
        {
            if(instance == null)
            {
                instance = new TaskManager();
            }
            return instance;
        }
    }
}

我用这个例子作为我班级的基础: https://msdn.microsoft.com/en-us/library/ff650316.aspx

然而,问题是,当我尝试在不同的脚本中访问TaskManager时,值不会被保存。

例如,我在一个脚本中执行:

TaskManager tm = TaskManager.Instance;

Task newTask = new Task();
tm.PushTask(newTask);

print(tm.GetTaskList().Count);

通过这个我可以看到TaskManager的计数为1,显示了新任务。

但是我的另一个脚本试图从TaskManager中读取:

TaskManager tm = TaskManager.Instance;
List<Task> l = tm.GetTaskList();
print(l.Count);

当我这样做时,Count返回0,表示上面的任务尚未保存到TaskManager。

我很确定错误是因为我误解了如何使用Singletons。我是否需要为TaskManager实例实现set属性?或者我正在制造另一个错误?

谢谢!

编辑:

PushTask()代码如下:

public void PushTask(Task t)
{
    Tasks.Add(t);
}

1 个答案:

答案 0 :(得分:6)

就个人而言,我认为您选择的解决方案并不完美。有一段时间,我尝试使用不从MonoBehaviours继承的“抽象”类来将逻辑与Unity机制分离 - 但发现这会使代码变得臃肿且不必要复杂。事实上,根据我的经验,每个不仅包含数据而且拥有自己逻辑的类最终都会成为MonoBehaviour。

因此,我不是从MonoBehaviour中删除继承,而是通过实现通常的MonoBehaviour单例模式来解决它:

using UnityEngine;

public abstract class Singleton<T> : MonoBehaviour where T : Singleton<T>
{
    public static T Instance { get; private set; }

    protected virtual void Awake()
    {
        if (Instance == null)
        {
            Instance = (T) this;
        }
        else
        {
            Debug.LogError("Got a second instance of the class " + this.GetType());
        }
    }
}

然后继承你的课程。