9.管理器基类和GameRoot
管理器基类和GameRoot
管理器基类
为管理器创建基类和管理器单例。
public abstract class ManagerBase : MonoBehaviour
{
public virtual void Init() { }
}
public abstract class ManagerBase<T> : ManagerBase where T : ManagerBase<T>
{
public static T Instance;
/// <summary>
/// 管理器的初始化
/// </summary>
public override void Init()
{
Instance = this as T;
}
}
这里可以发现在ManagerBase单例类上又包了一层ManagerBase,其目的就在与对不同的管理器单例进行一层包装,这样统一方便在GameRoot中用数组进行统一存储(不必关系具体T是哪一类管理器),ManagerBase实际是所有管理器类的爷爷类。
ManagerBase[] managers = GetComponents<ManagerBase>();
这种思想在事件系统中也有类似体现,对不同参数个数的事件类进行一层接口封装,方便Dictionary进行存储,稍有区别在于事件系统中事件类型只存数据可以使用接口进行封装,而管理器由于需要继承Mono所以用抽象类进行封装(接口不能继承Mono类,也可以爷爷接口,父亲继承Mono)。
GameRoot
使用GameRoot控制管理器的初始化顺序。
protected override void Awake()
{
if (Instance != null)
{
Destroy(gameObject);
return;
}
base.Awake();
DontDestroyOnLoad(gameObject);
// 初始化所有管理器
InitManager();
}
private void InitManager()
{
ManagerBase[] managers = GetComponents<ManagerBase>();
for (int i = 0; i < managers.Length; i++)
{
managers[i].Init();
}
}
对于GameRoot游戏根节点,其作为游戏运行的核心,挂载了许多功能脚本,应该是全局唯一且跨场景不销毁的,所以首先要判断当前是否存在GameRoot单例,存在那说明自己是多余的,把自己销毁并return,如果当前没有GameRoot单例(进入游戏第一个场景),需要调用父类的Awake方法完成单例实例化,再去调用InitManager对所有管理器类进行初始化,这样确保GameRoot第一个被加载且可以在这里自定义控制管理器类初始化顺序。
Unity独立游戏开发-程序框架1.0 文章被收录于专栏
Unity独立游戏开发