在 Unity3D 中使用单例
Using a Singleton in Unity3D
我目前正在尝试使用 Singleton 作为我在 Unity 中制作的游戏中任务组织的全局数据结构。
我的单例class代码如下:
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;
}
}
}
我用这个例子作为我 class 的基础:
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。
我很确定这个错误是由于我误解了如何使用单身人士造成的。我需要为 TaskManager 实例实现一个集合 属性 吗?还是我犯了另一个错误?
谢谢!
编辑:
PushTask()代码如下:
public void PushTask(Task t)
{
Tasks.Add(t);
}
就我个人而言,我认为您选择的解决方案并不完美。有一段时间,我尝试使用未从 MonoBehaviours 继承的 "abstract" classes 来将逻辑与 Unity 机制分离——但发现这会使代码变得臃肿和不必要的复杂。事实上,根据我的经验,每个 class 不仅包含数据而且有自己的一些逻辑,迟早会成为 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());
}
}
}
然后从中继承你的class。
我目前正在尝试使用 Singleton 作为我在 Unity 中制作的游戏中任务组织的全局数据结构。
我的单例class代码如下:
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;
}
}
}
我用这个例子作为我 class 的基础: 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。
我很确定这个错误是由于我误解了如何使用单身人士造成的。我需要为 TaskManager 实例实现一个集合 属性 吗?还是我犯了另一个错误?
谢谢!
编辑:
PushTask()代码如下:
public void PushTask(Task t)
{
Tasks.Add(t);
}
就我个人而言,我认为您选择的解决方案并不完美。有一段时间,我尝试使用未从 MonoBehaviours 继承的 "abstract" classes 来将逻辑与 Unity 机制分离——但发现这会使代码变得臃肿和不必要的复杂。事实上,根据我的经验,每个 class 不仅包含数据而且有自己的一些逻辑,迟早会成为 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());
}
}
}
然后从中继承你的class。