static function FindObjectsOfType (type : Type) : Object[]
返回Type类型的所有激活的加载的物体列表,它将返回任何资源(网格,纹理,预设,...)或未激活的物体。请注意这个函数是非常慢的。不推荐在每帧使用这个函数,大多数情况下你可以使用单例模式代替。
由上面的函数引出unity3d的泛型单利模式
在Unity中,单一模式的一个很好的替代方案是使用ScriptableObjects作为全局变量的一种类型。来自Schell Games的Ryan Hipple在2017年的unity Austin上做了一个名为《Game Architecture with Scriptable Objects》的演讲,解释了如何实现它们以及它们相对于单例模式的许多优势。“工具箱”概念通过提供一种不同的方法进一步改进了单例模式,使它们更加模块化,并提高了可测试性。
单例模式
单例模式是一种确保类在任何时候只有一个全局可访问的实例可用的方法。表现得很像一个常规的静态类,但是有一些优点。这对于创建全局管理器类型类非常有用,这些类包含许多其他类需要访问的全局变量和函数。然而,模式的便捷性很容易导致误用和滥用,这使得它有些争议,许多评论家认为它是一种应该避免的反模式。但是像任何设计模式一样,单例模式在某些情况下非常有用,最终取决于开发人员是否适合它们。
单例模式优点
1.在全球范围内访问,不需要搜索或维护对该类的引用。
2.持久化数据,可用于跨场景维护数据。
3.支持静态类不能实现接口。
4.支持静态类不能用于其他类。
在Unity中使用单例而不是静态参数和方法的好处是,静态类在第一次引用时是延迟加载的,但是必须有一个空的静态构造函数(或者为您生成一个)。这意味着,如果不小心,不知道自己在做什么,就更容易搞砸和破坏代码。至于使用单例模式,您已经自动完成了许多简单的工作,比如使用静态初始化方法创建它们并使它们不可变。
单例模式缺点
1.必须使用Instance关键字(例如<ClassName>.Instance)访问单例类。
2.每次只能有一个类的实例处于活动状态。
3.修改单例可以很容易地破坏依赖于它的所有其他代码。需要大量的重构。
4.没有多态性。
5.不是很可测试的。
这个脚本不会阻止派生类中使用非单例构造函数。要防止这种情况,请为每个派生类添加一个受保护的构造函数。当Unity退出时,它会随机销毁对象,这可能会给单例对象带来问题。因此,当应用程序退出以防止出现问题时,我们会阻止对单例实例的访问。
public class SinComponent<T> : MonoBehaviour where T : MonoBehaviour
{
private static T _instance;
private static object _lock = new object();
public static T Instance
{
get
{
if (applicationIsQuitting)
{
return null;
}
lock (_lock)
{
if (_instance == null)
{
_instance = (T)FindObjectOfType(typeof(T));
if (FindObjectsOfType(typeof(T)).Length > 1)
{
return _instance;
}
if (_instance == null)
{
GameObject singleton = new GameObject();
_instance = singleton.AddComponent<T>();
singleton.name = "(singleton) " + typeof(T).ToString();
DontDestroyOnLoad(singleton);
}
}
return _instance;
}
}
}
private static bool applicationIsQuitting = false;
public void OnDestroy()
{
applicationIsQuitting = true;
}
}
使用方法很简单,从这个基类继承创建一个单例。
eg: public class MyClassName : SinComponent<MyClassName> {}