Files
UnityAI/modules/frameworks/UI窗口系统/开发指南.md
lms ee1ff7f444 [docs][refactor]: 将旧 01~06 中文教程合并整理为 modules/frameworks 文件夹结构
- 删除 01~05 旧中文教程目录
- 将 03 核心功能教程拆分为各 framework 模块的子文档
- 06 工具脚本移入 modules/frameworks/编辑器工具/UI工具/
- 非框架内容合并进 rules/20-开发规则.md 与 rules/40-工作流清单.md
- 更新所有交叉链接与文档关联表

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-07 18:36:15 +08:00

6.9 KiB
Raw Blame History

StrayFog 框架 UI 开发指南

一、窗口开发

1.1 创建模板

[HFAssetBundlePath(enHFLanguageRootFolder.ASSETS_GAME_GAMEHFRESOURCE, "UIWindows/MyWindow/MyWindow.prefab")]
[HFUIWindowLayer(enHFUICanvasLayer.UIWindow, enHFUIWindowLayer.Dynamic)]
public class MyWindow : AbsHFUIWindow
{
    private SFUI_Button BtnClose;

    protected override void OnRunAwake()
    {
        base.OnRunAwake();
        BtnClose = FindUICtrlByName<SFUI_Button>("BtnClose");
        BtnClose.OnAddClickListener += OnBtnClose;
    }

    protected override void OnOpen(Action _onOpenComplete)
    {
        base.OnOpen(_onOpenComplete);
        RefreshUI();
    }

    private void OnBtnClose(GameObject go) => CloseWindow();
    private void RefreshUI() { }
}

1.2 生命周期

方法 调用时机 推荐操作
OnRunAwake 创建时一次 绑定 UI 事件、初始化滚动列表 BindEvent
OnOpen 每次打开 注册 TC 事件、调用 ShowView() 刷新数据
OnClose 每次关闭 取消 TC 事件

关键原则

  • 绑定类操作(如 BindEvent)放在 OnRunAwake,只需执行一次
  • 刷新类操作(如 ShowView)放在 OnOpen,每次打开都需执行

1.3 窗口操作

// 打开
HFFunCatalogue.UIManager.OpenWindow<MyWindow>();
// 关闭
HFFunCatalogue.UIManager.CloseWindow<MyWindow>();

二、事件绑定

事件类型 绑定位置 是否需要 -=
UI 按钮/拖拽 OnRunAwake 不需要
全局 TC 事件 OnOpen/OnClose 需要

三、常用组件

3.1 按钮

SFUI_Button btn = GetComponent<SFUI_Button>();
btn.OnAddClickListener += OnBtnClick;
btn.SetSelfGray(true);

3.2 文本

SFUI_TextMeshProUGUI txt = GetComponent<SFUI_TextMeshProUGUI>();
txt.text = "Hello";

3.3 图片

SFUI_Image img = GetComponent<SFUI_Image>();
img.HFSetSprite(/* atlasName */, "Icon_Player", /* languageRoot */);

3.4 滚动列表(核心)

生命周期正确划分示例

private SFUI_ScrollRect m_ScrollList;
private List<ItemData> m_ItemList;

protected override void OnRunAwake()
{
    base.OnRunAwake();
    m_ScrollList = FindUICtrlByName<SFUI_ScrollRect>("ScrollList");
    
    // ✅ 绑定事件放在 Awake一次绑定永久生效
    m_ScrollList.BindEvent(
        () => m_ItemList.Count,                           // 数据源闭包
        (idx) => itemPrefab.gameObject,                   // 生成预制体
        OnUpdateItem,                                    // 更新回调
        (item) => item.gameObject.HFGetOrAddSimulateBehaviour<ItemSlot>() // 获取组件
    );
}

protected override void OnOpen(Action _onOpenComplete)
{
    base.OnOpen(_onOpenComplete);
    m_ItemList = GetDataFromServer(); // 获取最新数据
    m_ScrollList.ShowView();          // ✅ 刷新显示放在 Open
}

private void OnUpdateItem(int index, AbsHFUIWindow window)
{
    ItemSlot slot = window as ItemSlot;
    slot.SetData(m_ItemList[index]);
}

设计要点

  • BindEventOnRunAwake 中执行,建立绑定机制
  • ShowViewOnOpen 中执行,触发数据刷新
  • 数据源通过闭包引用,ShowView 时自动获取最新数据

四、对象池

场景 推荐方式
滚动列表 SFUI_ScrollRect.BindEvent(内置池)
固定栏(装备/技能) HFSimulateBehaviourPool<T>

五、子组件

5.1 多态基类

public abstract class AbsListItem<T> : AbsHFUIWindow
{
    protected SFUI_Button m_BtnItem;
    protected Action<T> m_OnSelect;

    protected override void OnRunAwake()
    {
        base.OnRunAwake();
        m_BtnItem = gameObject.GetComponent<SFUI_Button>();
        m_BtnItem.OnAddClickListener += OnBtnClick;
    }

    public virtual void SetData(T data, Action<T> onSelect = null)
    {
        m_OnSelect = onSelect;
        OnDataChanged(data);
    }

    protected abstract void OnDataChanged(T data);
    private void OnBtnClick(GameObject go) => m_OnSelect?.Invoke(m_CurrentData);
}

// 子类
public class CardItem : AbsListItem<CardData>
{
    protected override void OnDataChanged(CardData data) { }
}

六、开发规范

6.1 文件路径

6.1.1 核心资源路径

类型 路径 说明
窗口脚本 Assets/Game/GameHFScripte/GameFunction/UIWindows/{WindowName}/ 窗口逻辑脚本存放目录
窗口预制体 Assets/Game/GameHFResource/CN/UIWindows/{WindowName}/ UI 窗口预制体存放目录
图标图集 Assets/Game/GameHFResource/CN/SpriteAtlas/{AtlasName}/ SpriteAtlas 图集资源
字体资源 Assets/Game/GameHFResource/CN/Fonts/ 字体文件存放目录

6.1.2 工具脚本路径

工具名称 路径 职责
UIPrefabGenerator Assets/Editor/Command/UIPrefabGenerator.cs JSON 转 UI 预制体
UIPrefabToJson Assets/Editor/Command/UIPrefabToJson.cs 预制体转 JSON
RemoteCommand Assets/Editor/Command/RemoteCommand.cs 外部命令接口
ExternalCommandListener Assets/Editor/Command/ExternalCommandListener.cs 外部命令监听器

6.1.3 文档路径

文档名称 路径
UI 开发指南 UI窗口系统/开发指南.md
UI 界面拼接设计指南 UI窗口系统/界面拼接.md

6.1.4 命令触发路径

  • 触发文件: {ProjectRoot}/Trigger_Command.txt
  • JSON 配置: Assets/Editor/UI/{WindowName}.json

6.2 性能优化

  • 使用对象池复用 UI 元素
  • 将图标打包到 SpriteAtlas
  • 滚动列表用 SFUI_ScrollRect.BindEvent

版本: v1.1
适用: StrayFog 框架 UI 开发人员


文档关联

当本文档发生变更时,应同步检查以下关联文档,避免信息不一致。

文档 关联原因
UI 窗口系统入口 本文件是 UI 窗口系统模块的子文档
UI 界面拼接设计指南 界面拼接是 UI 开发的补充设计指南
UI 拼接工具 JSON 驱动 UI 生成工具说明
事件系统 UI 事件订阅和释放规范
对象池与运行时对象管理 UI 元素复用相关
资源管理 UI 资源加载依赖资源管理
modules/模块索引.md 模块索引是项目知识总入口
rules/10-架构说明.md 架构说明定义总体分层和依赖方向
rules/20-开发规则.md UI 命名与编码规范互相引用
rules/30-模块登记规则.md 模块登记规则定义分类和状态口径