UIFacade 是 UI 系统的外观类,属于外观模式。
GameController / SceneState
↓
UIFacade
┌────┼────┐
UIManager Panel Factory
│ │ │
面板字典 UI显示 资源加载
它对外提供统一的 UI 操作入口,把 UIManager、Panel、Factory、AudioManager 和场景状态切换等多个子系统封装起来。外部代码只需要通过 UIFacade 进行面板添加、创建、销毁、场景切换和资源获取,不需要直接依赖这些具体模块。
在 Flower Defense 中,UIFacade 还负责场景切换时的黑幕动画、当前面板字典管理,以及将 UI 面板放回对象池。这样可以降低 UI 模块之间的耦合,让场景切换和 UI 资源管理更加统一。
它主要负责什么?
1. 管理场景状态切换
cs
public void ChangeSceneState(IBaseSceneState baseSceneState)
{
lastSceneState = currentSceneState;
ShowMask();
currentSceneState = baseSceneState;
}
切换过程不是直接跳转,而是:
实际的 EnterScene() 和 ExitScene() 会由状态类负责。
2. 管理当前场景的 Panel
进入场景时,状态类会添加需要的面板:
cs
mUIFacade.AddPanelToDict(StringManager.MainPanel);
mUIFacade.AddPanelToDict(StringManager.SetPanel);
UIFacade 再通过工厂获取对应的 Panel:
cs
mUIManager.currentScenePanelDict.Add(
uiPanelName,
GetGameObjectResource(
FactoryType.UIPanelFactory,
uiPanelName
)
);
进入场景后,`InitDict()` 会:
- 将面板放到 Canvas 下;
- 设置位置和缩放;
- 获取
IBasePanel; - 调用面板初始化;
- 加入当前场景面板字典。
离开场景时,`ClearDict()` 会:
- 清理面板字典;
- 把面板放回对象池;
- 释放当前场景的 UI 资源。
3. 统一创建 UI
例如创建遮罩、按钮或其他 UI:
cs
public GameObject CreateUIAndSetUIPosition(string uiName)
{
GameObject itemGo =
GetGameObjectResource(FactoryType.UIFactory, uiName);
itemGo.transform.SetParent(canvasTransform);
itemGo.transform.localPosition = Vector3.zero;
itemGo.transform.localScale = Vector3.one;
return itemGo;
}
4. 统一访问资源和音频
UIFacade 还对外提供:
cs
GetSprite(...)
GetAudioSource(...)
GetRuntimeAnimatorController(...)
GetGameObjectResource(...)
PushGameObjectToFactory(...)
为什么需要 UIFacade?
如果没有 UIFacade,可能每个 Panel 都要直接依赖:
- UIManager
- GameManager
- FactoryManager
- AudioSourceManager
- SceneState
- Canvas
模块之间会产生很多耦合。
使用 UIFacade 后:外部只面对一个接口,内部子系统可以调整而不影响调用方。
Panel / SceneState
↓
UIFacade
↓
多个 UI 子系统
它和 UIManager 有什么区别?
UIManager = 管理 UI 数据和面板集合
UIFacade = 对外提供统一的 UI 操作入口
UIManager 更像内部管理者,负责保存当前场景的 Panel 字典。
UIFacade 更像对外服务层,负责协调:
- 面板;
- 场景状态;
- UI 工厂;
- Canvas;
- 音频;
- 转场动画。