From 6ede45310302c89a748d3c5f925b86d5ef1d3d83 Mon Sep 17 00:00:00 2001 From: Shiliang Date: Fri, 22 May 2026 15:23:11 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BC=98=E5=8C=96UI=E5=BC=80=E5=8F=91=E6=8C=87?= =?UTF-8?q?=E5=8D=97=EF=BC=9A=E6=95=B4=E5=90=88=E4=B8=89=E4=B8=AA=E6=96=87?= =?UTF-8?q?=E6=A1=A3=E4=B8=BA=E4=B8=80=E4=B8=AA=EF=BC=8C=E7=B2=BE=E7=AE=80?= =?UTF-8?q?=E4=BB=A3=E7=A0=81=E7=A4=BA=E4=BE=8B=EF=BC=8C=E6=B7=BB=E5=8A=A0?= =?UTF-8?q?=E6=96=87=E4=BB=B6=E6=94=BE=E7=BD=AE=E8=A7=84=E8=8C=83?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- 03_核心功能/UI事件绑定指南.md | 157 ----------------- 03_核心功能/UI开发指南.md | 315 ++++++++++++++++++++++++++++++++++ 03_核心功能/UI窗口开发指南.md | 228 ------------------------ 03_核心功能/UI组件使用指南.md | 256 --------------------------- README.md | 6 +- 5 files changed, 316 insertions(+), 646 deletions(-) delete mode 100644 03_核心功能/UI事件绑定指南.md create mode 100644 03_核心功能/UI开发指南.md delete mode 100644 03_核心功能/UI窗口开发指南.md delete mode 100644 03_核心功能/UI组件使用指南.md diff --git a/03_核心功能/UI事件绑定指南.md b/03_核心功能/UI事件绑定指南.md deleted file mode 100644 index c1baea4..0000000 --- a/03_核心功能/UI事件绑定指南.md +++ /dev/null @@ -1,157 +0,0 @@ -# StrayFog 框架 UI事件绑定指南 - -## 一、事件绑定位置规范 - -### 1.1 事件绑定位置总览 - -| 事件类型 | 推荐位置 | 原因 | -|---------|---------|------| -| **UI按钮事件** | `OnRunAwake` | 静态稳定,只需注册一次 | -| **列表拖拽事件** | `OnRunAwake` | 窗口生命周期内持续响应 | -| **全局CTC事件** | `OnOpen`/`OnClose` | 窗口关闭后不应响应 | -| **数据刷新逻辑** | `OnOpen` | 每次打开窗口需刷新 | - -### 1.2 推荐绑定模式(防重复注册保护) - -```csharp -public class BagWindow : AbsHFUIWindow -{ - private SFUI_Button BtnClose; - private SFUI_ScrollRect BagListView; - - protected override void OnRunAwake() - { - base.OnRunAwake(); - BtnClose = FindUICtrlByName("BtnClose"); - BagListView = FindUICtrlByName("BagListView"); - - // ✅ 按钮事件放在 OnRunAwake(先取消再注册防止重复) - BtnClose.OnAddClickListener -= OnBtnClose; - BtnClose.OnAddClickListener += OnBtnClose; - - // ✅ 列表事件也放在 OnRunAwake - BagListView.OnAddBeginDragListener -= OnBeginDrag; - BagListView.OnAddBeginDragListener += OnBeginDrag; - } - - protected override void OnOpen(Action _onOpenComplete) - { - base.OnOpen(_onOpenComplete); - // ✅ 全局CTC事件放在 OnOpen - HFFunCatalogue.Event.TCEvent.AddListener( - enHFCTCEvent.BagItemUpdate, OnBagItemUpdate); - } - - protected override void OnClose(Action _onCloseComplete) - { - // ✅ 全局CTC事件在 OnClose 取消 - HFFunCatalogue.Event.TCEvent.RemoveListener( - enHFCTCEvent.BagItemUpdate, OnBagItemUpdate); - base.OnClose(_onCloseComplete); - } - - private void OnBtnClose(GameObject go) { /* 按钮点击处理 */ } - private void OnBeginDrag(GameObject go) { /* 拖拽处理 */ } - private void OnBagItemUpdate(IHFEventArg arg) { /* 数据更新处理 */ } -} -``` - -### 1.3 防重复注册原理 - -```csharp -// 先取消注册,再添加注册 -BtnLogin.OnAddClickListener -= OnBtnLoginClick; // 防止重复注册 -BtnLogin.OnAddClickListener += OnBtnLoginClick; // 安全注册 -``` - -**作用**:即使`OnRunAwake`被多次调用(如对象池复用),也不会导致事件重复触发。 - ---- - -## 二、SFUI_ScrollRect 绑定模式 - -### 2.1 列表绑定(推荐) - -```csharp -protected override void OnRunAwake() -{ - base.OnRunAwake(); - - var itemPrefab = FindUICtrlByName("Item"); - BagListView = FindUICtrlByName("BagListView"); - - BagListView.BindEvent( - () => { return m_items.Count; }, // 数据源数量 - (idx) => { return itemPrefab.gameObject; }, // 实例化模板 - OnUpdateItem, // 更新回调 - (item) => { // 组件获取 - return item.gameObject.HFGetOrAddSimulateBehaviour(); - } - ); -} - -private void OnUpdateItem(SFUI_ScrollRectItem item) -{ - var bagItem = item.simulateBehaviour as BagItemSlot; - bagItem.SetData(m_items[item.dataIdx], m_select, item.dataIdx, OnSelect); -} -``` - -### 2.2 列表刷新 - -```csharp -// 刷新整个列表 -BagListView.ShowView(); - -// 刷新指定项 -BagListView.RefreshView(null); - -// 滚动到指定位置 -BagListView.ScrollToIndex(0); -``` - ---- - -## 三、事件系统分类 - -### 3.1 TCEvent(客户端事件) - -```csharp -// 注册监听(在 OnOpen 中) -HFFunCatalogue.Event.TCEvent.AddListener( - enHFCTCEvent.BagItemUpdate, OnBagItemUpdate); - -// 取消监听(在 OnClose 中) -HFFunCatalogue.Event.TCEvent.RemoveListener( - enHFCTCEvent.BagItemUpdate, OnBagItemUpdate); -``` - -### 3.2 STCEvent(服务器事件) - -```csharp -// 在 Manager 层注册(UI窗口不直接监听) -HFFunCatalogue.Event.STCEvent.AddListener( - enHFSTCEvent.GetBag, OnPushBagItem); -``` - -> **注意**:UI窗口中不直接监听STCEvent,应在Logic层Manager中监听,然后通过TCEvent通知UI。 - ---- - -## 四、按钮事件委托 - -### 4.1 SFUI_Button 事件列表 - -| 事件 | 委托签名 | 说明 | -|-----|---------|------| -| `OnAddClickListener` | `Click(GameObject go)` | 点击事件 | -| `OnAddEnterListener` | `Enter(GameObject go)` | 鼠标进入 | -| `OnAddExitListener` | `Exit(GameObject go)` | 鼠标退出 | -| `OnAddPointerUpListener` | `PointerUp(GameObject go)` | 指针抬起 | -| `OnAddBeginDragListener` | `BeginDrag(GameObject go)` | 开始拖拽 | -| `OnAddEndDragListener` | `EndDrag(GameObject go)` | 结束拖拽 | - ---- - -**版本**: v1.1 -**适用范围**: GiftGameX项目业务开发人员 \ No newline at end of file diff --git a/03_核心功能/UI开发指南.md b/03_核心功能/UI开发指南.md new file mode 100644 index 0000000..7df6d5c --- /dev/null +++ b/03_核心功能/UI开发指南.md @@ -0,0 +1,315 @@ +# StrayFog 框架 UI开发指南 + +## 一、UI窗口开发 + +### 1.1 窗口创建模板 + +```csharp +[HFAssetBundlePath(enHFLanguageRootFolder.ASSETS_GAME_GAMEHFRESOURCE, "UIWindows/MyWindow/MyWindow.prefab")] +[HFUIWindowLayer(enHFUICanvasLayer.UIWindow, enHFUIWindowLayer.Dynamic, isIgnoreCloseByESC = false)] +public class MyWindow : AbsHFUIWindow +{ + // UI组件 + private SFUI_Button BtnClose; + private SFUI_TextMeshProUGUI TxtTitle; + + protected override void OnRunAwake() + { + base.OnRunAwake(); + // 初始化UI组件引用 + BtnClose = FindUICtrlByName("BtnClose"); + TxtTitle = FindUICtrlByName("TxtTitle"); + + // 绑定按钮事件(OnRunAwake只执行一次) + BtnClose.OnAddClickListener += OnBtnClose; + } + + protected override void OnOpen(Action _onOpenComplete) + { + base.OnOpen(_onOpenComplete); + // 注册全局事件监听(每次打开都要注册) + HFFunCatalogue.Event.TCEvent.AddListener( + enHFCTCEvent.DataUpdate, OnDataUpdate); + + // 初始化数据显示 + RefreshUI(); + } + + protected override void OnClose(Action _onCloseComplete) + { + // 取消全局事件监听(每次关闭都要取消) + HFFunCatalogue.Event.TCEvent.RemoveListener( + enHFCTCEvent.DataUpdate, OnDataUpdate); + + base.OnClose(_onCloseComplete); + } + + private void OnBtnClose(GameObject go) => CloseWindow(); + private void OnDataUpdate(IHFEventArg arg) => RefreshUI(); + private void RefreshUI() { /* 更新UI显示 */ } +} +``` + +### 1.2 窗口生命周期 + +| 方法 | 调用时机 | 说明 | 推荐操作 | +|-----|---------|------|---------| +| `OnRunAwake` | 窗口创建时调用一次 | 初始化组件引用 | **绑定按钮事件、初始化对象池** | +| `OnRunStart` | OnRunAwake之后调用一次 | 初始化数据 | **配置数据加载** | +| `OnOpen` | 每次打开窗口时调用 | 注册事件、刷新数据 | **注册TC事件、初始化数据显示** | +| `OnClose` | 每次关闭窗口时调用 | 取消事件、清理资源 | **取消TC事件、回收对象池** | +| `OnDestroy` | 窗口销毁时调用 | 释放资源 | **释放非托管资源** | + +### 1.3 窗口操作 + +```csharp +// 打开窗口 +HFFunCatalogue.UIManager.OpenWindow(); + +// 打开窗口并获取实例 +HFFunCatalogue.UIManager.OpenWindow((win, args) => { + // win: 窗口实例 +}); + +// 关闭窗口 +HFFunCatalogue.UIManager.CloseWindow(); +``` + +--- + +## 二、事件绑定规范 + +### 2.1 事件绑定位置 + +| 事件类型 | 推荐位置 | 原因 | 是否需要 `-=` 防重复 | +|---------|---------|------|-------------------| +| **UI按钮事件** | `OnRunAwake` | 静态稳定,只需注册一次 | ❌ 不需要 | +| **列表拖拽事件** | `OnRunAwake` | 窗口生命周期内持续响应 | ❌ 不需要 | +| **全局TC事件** | `OnOpen`/`OnClose` | 窗口关闭后不应响应 | ✅ 需要 | +| **数据刷新逻辑** | `OnOpen` | 每次打开窗口需刷新 | - | + +--- + +## 三、常用UI组件 + +### 3.1 SFUI_Button组件 + +```csharp +SFUI_Button btn = GetComponent(); + +// 添加事件 +btn.OnAddClickListener += OnBtnClick; +btn.OnAddEnterListener += OnBtnEnter; +btn.OnAddExitListener += OnBtnExit; + +// 设置状态 +btn.SetSelfGray(true); // 灰色不可用 +btn.interactable = false; // 不可交互 +btn.SetSelected(true); // 选中状态 +``` + +### 3.2 SFUI_TextMeshProUGUI组件 + +```csharp +SFUI_TextMeshProUGUI txt = GetComponent(); + +txt.text = "Hello World"; +txt.color = Color.red; +txt.fontSize = 24; +txt.outlineColor = Color.black; +txt.outlineWidth = 2; + +// 动态调整高度 +txt.rectTransform.SetSizeWithCurrentAnchors(RectTransform.Axis.Vertical, txt.preferredHeight); +``` + +### 3.3 SFUI_Image组件 + +```csharp +SFUI_Image img = GetComponent(); + +// 加载Sprite +img.HFSetSprite(enHFSpriteAtlas.ASSETS_GAME_GAMEHFRESOURCE_SPRITEATLAS_ITEM, + "Icon_Player", + enHFLanguageRootFolder.ASSETS_GAME_GAMEHFRESOURCE); + +// 设置透明度 +img.SetAlpha(0.5f); + +// 设置灰度 +img.SetSelfGray(true); + +// 清空Sprite +img.HFClearSprite(); +``` + +### 3.4 SFUI_ScrollRect组件(列表滚动) + +SFUI_ScrollRect 专门用于处理多物品的上下滑动列表,提供高效的列表渲染和滚动管理。 + +```csharp +SFUI_ScrollRect scroll = GetComponent(); + +// 绑定列表数据(核心方法) +scroll.BindEvent( + () => itemList.Count, // 数据数量 + (idx) => itemPrefab.gameObject, // 获取模板对象 + OnUpdateItem, // 更新回调 + (item) => item.gameObject.HFGetOrAddSimulateBehaviour() // 获取组件 +); + +// 刷新列表显示 +scroll.ShowView(); + +// 滚动到指定位置 +scroll.ScrollToIndex(0); // 滚动到第N项 +scroll.verticalNormalizedPosition = 0; // 滚动到底部(1=顶部,0=底部) +``` + +**使用流程**: +1. 在 `OnRunAwake` 中调用 `BindEvent` 绑定数据 +2. 在 `OnOpen` 或数据更新时调用 `ShowView` 刷新显示 +3. 通过 `ScrollToIndex` 或 `verticalNormalizedPosition` 控制滚动位置 + +--- + +## 四、对象池模式 + +### 4.1 对象池初始化 + +```csharp +HFSimulateBehaviourPool m_ItemPool = null; + +protected override void OnRunAwake() +{ + base.OnRunAwake(); + SFUI_Button itemPrefab = FindUICtrlByName("ItemPrefab"); + SFUI_Behaviour parentContainer = FindUICtrlByName("ParentContainer"); + + // 创建对象池 + m_ItemPool = new HFSimulateBehaviourPool( + itemPrefab.gameObject, // 模板对象 + parentContainer.gameObject // 父容器 + ); +} +``` + +### 4.2 对象池使用 + +```csharp +private void RefreshItems() +{ + // 回收所有已使用对象 + m_ItemPool.RecycUsingObject(); + + // 遍历数据创建新对象 + foreach (var data in itemDataList) + { + ItemSlot slot = m_ItemPool.GetItem(out bool isNew); + slot.SetData(data, OnItemClick); + } +} + +private void OnItemClick(ItemData data) +{ + // 处理点击逻辑 +} +``` + +--- + +## 五、子组件开发 + +子组件作为列表项使用,继承 `AbsHFUIWindow`,核心特点: + +| 特点 | 说明 | +|-----|------| +| **数据传递** | 通过 `SetData` 方法接收数据 | +| **回调机制** | 通过 `Action` 与父组件通信 | +| **对象池** | 配合 `HFSimulateBehaviourPool` 实现复用 | + +--- + +## 六、UI开发规范 + +### 6.1 文件放置结构 + +UI相关文件应按照以下规范组织: + +**脚本文件**(.cs): +``` +Assets/Game/GameHFScripte/GameFunction/UIWindows/ +├── BagWindow/ +│ └── BagWindow.cs # 窗口脚本 +├── MainWindow/ +│ └── MainWindow.cs +└── Common/ + └── ItemSlot.cs # 公共子组件脚本 +``` + +**预制体文件**(.prefab): +``` +Assets/Game/GameHFResource/CN/UIWindows/ +├── BagWindow/ +│ └── BagWindow.prefab # 窗口预制体 +├── MainWindow/ +│ └── MainWindow.prefab +└── Common/ + └── ItemSlot.prefab # 公共子组件预制体 +``` + +**图片资源**(按UI名称分类): +``` +Assets/Game/GameHFResource/CN/SpriteAtlas/ +├── BagWindow/ # 背包窗口相关图片 +│ ├── Icon_Bag.png +│ └── Btn_Close.png +├── MainWindow/ # 主窗口相关图片 +│ └── Btn_Menu.png +└── Common/ # 公共图片 + └── Btn_Confirm.png +``` + +### 6.2 窗口属性配置 + +每个窗口必须配置以下属性: + +```csharp +[HFAssetBundlePath(enHFLanguageRootFolder.ASSETS_GAME_GAMEHFRESOURCE, + "UIWindows/BagWindow/BagWindow.prefab")] +[HFUIWindowLayer(enHFUICanvasLayer.UIWindow, + enHFUIWindowLayer.Dynamic, + isIgnoreCloseByESC = false)] +public class BagWindow : AbsHFUIWindow +{ + // ... +} +``` + +**路径对应关系**: +- 属性路径:`UIWindows/BagWindow/BagWindow.prefab` +- 实际路径:`Assets/Game/GameHFResource/CN/UIWindows/BagWindow/BagWindow.prefab` + +**属性说明**: + +| 属性 | 作用 | 必填 | +|-----|------|------| +| `HFAssetBundlePath` | 指定预制体路径,用于资源加载 | ✅ | +| `HFUIWindowLayer` | 指定窗口层级和行为 | ✅ | +| `isIgnoreCloseByESC` | 是否忽略ESC关闭 | ❌ | + +### 6.3 性能优化建议 + +| 优化项 | 说明 | 实现方式 | +|-------|------|---------| +| **对象池复用** | 频繁创建的UI元素使用对象池 | 使用 `HFSimulateBehaviourPool` | +| **图集打包** | 将小图标打包到SpriteAtlas | 在Unity中配置SpriteAtlas | +| **层级优化** | 合理设置Canvas层级 | 使用 `HFUIWindowLayer` 属性 | +| **避免过度绘制** | 减少重叠UI元素 | 合理设计UI布局 | +| **批量操作** | 使用RectTransform批量修改 | 禁用后批量修改再启用 | +| **列表优化** | 使用SFUI_ScrollRect绑定模式 | 自动复用列表项 | + +--- + +**版本**: v1.0 +**适用范围**: StrayFog框架项目业务开发人员 \ No newline at end of file diff --git a/03_核心功能/UI窗口开发指南.md b/03_核心功能/UI窗口开发指南.md deleted file mode 100644 index 5bdecbc..0000000 --- a/03_核心功能/UI窗口开发指南.md +++ /dev/null @@ -1,228 +0,0 @@ -# StrayFog 框架 UI窗口开发指南 - -## 一、UI窗口基础 - -### 1.1 窗口创建流程 - -```csharp -[HFAssetBundlePath(enHFLanguageRootFolder.ASSETS_GAME_GAMEHFRESOURCE, "UIWindows/Bag/BagWindow.prefab")] -[HFUIWindowLayer(enHFUICanvasLayer.UIWindow, enHFUIWindowLayer.Fixed, isIgnoreCloseByESC = false)] -public class BagWindow : AbsHFUIWindow -{ - // ========== UI组件 ========== - private SFUI_Button BtnClose; - private SFUI_ScrollRect BagListView; - private BagTips tips; - - // ========== 数据 ========== - private List m_items = new List(); - private ItemInfo m_select; - - protected override void OnRunAwake() - { - base.OnRunAwake(); - // ✅ 初始化UI组件引用 - BtnClose = FindUICtrlByName("BtnClose"); - BagListView = FindUICtrlByName("BagListView"); - tips = BindUI("BagTips"); - - // ✅ 按钮事件绑定(带防重复注册保护) - BtnClose.OnAddClickListener -= OnBtnClose; - BtnClose.OnAddClickListener += OnBtnClose; - - // ✅ 列表绑定 - var itemPrefab = FindUICtrlByName("Item"); - BagListView.BindEvent( - () => { return m_items.Count; }, - (idx) => { return itemPrefab.gameObject; }, - OnUpdateItem, - (item) => { return item.gameObject.HFGetOrAddSimulateBehaviour(); } - ); - } - - protected override void OnOpen(Action _onOpenComplete) - { - base.OnOpen(_onOpenComplete); - // ✅ 注册全局事件监听 - HFFunCatalogue.Event.TCEvent.AddListener( - enHFCTCEvent.BagItemUpdate, OnBagItemUpdate); - - // ✅ 初始化数据 - RefreshBagItems(); - } - - protected override void OnClose(Action _onCloseComplete) - { - // ✅ 取消全局事件监听 - HFFunCatalogue.Event.TCEvent.RemoveListener( - enHFCTCEvent.BagItemUpdate, OnBagItemUpdate); - - // ✅ 清理资源 - tips.Clear(); - - base.OnClose(_onCloseComplete); - } - - private void OnBtnClose(GameObject go) => CloseWindow(); - private void OnUpdateItem(SFUI_ScrollRectItem item) { /* 更新列表项 */ } - private void RefreshBagItems() { /* 刷新背包数据 */ } -} -``` - -### 1.2 窗口打开方式 - -```csharp -// 方式1:直接打开(无回调) -HFFunCatalogue.UIManager.OpenWindow(); - -// 方式2:打开并获取窗口实例(推荐) -HFFunCatalogue.UIManager.OpenWindow((win, args) => { - Debug.Log("窗口打开完成"); -}); - -// 方式3:带额外参数打开 -object[] extraArgs = new object[] { "param1", 123 }; -HFFunCatalogue.UIManager.OpenWindow((win, args) => { - // 使用窗口实例 -}, extraArgs); -``` - ---- - -## 二、窗口生命周期 - -### 2.1 生命周期方法 - -| 方法 | 调用时机 | 说明 | 推荐操作 | -|-----|---------|------|---------| -| `OnRunAwake` | 窗口创建时调用一次 | 初始化组件引用 | **绑定按钮事件、列表初始化** | -| `OnOpen` | 每次打开窗口时调用 | 注册事件、刷新数据 | **注册全局TC事件、初始化数据** | -| `OnClose` | 每次关闭窗口时调用 | 取消事件、清理资源 | **取消全局TC事件、清理UI状态** | -| `OnDestroy` | 窗口销毁时调用 | 释放资源 | **释放非托管资源** | - -### 2.2 生命周期流程图 - -``` -窗口创建 - ↓ -OnRunAwake() ──→ 初始化组件、绑定按钮事件 - ↓ -窗口打开(可多次) - ↓ -OnOpen() ──→ 注册TC事件、刷新数据 - ↓ -窗口关闭(可多次) - ↓ -OnClose() ──→ 取消TC事件、清理资源 - ↓ -窗口销毁 - ↓ -OnDestroy() ──→ 释放资源 -``` - ---- - -## 三、窗口配置属性 - -### 3.1 常用属性 - -| 属性 | 说明 | 默认值 | -|-----|------|-------| -| `isIgnoreCloseByESC` | 是否忽略ESC关闭 | false | -| `isCloseOtherWindow` | 是否关闭其他窗口 | false | -| `isNeedMask` | 是否需要遮罩 | true | -| `maskType` | 遮罩类型 | 半透明 | - -### 3.2 层叠配置 - -```csharp -[HFUIWindowLayer(enHFUICanvasLayer.UIWindow, enHFUIWindowLayer.Fixed, isIgnoreCloseByESC = false)] -// ↑ Canvas层级 ↑ 窗口层级 -``` - ---- - -## 四、子组件开发 - -### 4.1 物品槽组件示例 - -```csharp -public class BagItemSlot : AbsHFUIWindow -{ - private SFUI_Button Btn_Item; - private SFUI_Image Img_Icon; - private SFUI_TextMeshProUGUI Txt_Num; - - private Action selectCallback; - private ItemInfo item; - private int m_index; - - protected override void OnRunAwake() - { - base.OnRunAwake(); - Btn_Item = FindUICtrlByName("Btn_Item"); - Img_Icon = FindUICtrlByName("Img_Icon"); - Txt_Num = FindUICtrlByName("Txt_Num"); - - Btn_Item.OnAddClickListener -= OnClick; - Btn_Item.OnAddClickListener += OnClick; - } - - public void SetData(ItemInfo item, ItemInfo nowSelect, int index, Action onSelect) - { - this.item = item; - this.m_index = index; - this.selectCallback = onSelect; - - Img_Icon.HFSetItemIcon(item.ItemConfig.Resource); - Txt_Num.text = item.Info.count.ToString(); - } - - private void OnClick(GameObject go) - { - selectCallback?.Invoke(item, m_index, go.transform.position); - } -} -``` - -### 4.2 提示框组件示例 - -```csharp -public class BagTips : AbsHFUIWindow -{ - private SFUI_Image Img_ItemIcon; - private SFUI_TextMeshProUGUI Txt_ItemName; - private SFUI_TextMeshProUGUI Txt_ItemDesc; - - public ItemInfo Info { get; private set; } - - protected override void OnRunAwake() - { - base.OnRunAwake(); - Img_ItemIcon = FindUICtrlByName("Img_ItemIcon"); - Txt_ItemName = FindUICtrlByName("Txt_ItemName"); - Txt_ItemDesc = FindUICtrlByName("Txt_ItemDesc"); - } - - public void SetData(ItemInfo item) - { - Info = item; - Img_ItemIcon.HFSetItemIcon(item.ItemConfig.Resource); - Txt_ItemName.text = item.ItemConfig.NameCN; - Txt_ItemDesc.text = item.ItemConfig.DesLanguageCN; - } - - public void Clear() - { - Info = null; - Img_ItemIcon.HFClearSprite(); - Txt_ItemName.text = string.Empty; - Txt_ItemDesc.text = string.Empty; - } -} -``` - ---- - -**版本**: v1.1 -**适用范围**: GiftGameX项目业务开发人员 \ No newline at end of file diff --git a/03_核心功能/UI组件使用指南.md b/03_核心功能/UI组件使用指南.md deleted file mode 100644 index 5c366f1..0000000 --- a/03_核心功能/UI组件使用指南.md +++ /dev/null @@ -1,256 +0,0 @@ -# StrayFog 框架 UI组件使用指南 - -## 一、常用UI组件(框架封装) - -### 1.1 SFUI_Button组件 - -```csharp -SFUI_Button btn = GetComponent(); - -// 添加点击事件(带防重复注册保护) -btn.OnAddClickListener -= OnBtnClick; -btn.OnAddClickListener += OnBtnClick; - -// 添加鼠标进入/退出事件 -btn.OnAddEnterListener -= OnBtnEnter; -btn.OnAddEnterListener += OnBtnEnter; - -btn.OnAddExitListener -= OnBtnExit; -btn.OnAddExitListener += OnBtnExit; - -// 设置按钮状态 -btn.SetSelfGray(true); // 设置灰色不可用 -btn.interactable = false; // 设置不可交互 -btn.SetSelected(true); // 设置选中状态 - -void OnBtnClick(GameObject go) { /* 处理点击 */ } -void OnBtnEnter(GameObject go) { /* 鼠标进入 */ } -void OnBtnExit(GameObject go) { /* 鼠标退出 */ } -``` - -### 1.2 SFUI_TextMeshProUGUI组件 - -```csharp -SFUI_TextMeshProUGUI txt = GetComponent(); - -// 设置文本 -txt.text = "Hello World"; - -// 设置颜色 -txt.color = Color.red; - -// 设置字体大小 -txt.fontSize = 24; - -// 设置描边 -txt.outlineColor = Color.black; -txt.outlineWidth = 2; -``` - -### 1.3 SFUI_Image组件 - -```csharp -SFUI_Image img = GetComponent(); - -// 加载Sprite(使用框架封装方法) -img.HFSetItemIcon("Icon_Player"); - -// 加载远程图片 -img.HFSetUrlSprite("https://example.com/icon.png"); - -// 设置透明度 -img.SetAlpha(0.5f); - -// 设置灰度 -img.SetSelfGray(true); - -// 清空Sprite -img.HFClearSprite(); -``` - -### 1.4 SFUI_Toggle组件 - -```csharp -SFUI_Toggle toggle = GetComponent(); - -// 添加状态改变事件 -toggle.onValueChanged.RemoveListener(OnToggleValueChanged); -toggle.onValueChanged.AddListener(OnToggleValueChanged); - -void OnToggleValueChanged(bool isOn) -{ - Debug.Log($"Toggle is {isOn}"); -} -``` - -### 1.5 SFUI_ScrollRect组件(列表绑定模式) - -```csharp -SFUI_ScrollRect scroll = GetComponent(); -List m_items = new List(); - -// ✅ 列表绑定(推荐方式) -scroll.BindEvent( - () => { return m_items.Count; }, // 数据源数量 - (idx) => { return itemPrefab.gameObject; }, // 实例化模板 - OnUpdateItem, // 更新回调 - (item) => { // 组件获取 - return item.gameObject.HFGetOrAddSimulateBehaviour(); - } -); - -// 刷新列表 -scroll.ShowView(); // 显示视图 -scroll.RefreshView(null); // 刷新当前视图 -scroll.ScrollToIndex(0); // 滚动到指定索引 - -// 添加拖拽事件 -scroll.OnAddBeginDragListener -= OnBeginDrag; -scroll.OnAddBeginDragListener += OnBeginDrag; - -void OnUpdateItem(SFUI_ScrollRectItem item) -{ - var slot = item.simulateBehaviour as BagItemSlot; - slot.SetData(m_items[item.dataIdx]); -} - -void OnBeginDrag(GameObject go) { /* 处理拖拽开始 */ } -``` - ---- - -## 二、UI组件命名规范 - -### 2.1 命名规则 - -变量名直接使用组件名,保持与 Unity 编辑器中组件名称一致。 - -| 组件类型 | 示例 | -|---------|-----| -| SFUI_Button | BtnLogin, BtnClose | -| SFUI_TextMeshProUGUI | TxtTitle, TxtNum | -| SFUI_Image | ImgIcon, ImgKuang | -| SFUI_Toggle | ToggleSelect | -| SFUI_ScrollRect | BagListView, ScrollContent | -| SFUI_InputField | InputName, InputPassword | -| SFUI_GridLayoutGroup | GridItemContainer | - -**命名约定**: -- 变量名 = 组件名(保持完全一致) -- 首字母大写,采用 PascalCase 命名风格 -- 前缀说明:Btn(按钮)、Txt(文本)、Img(图片)、Toggle(开关)、Scroll(滚动)、Input(输入框)、Grid(网格) - -### 2.2 层级结构 - -``` -WindowRoot/ -├── bg/ # 背景层 -├── content/ # 内容层 -│ ├── header/ # 头部(标签页、标题) -│ ├── body/ # 主体(列表、内容区) -│ └── footer/ # 底部(操作按钮) -└── top/ # 顶层(弹窗、提示、遮罩) -``` - ---- - -## 三、框架封装组件列表 - -| 组件名 | 基类 | 扩展功能 | -|-------|------|---------| -| `SFUI_Button` | Button | 灰色状态、多事件委托、选中状态 | -| `SFUI_Text` | Text | 描边、阴影扩展 | -| `SFUI_TextMeshProUGUI` | TextMeshProUGUI | 继承原生功能 | -| `SFUI_Image` | Image | 灰度、透明度快捷设置、Sprite加载 | -| `SFUI_Toggle` | Toggle | 状态改变事件 | -| `SFUI_ScrollRect` | ScrollRect | **列表绑定模式、滚动优化** | -| `SFUI_InputField` | InputField | 输入限制 | -| `SFUI_Slider` | Slider | 数值范围限制 | -| `SFUI_Dropdown` | Dropdown | 选项管理 | -| `SFUI_GridLayoutGroup` | GridLayoutGroup | 网格布局 | - ---- - -## 四、UI性能优化 - -### 4.1 优化建议 - -| 优化项 | 说明 | 实现方式 | -|-------|------|---------| -| **对象池复用** | 频繁创建的UI元素使用对象池 | 使用 `HFClassEntityManager` | -| **图集打包** | 将小图标打包到SpriteAtlas | 在Unity中配置SpriteAtlas | -| **层级优化** | 合理设置Canvas层级 | 使用 `HFUIWindowLayer` 属性 | -| **避免过度绘制** | 减少重叠UI元素 | 合理设计UI布局 | -| **批量操作** | 使用RectTransform批量修改 | 禁用后批量修改再启用 | -| **列表优化** | 使用SFUI_ScrollRect绑定模式 | 自动复用列表项 | - -### 4.2 列表性能优化示例 - -```csharp -// ✅ 使用SFUI_ScrollRect绑定模式(自动复用) -BagListView.BindEvent( - () => { return m_items.Count; }, - (idx) => { return itemPrefab.gameObject; }, - OnUpdateItem, - (item) => { return item.gameObject.HFGetOrAddSimulateBehaviour(); } -); - -// ✅ 数据变化时只刷新必要项 -private void OnBagItemUpdate(IHFEventArg arg) -{ - // 只在数据实际变化时刷新 - if (HasDataChanged()) - { - BagListView.ShowView(); - } -} -``` - ---- - -## 五、子组件开发规范 - -### 5.1 子组件模板 - -```csharp -public class CustomSlot : AbsHFUIWindow -{ - // UI组件 - private SFUI_Button Btn_Item; - private SFUI_Image Img_Icon; - - // 数据和回调 - private Action onSelect; - private ItemInfo item; - - protected override void OnRunAwake() - { - base.OnRunAwake(); - Btn_Item = FindUICtrlByName("Btn_Item"); - Img_Icon = FindUICtrlByName("Img_Icon"); - - // 事件绑定(带防重复保护) - Btn_Item.OnAddClickListener -= OnClick; - Btn_Item.OnAddClickListener += OnClick; - } - - public void SetData(ItemInfo item, Action onSelect) - { - this.item = item; - this.onSelect = onSelect; - - // 更新UI - Img_Icon.HFSetItemIcon(item.ItemConfig.Resource); - } - - private void OnClick(GameObject go) - { - onSelect?.Invoke(item); - } -} -``` - ---- - -**版本**: v1.1 -**适用范围**: GiftGameX项目业务开发人员 \ No newline at end of file diff --git a/README.md b/README.md index 7046f73..26d1fa5 100644 --- a/README.md +++ b/README.md @@ -13,11 +13,7 @@ - [事件系统使用指南](03_核心功能/事件系统使用指南.md) - [资源管理使用指南](03_核心功能/资源管理使用指南.md) - [相机系统使用指南](03_核心功能/相机系统使用指南.md) - -**UI开发(组合):** -- [UI窗口开发指南](03_核心功能/UI窗口开发指南.md) - 窗口创建、生命周期、配置 -- [UI组件使用指南](03_核心功能/UI组件使用指南.md) - SFUI_Button/Text/Image等封装组件 -- [UI事件绑定指南](03_核心功能/UI事件绑定指南.md) - 事件委托绑定、CTC事件监听 +- [UI开发指南](03_核心功能/UI开发指南.md) - 窗口开发、组件使用、事件绑定、对象池、开发规范 ### 04_开发流程 - [开发流程指南](04_开发流程/开发流程指南.md)