Skip to content

Commit 9840e5f

Browse files
committed
Add ReadMe for UIFramework
1 parent bf96df7 commit 9840e5f

File tree

4 files changed

+268
-0
lines changed

4 files changed

+268
-0
lines changed
Lines changed: 127 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,127 @@
1+
# CycloneGames.UIFramework
2+
3+
<div align="left"><a href="./README.md">English</a> | 简体中文</div>
4+
5+
一个为 Unity 设计的简洁、健壮且数据驱动的 UI 框架,旨在实现可扩展性和易用性。它为管理 UI 窗口、层级和过渡动画提供了清晰的架构,并利用了异步加载和解耦的动画系统。
6+
7+
## 核心架构
8+
9+
该框架由几个关键组件构建而成,它们协同工作,提供了一套全面的 UI 管理解决方案。
10+
11+
### 1. `UIService` (门面)
12+
这是与 UI 系统交互的主要公共 API。游戏逻辑代码应通过 `UIService` 来打开和关闭窗口,从而将底层的复杂性抽象出来。它作为一个清晰的入口点,并负责 `UIManager` 的初始化。
13+
14+
### 2. `UIManager` (核心)
15+
一个持久化的单例,负责协调整个 UI 的生命周期。其职责包括:
16+
- **异步加载**: 使用 `CycloneGames.AssetManagement` 异步加载 `UIWindowConfiguration` 和 UI 预制体。
17+
- **生命周期管理**: 管理 `UIWindow` 实例的创建、销毁和状态转换。
18+
- **资源缓存**: 实现了一个 LRU (最近最少使用) 缓存来存储 UI 预制体,以优化重开常用窗口时的性能。
19+
- **实例化节流**: 限制每帧实例化的 UI 元素数量,以防止性能峰值。
20+
21+
### 3. `UIRoot` & `UILayer` (场景层级)
22+
- **`UIRoot`**: 场景中必需的组件,作为所有 UI 元素的根节点。它包含 UI 相机并管理所有的 `UILayer`
23+
- **`UILayer`**: 代表一个独立的渲染和输入层级(例如 `Menu`, `Dialogue`, `Notification`)。窗口被添加到特定的层级中,由层级控制其排序顺序和分组。`UILayer` 通过 `ScriptableObject` 资产进行配置。
24+
25+
### 4. `UIWindow` (UI 单元)
26+
所有 UI 面板、页面或弹窗的基类。每个 `UIWindow` 都是一个自包含的组件,拥有自己的行为和生命周期,由一个健壮的状态机管理:
27+
- **`Opening`**: 窗口正在被创建,其打开过渡动画正在播放。
28+
- **`Opened`**: 窗口完全可见并可交互。
29+
- **`Closing`**: 窗口的关闭过渡动画正在播放。
30+
- **`Closed`**: 窗口已隐藏并准备被销毁。
31+
32+
### 5. `UIWindowConfiguration` (数据驱动配置)
33+
一个 `ScriptableObject`,用于定义 `UIWindow` 的属性。这种数据驱动的方法将配置与代码解耦,使设计师能够轻松修改 UI 行为而无需接触脚本。关键属性包括:
34+
- 需要实例化的 UI 预制体。
35+
- 窗口所属的 `UILayer`
36+
37+
### 6. `IUIWindowTransitionDriver` (解耦的动画)
38+
一个接口,定义了窗口在打开和关闭时的动画方式。这个强大的抽象允许您使用任何动画系统(如 Unity Animator, LitMotion, DOTween)来实现过渡逻辑,并将其应用于窗口,而无需修改其核心逻辑。
39+
40+
## 特性
41+
42+
- **原生异步**: 所有资源加载和实例化操作都使用 `UniTask` 完全异步执行,确保流畅、无阻塞的用户体验。
43+
- **数据驱动**: 使用 `ScriptableObject` 资产配置窗口和层级,以实现最大的灵活性和设计师友好性。
44+
- **健壮的状态管理**: 通过正式的状态机管理每个 `UIWindow` 的生命周期,防止常见的错误和竞态条件。
45+
- **可扩展的动画系统**: 轻松为窗口创建和分配自定义的过渡动画。
46+
- **面向服务的架构**: 与 `AssetManagement`, `Factory`, `Logger` 等其他服务无缝集成,接口编程可以完美兼容各 DI/IoC 框架。
47+
- **注重性能**: 包含预制体缓存和实例化节流等功能,以保持高性能。
48+
49+
## 依赖项
50+
51+
- `com.cysharp.unitask`
52+
- `com.cyclone-games.assetmanagement`
53+
- `com.cyclone-games.factory`
54+
- `com.cyclone-games.logger`
55+
- `com.cyclone-games.service`
56+
57+
## 快速上手指南
58+
59+
### 1. 场景设置
60+
1. 找到模块中的 `UIFramework.prefab` 预制体,将其加载或直接放进场景,其中已包含了基础的 UIRoot,UICamera,以及默认层级
61+
62+
### 2. 创建 `UILayer` 配置
63+
1. 在项目窗口中,右键单击并选择 **Create > CycloneGames > UIFramework > UILayer Configuration**
64+
2. 为您需要的每个层级创建配置,例如:
65+
- `UILayer_Menu`
66+
- `UILayer_Dialogue`
67+
- `UILayer_Notification`
68+
3. 将这些 `UILayer` 资产分配到 Inspector 中 `UIRoot``Layer Configurations` 列表中。
69+
70+
### 3. 创建 `UIWindow`
71+
1. **创建脚本**: 创建一个新的 C# 脚本,继承自 `UIWindow`。例如,`MainMenuWindow.cs`
72+
```csharp
73+
using CycloneGames.UIFramework.Runtime;
74+
75+
public class MainMenuWindow : UIWindow
76+
{
77+
// 在此处添加对您的 UI 元素(按钮、文本等)的引用
78+
}
79+
```
80+
2. **创建预制体**: 在场景中创建一个新的 UI `Canvas` 或 `Panel`。将其根 `GameObject` 添加 `MainMenuWindow` 组件。设计您的 UI,然后将其另存为预制体。
81+
3. **创建配置**: 在项目窗口中右键单击,选择 **Create > CycloneGames > UIFramework > UIWindow Configuration**
82+
- 为其指定一个描述性的名称,如 `UIWindow_MainMenu`。
83+
- 将您的 `MainMenuWindow` 预制体分配给 `Window Prefab` 字段。
84+
- 将适当的 `UILayer`(例如 `UILayer_Menu`)分配给 `Layer` 字段。
85+
86+
### 4. 初始化并使用 `UIService`
87+
在游戏的启动或初始化逻辑中,创建并初始化 `UIService`。
88+
89+
```csharp
90+
using CycloneGames.UIFramework.Runtime;
91+
using Cysharp.Threading.Tasks;
92+
using UnityEngine;
93+
94+
public class GameInitializer : MonoBehaviour
95+
{
96+
private IUIService uiService;
97+
98+
async void Start()
99+
{
100+
// 假设其他服务(资产管理、工厂等)已经初始化
101+
// 并可通过服务定位器或依赖注入获得。
102+
var assetPathBuilderFactory = ...; // 从您的 DI 容器获取
103+
var objectSpawner = ...; // 从您的 DI 容器获取
104+
var mainCameraService = ...; // 从您的 DI 容器获取
105+
106+
uiService = new UIService();
107+
uiService.Initialize(assetPathBuilderFactory, objectSpawner, mainCameraService);
108+
109+
// 现在您可以使用该服务了
110+
OpenMainMenu();
111+
}
112+
113+
public async UniTask OpenMainMenu()
114+
{
115+
// "UIWindow_MainMenu" 是您的 UIWindowConfiguration 资产的文件名
116+
UIWindow window = await uiService.OpenUIAsync("UIWindow_MainMenu");
117+
if (window is MainMenuWindow mainMenu)
118+
{
119+
// 与您的特定窗口实例进行交互
120+
}
121+
}
122+
123+
public void CloseMainMenu()
124+
{
125+
uiService.CloseUI("UIWindow_MainMenu");
126+
}
127+
}

UnityStarter/Assets/ThirdParty/CycloneGames/CycloneGames.UIFramework/README.SCH.md.meta

Lines changed: 7 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.
Lines changed: 127 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,127 @@
1+
# CycloneGames.UIFramework
2+
3+
<div align="left">English | <a href="./README.SCH.md">简体中文</a></div>
4+
5+
A simple, robust, and data-driven UI framework for Unity, designed for scalability and ease of use. It provides a clear architecture for managing UI windows, layers, and transitions, leveraging asynchronous loading and a decoupled animation system.
6+
7+
## Core Architecture
8+
9+
The framework is built upon several key components that work together to provide a comprehensive UI management solution.
10+
11+
### 1. `UIService` (The Facade)
12+
This is the primary public API for interacting with the UI system. Game code should use the `UIService` to open and close windows, abstracting away the underlying complexity. It acts as a clean entry point and handles the initialization of the `UIManager`.
13+
14+
### 2. `UIManager` (The Core)
15+
A persistent singleton that orchestrates the entire UI lifecycle. Its responsibilities include:
16+
- **Asynchronous Loading**: Loads `UIWindowConfiguration` and UI prefabs using `CycloneGames.AssetManagement`.
17+
- **Lifecycle Management**: Manages the creation, destruction, and state transitions of `UIWindow` instances.
18+
- **Resource Caching**: Implements an LRU cache for UI prefabs to optimize performance when reopening frequently used windows.
19+
- **Instantiation Throttling**: Limits the number of UI elements instantiated per frame to prevent performance spikes.
20+
21+
### 3. `UIRoot` & `UILayer` (Scene Hierarchy)
22+
- **`UIRoot`**: A required component in your scene that acts as the root for all UI elements. It contains the UI Camera and manages all `UILayer`s.
23+
- **`UILayer`**: Represents a distinct rendering and input layer (e.g., `Menu`, `Dialogue`, `Notification`). Windows are added to specific layers, which control their sorting order and grouping. `UILayer`s are configured via `ScriptableObject` assets.
24+
25+
### 4. `UIWindow` (The UI Unit)
26+
The base class for all UI panels, pages, or popups. Each `UIWindow` is a self-contained component with its own behavior and lifecycle, managed by a robust state machine:
27+
- **`Opening`**: The window is being created and its opening transition is playing.
28+
- **`Opened`**: The window is fully visible and interactive.
29+
- **`Closing`**: The window's closing transition is playing.
30+
- **`Closed`**: The window is hidden and ready to be destroyed.
31+
32+
### 5. `UIWindowConfiguration` (Data-Driven Configuration)
33+
A `ScriptableObject` that defines the properties of a `UIWindow`. This data-driven approach decouples configuration from code, allowing designers to easily modify UI behavior without touching scripts. Key properties include:
34+
- The UI prefab to instantiate.
35+
- The `UILayer` the window belongs to.
36+
37+
### 6. `IUIWindowTransitionDriver` (Decoupled Animations)
38+
An interface that defines how a window animates when opening and closing. This powerful abstraction allows you to implement transition logic using any animation system (e.g., Unity Animator, LitMotion, DOTween) and apply it to windows without modifying their core logic.
39+
40+
## Features
41+
42+
- **Asynchronous by Design**: All resource loading and instantiation operations are fully asynchronous using `UniTask`, ensuring a smooth, non-blocking user experience.
43+
- **Data-Driven**: Configure windows and layers with `ScriptableObject` assets for maximum flexibility and designer-friendliness.
44+
- **Robust State Management**: A formal state machine manages the lifecycle of each `UIWindow`, preventing common bugs and race conditions.
45+
- **Extensible Animation System**: Easily create and assign custom transition animations for windows.
46+
- **Service-Based Architecture**: Integrates seamlessly with other services like `AssetManagement`, `Factory`, and `Logger`. Perfectly compatible with DI/IoC.
47+
- **Performance-Minded**: Includes features like prefab caching and instantiation throttling to maintain high performance.
48+
49+
## Dependencies
50+
51+
- `com.cysharp.unitask`
52+
- `com.cyclone-games.assetmanagement`
53+
- `com.cyclone-games.factory`
54+
- `com.cyclone-games.logger`
55+
- `com.cyclone-games.service`
56+
57+
## Quick Start Guide
58+
59+
### 1. Scene Setup
60+
1. Find the `UIFramework.prefab` in package, place it in the scene or load it runtime, the `UIFramework.prefab` already contains UIRoot, UICamera,default Layers.
61+
62+
### 2. Create `UILayer` Configurations
63+
1. In the Project window, right-click and select **Create > CycloneGames > UIFramework > UILayer Configuration**.
64+
2. Create configurations for each layer you need, for example:
65+
- `UILayer_Menu`
66+
- `UILayer_Dialogue`
67+
- `UILayer_Notification`
68+
3. Assign these `UILayer` assets to the `UIRoot`'s `Layer Configurations` list in the Inspector.
69+
70+
### 3. Create a `UIWindow`
71+
1. **Create the Script**: Create a new C# script that inherits from `UIWindow`. For example, `MainMenuWindow.cs`.
72+
```csharp
73+
using CycloneGames.UIFramework.Runtime;
74+
75+
public class MainMenuWindow : UIWindow
76+
{
77+
// Add references to your UI elements (buttons, text, etc.) here
78+
}
79+
```
80+
2. **Create the Prefab**: Create a new UI `Canvas` or `Panel` in your scene. Add your `MainMenuWindow` component to its root `GameObject`. Design your UI, then save it as a prefab.
81+
3. **Create the Configuration**: Right-click in the Project window and select **Create > CycloneGames > UIFramework > UIWindow Configuration**.
82+
- Name it something descriptive, like `UIWindow_MainMenu`.
83+
- Assign your `MainMenuWindow` prefab to the `Window Prefab` field.
84+
- Assign the appropriate `UILayer` (e.g., `UILayer_Menu`) to the `Layer` field.
85+
86+
### 4. Initialize and Use the `UIService`
87+
In your game's bootstrap or initialization logic, create and initialize the `UIService`.
88+
89+
```csharp
90+
using CycloneGames.UIFramework.Runtime;
91+
using Cysharp.Threading.Tasks;
92+
using UnityEngine;
93+
94+
public class GameInitializer : MonoBehaviour
95+
{
96+
private IUIService uiService;
97+
98+
async void Start()
99+
{
100+
// Assume other services (asset management, factory, etc.) are already initialized
101+
// and available through a service locator or dependency injection.
102+
var assetPathBuilderFactory = ...; // Get from your DI container
103+
var objectSpawner = ...; // Get from your DI container
104+
var mainCameraService = ...; // Get from your DI container
105+
106+
uiService = new UIService();
107+
uiService.Initialize(assetPathBuilderFactory, objectSpawner, mainCameraService);
108+
109+
// Now you can use the service
110+
OpenMainMenu();
111+
}
112+
113+
public async UniTask OpenMainMenu()
114+
{
115+
// "UIWindow_MainMenu" is the filename of your UIWindowConfiguration asset
116+
UIWindow window = await uiService.OpenUIAsync("UIWindow_MainMenu");
117+
if (window is MainMenuWindow mainMenu)
118+
{
119+
// Interact with your specific window instance
120+
}
121+
}
122+
123+
public void CloseMainMenu()
124+
{
125+
uiService.CloseUI("UIWindow_MainMenu");
126+
}
127+
}

UnityStarter/Assets/ThirdParty/CycloneGames/CycloneGames.UIFramework/README.md.meta

Lines changed: 7 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)