简体   繁体   English

在Unity3D中使用Singleton

[英]Using a Singleton in Unity3D

I'm currently attempting to use a Singleton as a global data structure for Task organization in a game I'm making in Unity. 我正在尝试使用Singleton作为我在Unity中制作的游戏中的任务组织的全局数据结构。

My Singleton class code is as follows: 我的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;
        }
    }
}

I used this example as a basis for my class: https://msdn.microsoft.com/en-us/library/ff650316.aspx 我用这个例子作为我班级的基础: https//msdn.microsoft.com/en-us/library/ff650316.aspx

However, the problem is, when I try to access the TaskManager in different scripts, the values don't get saved. 但是,问题是,当我尝试在不同的脚本中访问TaskManager时,值不会被保存。

For example, in one script I do: 例如,我在一个脚本中执行以下操作:

TaskManager tm = TaskManager.Instance;

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

print(tm.GetTaskList().Count);

Through this I can see that the TaskManager has a count of 1, showing the new task. 通过这个我可以看到TaskManager的计数为1,显示了新任务。

But then my other script attempts to read from the TaskManager: 但是我的另一个脚本试图从TaskManager中读取:

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

When I do this, the Count is returned as 0, showing that the above task from the world has not been saved to the TaskManager. 当我这样做时,Count返回0,表明上面的任务来自世界尚未保存到TaskManager。

I'm pretty sure the error is resulting from me misunderstanding how to use Singletons. 我很确定这个错误是因为我误解了如何使用Singletons。 Do I need to implement a set property for TaskManager Instance? 我是否需要为TaskManager实例实现set属性? Or is there another mistake I'm making? 或者我正在制造另一个错误?

Thanks! 谢谢!

Edit: 编辑:

The PushTask() code is as follows: PushTask()代码如下:

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

Personally, I don't think that solution that you chose is a perfect one. 就个人而言,我认为您选择的解决方案并不完美。 For some time, I tried using "abstract" classes that didn't inherit from MonoBehaviours, to decouple logic from Unity mechanics — but found that this makes code bloated and unnecessary complicated. 有一段时间,我尝试使用不从MonoBehaviours继承的“抽象”类来将逻辑与Unity机制分离 - 但发现这会使代码变得臃肿且不必要复杂。 In fact, every class that doesn't only contain data but has some logic of its own ends up being a MonoBehaviour sooner or later, in my experience. 事实上,根据我的经验,每个不仅包含数据但具有某种逻辑的类最终都会成为MonoBehaviour。

So, instead of removing inheritance from MonoBehaviour, I'd solve it by implementing the usual MonoBehaviour singleton pattern: 因此,我不是从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());
        }
    }
}

And then just inheriting your class from it. 然后从它继承你的类。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM