{"id":21358837,"url":"https://github.com/gameframex/com.gameframex.unity.ui","last_synced_at":"2026-04-30T09:02:07.351Z","repository":{"id":253369989,"uuid":"842347691","full_name":"GameFrameX/com.gameframex.unity.ui","owner":"GameFrameX","description":null,"archived":false,"fork":false,"pushed_at":"2026-03-02T02:59:37.000Z","size":238,"stargazers_count":1,"open_issues_count":1,"forks_count":5,"subscribers_count":1,"default_branch":"main","last_synced_at":"2026-03-02T06:41:38.220Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"C#","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/GameFrameX.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE.md","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2024-08-14T07:01:01.000Z","updated_at":"2026-03-02T02:59:40.000Z","dependencies_parsed_at":"2024-08-16T09:27:22.744Z","dependency_job_id":"ba97f57c-bd4a-401e-b812-473b9be0e3c4","html_url":"https://github.com/GameFrameX/com.gameframex.unity.ui","commit_stats":null,"previous_names":["gameframex/com.gameframex.unity.ui"],"tags_count":23,"template":false,"template_full_name":null,"purl":"pkg:github/GameFrameX/com.gameframex.unity.ui","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/GameFrameX%2Fcom.gameframex.unity.ui","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/GameFrameX%2Fcom.gameframex.unity.ui/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/GameFrameX%2Fcom.gameframex.unity.ui/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/GameFrameX%2Fcom.gameframex.unity.ui/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/GameFrameX","download_url":"https://codeload.github.com/GameFrameX/com.gameframex.unity.ui/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/GameFrameX%2Fcom.gameframex.unity.ui/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":30117464,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-03-05T08:19:04.902Z","status":"ssl_error","status_checked_at":"2026-03-05T08:17:37.148Z","response_time":93,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.5:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-11-22T05:22:35.144Z","updated_at":"2026-03-05T09:01:14.898Z","avatar_url":"https://github.com/GameFrameX.png","language":"C#","funding_links":[],"categories":[],"sub_categories":[],"readme":"﻿# Game Frame X UI\n\n[![License](https://img.shields.io/badge/license-MIT-blue.svg)](LICENSE.md)\n[![Unity Version](https://img.shields.io/badge/unity-2019.4+-green.svg)](https://unity3d.com/get-unity/download)\n[![Version](https://img.shields.io/badge/version-2.0.0-orange.svg)](package.json)\n\n**Game Frame X UI** 是 GameFrameX 框架的 UI 组件，提供了完整的 UI 管理解决方案，支持 UGUI 和 FairyGUI 两种 UI 系统。\n\n## 📋 目录\n\n- [特性](#特性)\n- [安装](#安装)\n- [快速开始](#快速开始)\n- [核心概念](#核心概念)\n- [API 文档](#api-文档)\n- [UI 组层级](#ui-组层级)\n- [事件系统](#事件系统)\n- [最佳实践](#最佳实践)\n- [示例代码](#示例代码)\n- [依赖项](#依赖项)\n- [版本历史](#版本历史)\n- [许可证](#许可证)\n\n## ✨ 特性\n\n- 🎯 **统一的 UI 管理接口** - 支持 UGUI 和 FairyGUI\n- 🏗️ **分层 UI 系统** - 预定义的 UI 组层级管理\n- 🔄 **对象池管理** - 自动回收和复用 UI 实例\n- 📡 **事件驱动** - 完整的 UI 生命周期事件\n- ⚡ **异步加载** - 支持异步 UI 加载和依赖管理\n- 🎨 **灵活配置** - 可配置的 UI 组和辅助器\n- 🔧 **编辑器支持** - 完整的 Unity 编辑器集成\n\n## 📦 安装\n\n### 方式一：Package Manager (推荐)\n\n1. 打开 Unity Package Manager\n2. 点击 \"+\" 按钮，选择 \"Add package from git URL\"\n3. 输入以下 URL：\n   ```\n   https://github.com/gameframex/com.gameframex.unity.ui.git\n   ```\n\n### 方式二：manifest.json\n\n在项目的 `Packages/manifest.json` 文件中添加：\n\n```json\n{\n  \"dependencies\": {\n    \"com.gameframex.unity.ui\": \"https://github.com/gameframex/com.gameframex.unity.ui.git\"\n  }\n}\n```\n\n### 方式三：本地安装\n\n1. 下载或克隆此仓库\n2. 将文件夹放置到项目的 `Packages` 目录下\n3. Unity 会自动识别并加载包\n\n## 🚀 快速开始\n\n### 1. 添加 UI 组件\n\n在场景中创建一个 GameObject 并添加 `UIComponent` 组件：\n\n```csharp\n// 获取 UI 组件\nvar uiComponent = GameEntry.GetComponent\u003cUIComponent\u003e();\n```\n\n### 2. 创建 UI 窗体\n\n```csharp\n// 继承 UIForm 创建自定义 UI\npublic class MainMenuUI : UIForm\n{\n    protected override void OnInit(object userData)\n    {\n        base.OnInit(userData);\n        // 初始化 UI 逻辑\n    }\n\n    protected override void OnOpen(object userData)\n    {\n        base.OnOpen(userData);\n        // UI 打开时的逻辑\n    }\n\n    protected override void OnClose(bool isShutdown, object userData)\n    {\n        base.OnClose(isShutdown, userData);\n        // UI 关闭时的逻辑\n    }\n}\n```\n\n### 3. 打开和关闭 UI\n\n```csharp\n// 打开 UI\nuiComponent.OpenUIForm(\"MainMenuUI\", \"UI/MainMenu\");\n\n// 异步打开 UI\nawait uiComponent.OpenUIFormAsync(\"MainMenuUI\", \"UI/MainMenu\");\n\n// 关闭 UI\nuiComponent.CloseUIForm(\"MainMenuUI\");\n\n// 关闭所有 UI\nuiComponent.CloseAllLoadedUIForms();\n```\n\n## 🏗️ 核心概念\n\n### UI 管理器 (IUIManager)\n\nUI 管理器是整个 UI 系统的核心，负责：\n- UI 窗体的生命周期管理\n- UI 组的管理和层级控制\n- 对象池的管理和回收\n- 事件的分发和处理\n\n### UI 窗体 (UIForm)\n\nUI 窗体是所有 UI 界面的基类，提供：\n- 标准的生命周期方法\n- 可见性控制\n- 暂停和恢复功能\n- 用户数据传递\n\n### UI 组 (UIGroup)\n\nUI 组用于管理 UI 的层级关系，每个组有不同的深度值：\n- 深度值越小，显示层级越高\n- 支持组内 UI 的排序和管理\n- 可配置组的辅助器\n\n## 📚 API 文档\n\n### UIComponent 主要方法\n\n#### 打开 UI 窗体\n\n```csharp\n/// \u003csummary\u003e\n/// 打开界面。\n/// \u003c/summary\u003e\n/// \u003cparam name=\"uiFormAssetName\"\u003e界面资源名称。\u003c/param\u003e\n/// \u003cparam name=\"uiGroupName\"\u003e界面组名称。\u003c/param\u003e\n/// \u003cparam name=\"priority\"\u003e加载界面资源的优先级。\u003c/param\u003e\n/// \u003cparam name=\"pauseCoveredUIForm\"\u003e是否暂停被覆盖的界面。\u003c/param\u003e\n/// \u003cparam name=\"userData\"\u003e用户自定义数据。\u003c/param\u003e\n/// \u003creturns\u003e界面的序列编号。\u003c/returns\u003e\npublic int OpenUIForm(string uiFormAssetName, string uiGroupName, int priority = 0, bool pauseCoveredUIForm = true, object userData = null)\n\n/// \u003csummary\u003e\n/// 异步打开界面。\n/// \u003c/summary\u003e\n/// \u003cparam name=\"uiFormAssetName\"\u003e界面资源名称。\u003c/param\u003e\n/// \u003cparam name=\"uiGroupName\"\u003e界面组名称。\u003c/param\u003e\n/// \u003cparam name=\"priority\"\u003e加载界面资源的优先级。\u003c/param\u003e\n/// \u003cparam name=\"pauseCoveredUIForm\"\u003e是否暂停被覆盖的界面。\u003c/param\u003e\n/// \u003cparam name=\"userData\"\u003e用户自定义数据。\u003c/param\u003e\n/// \u003creturns\u003e界面实例。\u003c/returns\u003e\npublic Task\u003cIUIForm\u003e OpenUIFormAsync(string uiFormAssetName, string uiGroupName, int priority = 0, bool pauseCoveredUIForm = true, object userData = null)\n```\n\n#### 关闭 UI 窗体\n\n```csharp\n/// \u003csummary\u003e\n/// 关闭界面。\n/// \u003c/summary\u003e\n/// \u003cparam name=\"serialId\"\u003e要关闭界面的序列编号。\u003c/param\u003e\n/// \u003cparam name=\"userData\"\u003e用户自定义数据。\u003c/param\u003e\npublic void CloseUIForm(int serialId, object userData = null)\n\n/// \u003csummary\u003e\n/// 关闭界面。\n/// \u003c/summary\u003e\n/// \u003cparam name=\"uiForm\"\u003e要关闭的界面。\u003c/param\u003e\n/// \u003cparam name=\"userData\"\u003e用户自定义数据。\u003c/param\u003e\npublic void CloseUIForm(IUIForm uiForm, object userData = null)\n```\n\n#### 获取 UI 窗体\n\n```csharp\n/// \u003csummary\u003e\n/// 获取界面。\n/// \u003c/summary\u003e\n/// \u003cparam name=\"serialId\"\u003e要获取界面的序列编号。\u003c/param\u003e\n/// \u003creturns\u003e要获取的界面。\u003c/returns\u003e\npublic IUIForm GetUIForm(int serialId)\n\n/// \u003csummary\u003e\n/// 获取界面。\n/// \u003c/summary\u003e\n/// \u003cparam name=\"uiFormAssetName\"\u003e要获取界面的资源名称。\u003c/param\u003e\n/// \u003creturns\u003e要获取的界面。\u003c/returns\u003e\npublic IUIForm GetUIForm(string uiFormAssetName)\n```\n\n### UIForm 生命周期方法\n\n```csharp\n/// \u003csummary\u003e\n/// 界面初始化。\n/// \u003c/summary\u003e\n/// \u003cparam name=\"userData\"\u003e用户自定义数据。\u003c/param\u003e\nprotected virtual void OnInit(object userData) { }\n\n/// \u003csummary\u003e\n/// 界面回收。\n/// \u003c/summary\u003e\nprotected virtual void OnRecycle() { }\n\n/// \u003csummary\u003e\n/// 界面打开。\n/// \u003c/summary\u003e\n/// \u003cparam name=\"userData\"\u003e用户自定义数据。\u003c/param\u003e\nprotected virtual void OnOpen(object userData) { }\n\n/// \u003csummary\u003e\n/// 界面关闭。\n/// \u003c/summary\u003e\n/// \u003cparam name=\"isShutdown\"\u003e是否是关闭界面管理器时触发。\u003c/param\u003e\n/// \u003cparam name=\"userData\"\u003e用户自定义数据。\u003c/param\u003e\nprotected virtual void OnClose(bool isShutdown, object userData) { }\n\n/// \u003csummary\u003e\n/// 界面暂停。\n/// \u003c/summary\u003e\nprotected virtual void OnPause() { }\n\n/// \u003csummary\u003e\n/// 界面暂停恢复。\n/// \u003c/summary\u003e\nprotected virtual void OnResume() { }\n```\n\n## 🎯 UI 组层级\n\n框架预定义了以下 UI 组层级（按深度值排序）：\n\n| 组名 | 深度值 | 描述 |\n|------|--------|------|\n| System | -35 | 系统顶级界面 |\n| Notify | -30 | 通知界面 |\n| Loading | -25 | 加载界面 |\n| Dialogue | -23 | 对话界面 |\n| BlackBoard | -22 | 黑板界面 |\n| Guide | -20 | 引导界面 |\n| Tip | -15 | 提示界面 |\n| Window | -10 | 窗口界面 |\n| Fixed | 0 | 固定界面 |\n| Normal | 10 | 普通界面 |\n| Floor | 15 | 底板界面 |\n| Map | 20 | 地图界面 |\n| Hud | 22 | 头顶界面 |\n| Battle | 25 | 战斗界面 |\n| World | 27 | 世界界面 |\n| Scene | 30 | 场景界面 |\n| Background | 35 | 背景界面 |\n| Hidden | 40 | 隐藏界面 |\n\n## 📡 事件系统\n\n框架提供了完整的 UI 事件系统：\n\n### 事件类型\n\n- `OpenUIFormSuccessEventArgs` - UI 打开成功事件\n- `OpenUIFormFailureEventArgs` - UI 打开失败事件\n- `CloseUIFormCompleteEventArgs` - UI 关闭完成事件\n- `UIFormVisibleChangedEventArgs` - UI 可见性改变事件\n\n### 事件订阅示例\n\n```csharp\n// 订阅 UI 打开成功事件\nGameEntry.Event.Subscribe(OpenUIFormSuccessEventArgs.EventId, OnOpenUIFormSuccess);\n\nprivate void OnOpenUIFormSuccess(object sender, GameEventArgs e)\n{\n    var args = (OpenUIFormSuccessEventArgs)e;\n    Debug.Log($\"UI {args.UIForm.UIFormAssetName} 打开成功\");\n}\n```\n\n## 💡 最佳实践\n\n### 1. UI 资源命名规范\n\n```csharp\n// 推荐的命名方式\n\"UI/MainMenu\"      // 主菜单\n\"UI/Battle/HUD\"    // 战斗 HUD\n\"UI/Shop/ItemList\" // 商店物品列表\n```\n\n### 2. UI 数据传递\n\n```csharp\n// 使用强类型数据类\npublic class ShopUIData\n{\n    public int PlayerId { get; set; }\n    public List\u003cItem\u003e Items { get; set; }\n}\n\n// 打开 UI 时传递数据\nvar shopData = new ShopUIData { PlayerId = 123, Items = itemList };\nuiComponent.OpenUIForm(\"ShopUI\", \"Normal\", userData: shopData);\n\n// 在 UI 中接收数据\nprotected override void OnOpen(object userData)\n{\n    var shopData = userData as ShopUIData;\n    if (shopData != null)\n    {\n        // 使用数据初始化 UI\n    }\n}\n```\n\n### 3. UI 性能优化\n\n```csharp\n// 配置对象池参数\nuiComponent.InstanceCapacity = 16;        // 对象池容量\nuiComponent.InstanceExpireTime = 60f;     // 对象过期时间\nuiComponent.RecycleInterval = 60;         // 回收间隔\n```\n\n## 📝 示例代码\n\n### 完整的 UI 窗体示例\n\n```csharp\nusing GameFrameX.UI.Runtime;\nusing UnityEngine;\nusing UnityEngine.UI;\n\npublic class MainMenuUI : UIForm\n{\n    [SerializeField] private Button startButton;\n    [SerializeField] private Button settingsButton;\n    [SerializeField] private Button exitButton;\n\n    protected override void OnInit(object userData)\n    {\n        base.OnInit(userData);\n        \n        // 绑定按钮事件\n        startButton.onClick.AddListener(OnStartButtonClick);\n        settingsButton.onClick.AddListener(OnSettingsButtonClick);\n        exitButton.onClick.AddListener(OnExitButtonClick);\n    }\n\n    protected override void OnOpen(object userData)\n    {\n        base.OnOpen(userData);\n        \n        // 播放打开动画\n        PlayOpenAnimation();\n    }\n\n    protected override void OnClose(bool isShutdown, object userData)\n    {\n        base.OnClose(isShutdown, userData);\n        \n        // 清理资源\n        CleanupResources();\n    }\n\n    private void OnStartButtonClick()\n    {\n        // 关闭当前 UI 并打开游戏 UI\n        UIComponent.CloseUIForm(this);\n        UIComponent.OpenUIForm(\"GameUI\", \"Normal\");\n    }\n\n    private void OnSettingsButtonClick()\n    {\n        // 打开设置 UI\n        UIComponent.OpenUIForm(\"SettingsUI\", \"Window\");\n    }\n\n    private void OnExitButtonClick()\n    {\n        // 退出游戏\n        Application.Quit();\n    }\n\n    private void PlayOpenAnimation()\n    {\n        // 实现打开动画\n    }\n\n    private void CleanupResources()\n    {\n        // 清理资源\n    }\n}\n```\n\n### UI 管理器使用示例\n\n```csharp\npublic class UIManager : MonoBehaviour\n{\n    private UIComponent uiComponent;\n\n    private void Start()\n    {\n        uiComponent = GameEntry.GetComponent\u003cUIComponent\u003e();\n        \n        // 配置 UI 组件\n        ConfigureUIComponent();\n        \n        // 打开主菜单\n        OpenMainMenu();\n    }\n\n    private void ConfigureUIComponent()\n    {\n        // 设置对象池参数\n        uiComponent.InstanceCapacity = 20;\n        uiComponent.InstanceExpireTime = 120f;\n        uiComponent.RecycleInterval = 60;\n        \n        // 订阅事件\n        GameEntry.Event.Subscribe(OpenUIFormSuccessEventArgs.EventId, OnUIFormOpenSuccess);\n        GameEntry.Event.Subscribe(OpenUIFormFailureEventArgs.EventId, OnUIFormOpenFailure);\n    }\n\n    private async void OpenMainMenu()\n    {\n        try\n        {\n            var mainMenuUI = await uiComponent.OpenUIFormAsync(\"MainMenuUI\", \"Normal\");\n            Debug.Log(\"主菜单打开成功\");\n        }\n        catch (System.Exception ex)\n        {\n            Debug.LogError($\"主菜单打开失败: {ex.Message}\");\n        }\n    }\n\n    private void OnUIFormOpenSuccess(object sender, GameEventArgs e)\n    {\n        var args = (OpenUIFormSuccessEventArgs)e;\n        Debug.Log($\"UI 打开成功: {args.UIForm.UIFormAssetName}\");\n    }\n\n    private void OnUIFormOpenFailure(object sender, GameEventArgs e)\n    {\n        var args = (OpenUIFormFailureEventArgs)e;\n        Debug.LogError($\"UI 打开失败: {args.UIFormAssetName}, 错误: {args.ErrorMessage}\");\n    }\n}\n```\n\n## 🔗 依赖项\n\n此包依赖以下 GameFrameX 组件：\n\n- `com.gameframex.unity` (\u003e= 1.1.1) - 核心框架\n- `com.gameframex.unity.asset` (\u003e= 1.0.6) - 资源管理\n- `com.gameframex.unity.event` (\u003e= 1.0.0) - 事件系统\n- `com.gameframex.unity.localization` (\u003e= 1.0.0) - 本地化支持\n\n## 📋 版本历史\n\n### 2.0.0 (2025-06-12)\n- 重大版本更新\n- 优化 UI 管理器架构\n- 改进对象池性能\n\n### 1.2.7 (2025-06-11)\n- 修复 UI 回收后参数重置问题\n- 优化异步加载性能\n\n查看完整的 [CHANGELOG.md](CHANGELOG.md) 了解详细的版本历史。\n\n## 📄 许可证\n\n本项目采用 MIT 许可证 - 查看 [LICENSE.md](LICENSE.md) 文件了解详情。\n\n## 🤝 贡献\n\n欢迎提交 Issue 和 Pull Request！\n\n## 📞 联系方式\n\n- 文档地址: https://gameframex.doc.alianblank.com\n- 作者: Blank (alianblank@outlook.com)\n- 仓库地址: https://github.com/gameframex/com.gameframex.unity.ui\n\n---\n\n**Game Frame X** - 独立游戏前后端一体化解决方案，独立游戏开发者的圆梦大使。","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fgameframex%2Fcom.gameframex.unity.ui","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fgameframex%2Fcom.gameframex.unity.ui","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fgameframex%2Fcom.gameframex.unity.ui/lists"}