GameBox使用
服务
服务是对微模块的定义,每一个服务都有严格的边界限定。服务是以二进制文件(动态链接库)提供,并且以接口对外提供功能服务。
每一个服务都实现了IService接口
// 服务的基础接口
public interface IService
{
// Id是唯一标示一个Service的标识符,调用者通过Id可以查询到Service的实例。
string Id { get; }
// 服务的启动入口,ServiceCenter启动一个Service时会调用该方法,从而让Service完成初始化。
void Run(IServiceRunner runner);
}
配置服务
- 在服务中心(ServiceCenter)中勾选需要的服务模块,更新到项目,例如勾选了资产管理和对象池两个模块
- 项目的GameBox目录下多了两个DLL(AssetManager.dll和ObjectPool.dll),展开会看到各有一个Unity Component(AssetManagerInstaller和RecycleManagerInstaller)
- 拖拽这两个Component挂在场景中的_GameBox上
获取服务
以AssetManager(资产管理)为例,它对外提供了IAssetManager接口,定义如下
public interface IAssetManager : IService
{
...
IAsset Load(string path, AssetType type);
void LoadAsync(string path, AssetType type, Action<IAsset> handler);
...
}
GameBox提供了两种方式获取该接口:安全和非安全。
之所以提供两种方式是因为GameBox定义的服务是允许异步完成的,也就是说服务是有可能需要时间才能完成的。如果要确保服务可用,则也必须采用异步的方式提供;但异步方式在使用上不方便,所以还是要提供同步的获取方式,但从设计上无法确保获取的服务是完成初始化(只能通过编程规范来确保)。
安全获取
通过异步任务(ServiceTask)的方式获取。
new ServiceTask<IAssetManager>().Start().Continue(task =>
{
var assetManager = task.Result as IAssetManager;
...
return null;
});
非安全获取
通过ServiceCenter同步获取。
var assetManager = ServiceCenter.GetService<IAssetManager>();
...
编程规范
通过编程规范来确保服务获取的安全性,也就是结合同步和异步两种方式。在初始化阶段通过异步方式确保服务初始化完毕;其余阶段直接通过同步方式获取。例如使用状态机控制流程
// 游戏控制类
public class Game : MonoBehaviour
{
public void Start()
{
// 进入初始化状态
ChangeState(new InitializeState());
}
public void Update()
{
if (null != this.state)
{
this.state.OnUpdate(this); // 状态更新
}
}
public void ChangeState(State state)
{
if (null != this.state)
{
this.state.OnExit(this); // 状态清理
}
this.state = state;
if (null != this.state)
{
this.state.OnEnter(this); // 状态初始化
}
}
private State state = null;
}
// 状态基类
public class State
{
public virtual void OnEnter(Game game)
{}
public virtual void OnUpdate(Game game)
{}
public virtual void OnExit(Game game)
{}
}
// 初始化状态
public class InitializeState : State
{
public override void Enter(Game game)
{
new ServiceTask(new Type[] {
typeof(IAssetManager),
typeof(IRecycleManager),
}).Start().Continue(task =>
{
game.ChangeState(new RunningState()); // 所有依赖的服务已初始化完毕,进入运行状态
return null;
});
}
}
// 运行状态
public class RunningState : State
{
public override void Enter(Game game)
{
var assetManager = ServiceCenter.GetService<IAssetManager>(); // 同步获取所需服务
var prefab = assetManager.Load("Character.prefab", AssetType.Prefab);
...
}
}