【重构】整理文档目录结构,创建5个分类文件夹,拆分业务开发指南为8个独立文档,添加README入口导航

This commit is contained in:
Shiliang
2026-05-22 10:41:34 +08:00
parent 4139f8d392
commit e4198ddd16
13 changed files with 710 additions and 567 deletions

View File

@@ -0,0 +1,106 @@
# StrayFog 框架开发规范指南
## 一、开发前准备
### 1.1 核心概念理解
#### 1.1.1 框架层级关系
```
┌─────────────────────────────────────────────────────────────┐
│ 开发层级视图 │
├─────────────────────────────────────────────────────────────┤
│ 业务层 (你开发的代码) │
│ ├── UI界面、业务逻辑、游戏数据 │
│ │ │
│ │ ┌───────────────────────────────────────────────────┐ │
│ │ │ 核心库 (只读,框架团队维护) │ │
│ │ │ ├── Core: 模拟行为、全局数据 │ │
│ │ │ ├── HF: 资源管理、事件系统、相机管理 │ │
│ │ │ └── General: 状态机、工具类 │ │
│ │ └───────────────────────────────────────────────────┘ │
│ │ │
│ └─────────────────────────────────────────────────────────┘ │
└─────────────────────────────────────────────────────────────┘
```
#### 1.1.2 核心库访问原则
| 原则 | 说明 |
|-----|-----|
| **只读访问** | 核心库代码只可读取,不可修改 |
| **接口优先** | 通过接口访问服务,而非直接实例化实现类 |
| **继承扩展** | 通过继承抽象类实现自定义逻辑 |
| **依赖注入** | 通过管理器获取实例,而非硬编码 |
---
## 二、业务代码结构
### 2.1 目录组织规范
```
Assets/Game/GameHFScripte/GameFunction/
├── Event/ # 消息处理
│ ├── ServerToClient/ # 服务器到客户端消息
│ ├── ClientToClient/ # 客户端内部消息
│ └── Handle/ # 消息处理器
├── GameRoot/ # 框架调用入口
│ ├── HFGameStart.cs # 热更新进入入口
│ ├── HFFunCatalogue.cs # 框架统一调用入口
│ ├── HFFunCatalogue_Function.cs # 功能调用方法
│ └── ...
├── HFDownLoadSubPackage/ # 分包下载
│ ├── HFSubPackageManager.cs # 分包管理器
│ ├── HFGameStartAssetsCheckManager.cs # 资源检查
│ └── ...
├── HFExtends/ # Class扩展方法
│ ├── UI/ # UI扩展
│ ├── Material/ # 材质扩展
│ ├── String/ # 字符串扩展
│ └── ...
├── Logic/ # 游戏主要业务逻辑存放各功能Manager
│ ├── User/ # 用户相关
│ ├── Login/ # 登录系统
│ ├── Fight/ # 战斗系统
│ ├── CardDeck/ # 卡组系统
│ ├── Bag/ # 背包系统
│ └── ...
├── UIWindows/ # UI窗口业务逻辑
│ ├── Login/ # 登录窗口
│ ├── Lobby/ # 大厅窗口
│ ├── Fight/ # 战斗窗口
│ ├── Shop/ # 商店窗口
│ └── ...
├── GameEntity/ # 游戏实体
│ ├── Entity/ # 实体定义
│ ├── EntityPool/ # 实体对象池
│ └── ...
├── SoundManagerPro/ # 音效管理
├── SceneManager/ # 场景管理
├── SDK/ # SDK集成
└── MonoCompent/ # Mono组件
```
### 2.2 文件命名规范
| 文件类型 | 命名规则 | 示例 |
|---------|---------|-----|
| **窗口类** | `XXXWindow.cs` | `LoginWindow.cs` |
| **组件类** | `XXXComponent.cs` | `ItemCellComponent.cs` |
| **管理器类** | `XXXManager.cs` | `UIManager.cs` |
| **数据类** | `XXXData.cs` | `PlayerData.cs` |
| **配置类** | `XXXConfig.cs` | `SkillConfig.cs` |
---
**版本**: v1.0
**生效日期**: 2026年
**适用范围**: GiftGameX项目业务开发人员

View File

@@ -0,0 +1,151 @@
# StrayFog 框架事件系统使用指南
## 一、事件系统概述
事件系统分为两类:
- **STCEvent**Server To Client服务器到客户端消息
- **CTCEvent**Client To Client客户端内部消息
---
## 二、定义事件
### 2.1 定义事件枚举和参数
```csharp
// 事件ID枚举
public enum GameEventId
{
PlayerLevelUp,
EnemyKilled,
GoldChanged
}
// 事件参数基类
public class GameEventArgs : IHFEventArg<GameEventId>, IHFRecycle
{
public GameEventId eventId { get; set; }
public void Recycle()
{
// 重置状态
eventId = default;
}
}
// 具体事件参数
public class PlayerLevelUpEventArgs : GameEventArgs
{
public int playerId;
public int oldLevel;
public int newLevel;
}
```
---
## 三、UI窗口事件监听
### 3.1 在窗口中注册CTCEvent
```csharp
[HFAssetBundlePath(enHFLanguageRootFolder.ASSETS_GAME_GAMEHFRESOURCE, "UIWindows/CardDeck/CardDeckWindow.prefab")]
[HFUIWindowLayer(enHFUICanvasLayer.UIWindow, enHFUIWindowLayer.Dynamic, isIgnoreCloseByESC = false)]
public class CardDeckWindow : AbsHFUIWindow
{
protected override void OnOpen(Action _onOpenComplete)
{
base.OnOpen(_onOpenComplete);
// 注册客户端内部消息监听CTCEvent
HFFunCatalogue.Event.CTCEvent.AddListener<HFEvent_CTC_CardUpdate>(enHFCTCEvent.CardUpdate, OnCardUpdate);
}
protected override void OnClose(Action _onCloseComplete)
{
base.OnClose(_onCloseComplete);
// 取消客户端内部消息监听
HFFunCatalogue.Event.CTCEvent.RemoveListener<HFEvent_CTC_CardUpdate>(enHFCTCEvent.CardUpdate, OnCardUpdate);
}
void OnCardUpdate(HFEventArgBase arg)
{
HFEvent_CTC_CardUpdate cardArg = arg as HFEvent_CTC_CardUpdate;
// 更新卡组UI显示
}
}
```
> **注意**UI窗口中**不监听服务器事件STCEvent**服务器事件应在Logic层的Manager中监听。
---
## 四、Manager事件监听
### 4.1 使用AbsHFSingleMonoBehaviour需要Update
```csharp
public class PlayerManager : AbsHFSingleMonoBehaviour<PlayerManager>
{
protected override int[] simulateBehaviourEvents => new int[]
{
enHFSimulateBehaviourEvent.Mono_Update,
enHFSimulateBehaviourEvent.Mono_FixedUpdate
};
protected override void OnAfterCreateInstance()
{
base.OnAfterCreateInstance();
RegisterServerEvents();
}
void RegisterServerEvents()
{
HFFunCatalogue.Event.STCEvent.AddListener<HFEvent_STC_PlayerInfo>(enHFSTCEvent.PlayerInfo, OnPlayerInfo);
}
void OnPlayerInfo(HFEventArgBase arg)
{
HFEvent_STC_PlayerInfo info = arg as HFEvent_STC_PlayerInfo;
// 处理服务器返回的玩家信息
// 触发客户端事件通知UI更新
HFEvent_CTC_PlayerLevelUp evt = HFFunCatalogue.New<HFEvent_CTC_PlayerLevelUp>();
evt.playerId = info.playerId;
evt.newLevel = info.level;
HFFunCatalogue.Event.CTCEvent.Dispatch(evt);
}
}
```
### 4.2 使用AbsHFSingleRunTime纯逻辑
```csharp
public class ConfigManager : AbsHFSingleRunTime<ConfigManager>
{
protected override void OnAfterCreateInstance()
{
base.OnAfterCreateInstance();
// 加载配置表
LoadConfigTables();
}
void LoadConfigTables()
{
// 加载配置数据
}
}
```
---
## 五、Manager类型对比
| 类型 | 说明 | 适用场景 |
|-----|------|---------|
| `AbsHFSingleMonoBehaviour` | 生成GameObject可注册MonoBehaviour事件 | 需要Update/FixedUpdate等生命周期 |
| `AbsHFSingleRunTime` | 纯内存单例无GameObject | 不需要生命周期事件 |
---
**版本**: v1.0
**生效日期**: 2026年
**适用范围**: GiftGameX项目业务开发人员

View File

@@ -0,0 +1,101 @@
# StrayFog 框架对象池使用指南
## 一、GameObject对象池
### 1.1 基本用法
```csharp
public class BulletManager : MonoBehaviour
{
[SerializeField] private GameObject bulletPrefab;
private HFObjectMemPool m_BulletPool;
void Awake()
{
// 创建对象池
m_BulletPool = new HFObjectMemPool(bulletPrefab, transform);
}
public void Fire(Vector3 position, Quaternion rotation)
{
bool isNew;
GameObject bullet = m_BulletPool.GetItem(out isNew);
bullet.transform.position = position;
bullet.transform.rotation = rotation;
// 如果是新创建的对象,初始化组件
if (isNew)
{
bullet.GetComponent<BulletComponent>().Initialize();
}
}
public void RecycleBullet(GameObject bullet)
{
m_BulletPool.GiveBack(bullet);
}
void OnDestroy()
{
// 清理对象池
m_BulletPool.Recycle();
}
}
```
---
## 二、脚本对象池
### 2.1 基本用法
```csharp
public class EventArgPool : MonoBehaviour
{
private HFScriptMemPool<GameEventArgs> m_ArgPool;
void Awake()
{
m_ArgPool = new HFScriptMemPool<GameEventArgs>();
}
public GameEventArgs GetEventArgs(GameEventId eventId)
{
bool isNew;
GameEventArgs arg = m_ArgPool.GetItem(out isNew);
arg.eventId = eventId;
return arg;
}
public void RecycleEventArgs(GameEventArgs arg)
{
m_ArgPool.GiveBack(arg);
}
}
```
---
## 三、使用注意事项
### 3.1 对象池设计特点
| 特性 | 说明 |
|-----|-----|
| **双池结构** | 空闲池 + 使用池,高效管理对象状态 |
| **内存泄漏检测** | 归还时校验来源,及时发现问题 |
| **泛型支持** | `HFScriptMemPool<T>` 提供类型安全 |
| **Mono支持** | 自动创建GameObject无缝集成Unity |
### 3.2 性能优化建议
- 频繁创建销毁的对象必须使用对象池
- 合理设置对象池初始容量
- 定期清理空闲对象避免内存泄漏
---
**版本**: v1.0
**生效日期**: 2026年
**适用范围**: GiftGameX项目业务开发人员

View File

@@ -0,0 +1,86 @@
# StrayFog 框架相机系统使用指南
## 一、创建自定义相机
### 1.1 继承AbsHFCameraItem
```csharp
public class UIOverlayCamera : AbsHFCameraItem
{
[SerializeField] private Camera uiCamera;
[SerializeField] private int weight = 10;
public override Camera CameraItem => uiCamera;
public override int Weight => weight;
protected override void OnInitialize()
{
base.OnInitialize();
// 自定义初始化逻辑
uiCamera.clearFlags = CameraClearFlags.Depth;
uiCamera.depth = 100;
}
}
```
---
## 二、管理相机堆栈
### 2.1 使用相机管理器
```csharp
public class CameraController : MonoBehaviour
{
void Start()
{
// 获取相机管理器
HFCameraManager cameraMgr = HFCameraManager.Instance;
// 添加自定义相机
UIOverlayCamera uiCamera = GetComponent<UIOverlayCamera>();
cameraMgr.AddCamera(uiCamera);
// 获取主相机
Camera mainCam = cameraMgr.mainCamera.MainCamera;
}
void OnDestroy()
{
UIOverlayCamera uiCamera = GetComponent<UIOverlayCamera>();
HFCameraManager.Instance.RemoveCamera(uiCamera);
}
}
```
### 2.2 相机堆栈架构
```
相机层级架构:
HFMainCamera (主相机)
├── CameraStack (相机堆栈)
│ ├── CameraItem1 (Weight=10)
│ ├── CameraItem2 (Weight=20)
│ └── CameraItem3 (Weight=5)
└── 按Weight排序 → 渲染顺序控制
```
---
## 三、相机管理API
### 3.1 常用方法
| 方法 | 说明 |
|-----|------|
| `AddCamera()` | 添加相机到堆栈 |
| `RemoveCamera()` | 从堆栈移除相机 |
| `GetCamera()` | 获取指定相机 |
---
**版本**: v1.0
**生效日期**: 2026年
**适用范围**: GiftGameX项目业务开发人员

View File

@@ -0,0 +1,86 @@
# StrayFog 框架资源管理使用指南
## 一、AssetBundle资源加载
### 1.1 加载资源示例
```csharp
public class ResourceLoader : MonoBehaviour
{
public void LoadPlayerModel(int resId, Action<GameObject> onLoaded)
{
// 通过HFFunCatalogue统一入口加载资源
// resId: 从Res配置表中读取的资源ID
HFFunCatalogue.Asset.LoadAsset(resId, (res, obj) =>
{
if (obj != null)
{
GameObject model = res.GetAsset<GameObject>();
onLoaded?.Invoke(model);
}
else
{
Debug.LogError($"加载失败: resId={resId}");
}
});
}
}
```
### 1.2 实体资源加载示例
```csharp
// 在Entity中加载资源
HFFunCatalogue.Asset.LoadAsset(data.EntityRes.Id, (res, obj) => {
if (!entity.isDeath)
{
var Boddy = res.GetAsset<GameObject>();
data.SetBoddy(Boddy);
}
});
```
---
## 二、资源管理API
### 2.1 常用方法
| 类别 | 管理器 | 常用方法 |
|-----|-------|---------|
| **资源** | `HFABMgr` | `LoadAsset()`, `OnStartLoad()` |
### 2.2 资源加载流程
```
资源加载流程:
OnStartLoad(request)
检查缓存 → 获取/创建 HFAssetLoader
loader.AddRequest(request)
loader.LoadAsset() → 异步加载
加载完成 → 回调处理
```
---
## 三、资源管理注意事项
### 3.1 性能优化建议
- 及时释放不再使用的资源
- 使用异步加载避免卡顿
- 合理使用资源缓存
---
**版本**: v1.0
**生效日期**: 2026年
**适用范围**: GiftGameX项目业务开发人员

View File

@@ -0,0 +1,46 @@
# StrayFog 框架常见问题指南
## 一、常见问题解答
### 1.1 如何扩展核心库功能?
通过继承抽象类或实现接口来扩展,不要直接修改核心库代码。
### 1.2 核心库有Bug怎么办
提交Issue到框架团队由框架团队修复并发布新版本。
### 1.3 如何获取核心库的最新版本?
关注内部通知,定期更新核心库引用。
### 1.4 如何调试核心库代码?
可以设置断点调试,但不允许修改代码。
---
## 附录
### A. 常用核心库API
| 类别 | 管理器 | 常用方法 |
|-----|-------|---------|
| **对象池** | `HFObjectMemPool` | `GetItem()`, `GiveBack()` |
| **事件** | `IHFEventHandle` | `AddListener()`, `Dispatch()` |
| **资源** | `HFABMgr` | `OnStartLoad()` |
| **相机** | `HFCameraManager` | `AddCamera()`, `GetCamera()` |
### B. 核心库只读目录
```
Assets/StrayFog/Core/
Assets/Game/GameHFScripte/CopyToHF/
Assets/Game/GameGeneralScripte/
```
---
**版本**: v1.0
**生效日期**: 2026年
**适用范围**: GiftGameX项目业务开发人员

View File

@@ -0,0 +1,45 @@
# StrayFog 框架开发流程指南
## 一、需求分析
### 1.1 需求分析步骤
1. **明确需求**:理解业务需求,确定需要实现的功能
2. **评估复杂度**:判断是否需要核心库支持或扩展
3. **设计方案**:规划代码结构和调用关系
---
## 二、代码编写
### 2.1 代码编写步骤
1. **创建目录**:在`GameBusiness`下创建对应模块目录
2. **编写代码**遵循编码规范使用核心库提供的API
3. **测试验证**在Unity中测试功能正确性
---
## 三、代码审查
### 3.1 代码审查流程
1. **自我检查**:检查是否符合规范,是否有潜在问题
2. **团队审查**:提交代码进行团队审查
3. **修复问题**:根据审查意见修改代码
---
## 四、集成测试
### 4.1 测试阶段
1. **模块测试**:测试单个模块功能
2. **集成测试**:测试模块间交互
3. **回归测试**:确保不影响现有功能
---
**版本**: v1.0
**生效日期**: 2026年
**适用范围**: GiftGameX项目业务开发人员

View File

@@ -0,0 +1,49 @@
# StrayFog 框架最佳实践指南
## 一、性能优化
### 1.1 对象池使用
- 频繁创建销毁的对象必须使用对象池
- 合理设置对象池初始容量
- 定期清理空闲对象避免内存泄漏
### 1.2 资源管理
- 及时释放不再使用的资源
- 使用异步加载避免卡顿
- 合理使用资源缓存
---
## 二、代码组织
### 2.1 单一职责
- 每个类只负责一个功能
- 避免庞大的God类
### 2.2 依赖管理
- 通过管理器获取依赖,而非硬编码
- 使用接口解耦依赖关系
---
## 三、错误处理
### 3.1 异常捕获
- 在关键路径添加异常处理
- 记录错误日志便于排查
### 3.2 防御性编程
- 检查参数合法性
- 处理空引用情况
---
**版本**: v1.0
**生效日期**: 2026年
**适用范围**: GiftGameX项目业务开发人员

40
README.md Normal file
View File

@@ -0,0 +1,40 @@
# UnityAI - StrayFog框架文档中心
## 📋 文档索引
### 01_框架架构
- [StrayFog框架架构分析](01_框架架构/StrayFog框架架构分析.md)
### 02_开发规范
- [开发规范指南](02_开发规范/开发规范指南.md)
### 03_核心功能
- [对象池使用指南](03_核心功能/对象池使用指南.md)
- [事件系统使用指南](03_核心功能/事件系统使用指南.md)
- [资源管理使用指南](03_核心功能/资源管理使用指南.md)
- [相机系统使用指南](03_核心功能/相机系统使用指南.md)
### 04_开发流程
- [开发流程指南](04_开发流程/开发流程指南.md)
- [最佳实践指南](04_开发流程/最佳实践指南.md)
- [常见问题指南](04_开发流程/常见问题指南.md)
### 05_项目管理
- [核心库保护规范](05_项目管理/核心库保护规范.md)
- [Git规定指南](05_项目管理/Git规定指南.md)
---
## 🎯 快速入门
| 场景 | 推荐文档 |
|-----|---------|
| 新人开发 | `02_开发规范/开发规范指南.md` |
| 使用对象池 | `03_核心功能/对象池使用指南.md` |
| 使用事件系统 | `03_核心功能/事件系统使用指南.md` |
| 遇到问题 | `04_开发流程/常见问题指南.md` |
---
**版本**: v1.0
**适用项目**: GiftGameX

View File

@@ -1,567 +0,0 @@
# StrayFog 框架业务开发指南
## 一、开发前准备
### 1.1 核心概念理解
#### 1.1.1 框架层级关系
```
┌─────────────────────────────────────────────────────────────┐
│ 开发层级视图 │
├─────────────────────────────────────────────────────────────┤
│ 业务层 (你开发的代码) │
│ ├── UI界面、业务逻辑、游戏数据 │
│ │ │
│ │ ┌───────────────────────────────────────────────────┐ │
│ │ │ 核心库 (只读,框架团队维护) │ │
│ │ │ ├── Core: 模拟行为、全局数据 │ │
│ │ │ ├── HF: 资源管理、事件系统、相机管理 │ │
│ │ │ └── General: 状态机、工具类 │ │
│ │ └───────────────────────────────────────────────────┘ │
│ │ │
│ └─────────────────────────────────────────────────────────┘ │
└─────────────────────────────────────────────────────────────┘
```
#### 1.1.2 核心库访问原则
| 原则 | 说明 |
|-----|-----|
| **只读访问** | 核心库代码只可读取,不可修改 |
| **接口优先** | 通过接口访问服务,而非直接实例化实现类 |
| **继承扩展** | 通过继承抽象类实现自定义逻辑 |
| **依赖注入** | 通过管理器获取实例,而非硬编码 |
---
## 二、业务代码结构
### 2.1 目录组织规范
```
Assets/Game/GameHFScripte/GameFunction/
├── Event/ # 消息处理
│ ├── ServerToClient/ # 服务器到客户端消息
│ ├── ClientToClient/ # 客户端内部消息
│ └── Handle/ # 消息处理器
├── GameRoot/ # 框架调用入口
│ ├── HFGameStart.cs # 热更新进入入口
│ ├── HFFunCatalogue.cs # 框架统一调用入口
│ ├── HFFunCatalogue_Function.cs # 功能调用方法
│ └── ...
├── HFDownLoadSubPackage/ # 分包下载
│ ├── HFSubPackageManager.cs # 分包管理器
│ ├── HFGameStartAssetsCheckManager.cs # 资源检查
│ └── ...
├── HFExtends/ # Class扩展方法
│ ├── UI/ # UI扩展
│ ├── Material/ # 材质扩展
│ ├── String/ # 字符串扩展
│ └── ...
├── Logic/ # 游戏主要业务逻辑存放各功能Manager
│ ├── User/ # 用户相关
│ ├── Login/ # 登录系统
│ ├── Fight/ # 战斗系统
│ ├── CardDeck/ # 卡组系统
│ ├── Bag/ # 背包系统
│ └── ...
├── UIWindows/ # UI窗口业务逻辑
│ ├── Login/ # 登录窗口
│ ├── Lobby/ # 大厅窗口
│ ├── Fight/ # 战斗窗口
│ ├── Shop/ # 商店窗口
│ └── ...
├── GameEntity/ # 游戏实体
│ ├── Entity/ # 实体定义
│ ├── EntityPool/ # 实体对象池
│ └── ...
├── SoundManagerPro/ # 音效管理
├── SceneManager/ # 场景管理
├── SDK/ # SDK集成
└── MonoCompent/ # Mono组件
```
### 2.2 文件命名规范
| 文件类型 | 命名规则 | 示例 |
|---------|---------|-----|
| **窗口类** | `XXXWindow.cs` | `LoginWindow.cs` |
| **组件类** | `XXXComponent.cs` | `ItemCellComponent.cs` |
| **管理器类** | `XXXManager.cs` | `UIManager.cs` |
| **数据类** | `XXXData.cs` | `PlayerData.cs` |
| **配置类** | `XXXConfig.cs` | `SkillConfig.cs` |
---
## 三、核心库使用指南
### 3.1 对象池使用
#### 3.1.1 GameObject对象池
```csharp
public class BulletManager : MonoBehaviour
{
[SerializeField] private GameObject bulletPrefab;
private HFObjectMemPool m_BulletPool;
void Awake()
{
// 创建对象池
m_BulletPool = new HFObjectMemPool(bulletPrefab, transform);
}
public void Fire(Vector3 position, Quaternion rotation)
{
bool isNew;
GameObject bullet = m_BulletPool.GetItem(out isNew);
bullet.transform.position = position;
bullet.transform.rotation = rotation;
// 如果是新创建的对象,初始化组件
if (isNew)
{
bullet.GetComponent<BulletComponent>().Initialize();
}
}
public void RecycleBullet(GameObject bullet)
{
m_BulletPool.GiveBack(bullet);
}
void OnDestroy()
{
// 清理对象池
m_BulletPool.Recycle();
}
}
```
#### 3.1.2 脚本对象池
```csharp
public class EventArgPool : MonoBehaviour
{
private HFScriptMemPool<GameEventArgs> m_ArgPool;
void Awake()
{
m_ArgPool = new HFScriptMemPool<GameEventArgs>();
}
public GameEventArgs GetEventArgs(GameEventId eventId)
{
bool isNew;
GameEventArgs arg = m_ArgPool.GetItem(out isNew);
arg.eventId = eventId;
return arg;
}
public void RecycleEventArgs(GameEventArgs arg)
{
m_ArgPool.GiveBack(arg);
}
}
```
### 3.2 事件系统使用
#### 3.2.1 定义事件枚举和参数
```csharp
// 事件ID枚举
public enum GameEventId
{
PlayerLevelUp,
EnemyKilled,
GoldChanged
}
// 事件参数基类
public class GameEventArgs : IHFEventArg<GameEventId>, IHFRecycle
{
public GameEventId eventId { get; set; }
public void Recycle()
{
// 重置状态
eventId = default;
}
}
// 具体事件参数
public class PlayerLevelUpEventArgs : GameEventArgs
{
public int playerId;
public int oldLevel;
public int newLevel;
}
```
#### 3.2.2 注册和触发事件
**事件系统分为两类**
- **STCEvent**Server To Client服务器到客户端消息
- **CTCEvent**Client To Client客户端内部消息
**注册事件监听**
```csharp
/// <summary>
/// 卡组窗口
/// </summary>
[HFAssetBundlePath(enHFLanguageRootFolder.ASSETS_GAME_GAMEHFRESOURCE, "UIWindows/CardDeck/CardDeckWindow.prefab")]
[HFUIWindowLayer(enHFUICanvasLayer.UIWindow, enHFUIWindowLayer.Dynamic, isIgnoreCloseByESC = false)]
public class CardDeckWindow : AbsHFUIWindow
{
/// <summary>
/// 初始化(仅调用一次)
/// </summary>
protected override void OnRunAwake()
{
base.OnRunAwake();
// 初始化UI组件引用
// 绑定事件监听(如按钮点击等)
}
/// <summary>
/// 打开窗口(每次打开调用)
/// </summary>
protected override void OnOpen(Action _onOpenComplete)
{
base.OnOpen(_onOpenComplete);
// 注册客户端内部消息监听CTCEvent
HFFunCatalogue.Event.CTCEvent.AddListener<HFEvent_CTC_CardUpdate>(enHFCTCEvent.CardUpdate, OnCardUpdate);
}
/// <summary>
/// 关闭窗口
/// </summary>
protected override void OnClose(Action _onCloseComplete)
{
base.OnClose(_onCloseComplete);
// 取消客户端内部消息监听
HFFunCatalogue.Event.CTCEvent.RemoveListener<HFEvent_CTC_CardUpdate>(enHFCTCEvent.CardUpdate, OnCardUpdate);
}
void OnCardUpdate(HFEventArgBase arg)
{
HFEvent_CTC_CardUpdate cardArg = arg as HFEvent_CTC_CardUpdate;
// 更新卡组UI显示
}
}
```
> **注意**UI窗口中**不监听服务器事件STCEvent**服务器事件应在Logic层的Manager中监听。
**Manager类型定义**
Manager需要继承`AbsHFSingleMonoBehaviour``AbsHFSingleRunTime`
| 类型 | 说明 | 适用场景 |
|-----|------|---------|
| `AbsHFSingleMonoBehaviour` | 生成GameObject可注册MonoBehaviour事件 | 需要Update/FixedUpdate等生命周期 |
| `AbsHFSingleRunTime` | 纯内存单例无GameObject | 不需要生命周期事件 |
**示例1使用AbsHFSingleMonoBehaviour需要Update**
```csharp
public class PlayerManager : AbsHFSingleMonoBehaviour<PlayerManager>
{
/// <summary>
/// 注册模拟Behaviour事件
/// 通过此属性声明需要监听的事件
/// </summary>
protected override int[] simulateBehaviourEvents => new int[]
{
enHFSimulateBehaviourEvent.Mono_Update,
enHFSimulateBehaviourEvent.Mono_FixedUpdate
};
/// <summary>
/// 单例创建时调用(仅一次)
/// </summary>
protected override void OnAfterCreateInstance()
{
base.OnAfterCreateInstance();
// 初始化逻辑
RegisterServerEvents();
}
/// <summary>
/// 模拟Update事件通过simulateBehaviourEvents注册后自动调用
/// 注这是封装后的事件非Unity原生MonoBehaviour.Update
/// </summary>
protected override void OnRunUpdate()
{
// 每帧更新逻辑
}
/// <summary>
/// 模拟FixedUpdate事件
/// </summary>
protected override void OnRunFixedUpdate()
{
// 物理更新逻辑
}
/// <summary>
/// 注册服务器事件监听
/// </summary>
void RegisterServerEvents()
{
HFFunCatalogue.Event.STCEvent.AddListener<HFEvent_STC_PlayerInfo>(enHFSTCEvent.PlayerInfo, OnPlayerInfo);
}
void OnPlayerInfo(HFEventArgBase arg)
{
HFEvent_STC_PlayerInfo info = arg as HFEvent_STC_PlayerInfo;
// 处理服务器返回的玩家信息
// 触发客户端事件通知UI更新
HFEvent_CTC_PlayerLevelUp evt = HFFunCatalogue.New<HFEvent_CTC_PlayerLevelUp>();
evt.playerId = info.playerId;
evt.newLevel = info.level;
HFFunCatalogue.Event.CTCEvent.Dispatch(evt);
}
}
```
**示例2使用AbsHFSingleRunTime纯逻辑**
```csharp
public class ConfigManager : AbsHFSingleRunTime<ConfigManager>
{
/// <summary>
/// 单例创建时调用(仅一次)
/// </summary>
protected override void OnAfterCreateInstance()
{
base.OnAfterCreateInstance();
// 加载配置表
LoadConfigTables();
}
void LoadConfigTables()
{
// 加载配置数据
}
}
```
### 3.3 资源加载使用
#### 3.3.1 加载AssetBundle资源
```csharp
public class ResourceLoader : MonoBehaviour
{
public void LoadPlayerModel(int resId, Action<GameObject> onLoaded)
{
// 通过HFFunCatalogue统一入口加载资源
// resId: 从Res配置表中读取的资源ID
HFFunCatalogue.Asset.LoadAsset(resId, (res, obj) =>
{
if (obj != null)
{
GameObject model = res.GetAsset<GameObject>();
onLoaded?.Invoke(model);
}
else
{
Debug.LogError($"加载失败: resId={resId}");
}
});
}
}
```
**实体资源加载示例**
```csharp
// 在Entity中加载资源
HFFunCatalogue.Asset.LoadAsset(data.EntityRes.Id, (res, obj) => {
if (!entity.isDeath)
{
var Boddy = res.GetAsset<GameObject>();
data.SetBoddy(Boddy);
}
});
```
### 3.4 相机管理使用
#### 3.4.1 创建自定义相机
```csharp
public class UIOverlayCamera : AbsHFCameraItem
{
[SerializeField] private Camera uiCamera;
[SerializeField] private int weight = 10;
public override Camera CameraItem => uiCamera;
public override int Weight => weight;
protected override void OnInitialize()
{
base.OnInitialize();
// 自定义初始化逻辑
uiCamera.clearFlags = CameraClearFlags.Depth;
uiCamera.depth = 100;
}
}
```
#### 3.4.2 管理相机堆栈
```csharp
public class CameraController : MonoBehaviour
{
void Start()
{
// 获取相机管理器
HFCameraManager cameraMgr = HFCameraManager.Instance;
// 添加自定义相机
UIOverlayCamera uiCamera = GetComponent<UIOverlayCamera>();
cameraMgr.AddCamera(uiCamera);
// 获取主相机
Camera mainCam = cameraMgr.mainCamera.MainCamera;
}
void OnDestroy()
{
UIOverlayCamera uiCamera = GetComponent<UIOverlayCamera>();
HFCameraManager.Instance.RemoveCamera(uiCamera);
}
}
```
---
## 四、开发流程
### 4.1 需求分析
1. **明确需求**:理解业务需求,确定需要实现的功能
2. **评估复杂度**:判断是否需要核心库支持或扩展
3. **设计方案**:规划代码结构和调用关系
### 4.2 代码编写
1. **创建目录**:在`GameBusiness`下创建对应模块目录
2. **编写代码**遵循编码规范使用核心库提供的API
3. **测试验证**在Unity中测试功能正确性
### 4.3 代码审查
1. **自我检查**:检查是否符合规范,是否有潜在问题
2. **团队审查**:提交代码进行团队审查
3. **修复问题**:根据审查意见修改代码
### 4.4 集成测试
1. **模块测试**:测试单个模块功能
2. **集成测试**:测试模块间交互
3. **回归测试**:确保不影响现有功能
---
## 五、最佳实践
### 5.1 性能优化
#### 5.1.1 对象池使用
- 频繁创建销毁的对象必须使用对象池
- 合理设置对象池初始容量
- 定期清理空闲对象避免内存泄漏
#### 5.1.2 资源管理
- 及时释放不再使用的资源
- 使用异步加载避免卡顿
- 合理使用资源缓存
### 5.2 代码组织
#### 5.2.1 单一职责
- 每个类只负责一个功能
- 避免庞大的God类
#### 5.2.2 依赖管理
- 通过管理器获取依赖,而非硬编码
- 使用接口解耦依赖关系
### 5.3 错误处理
#### 5.3.1 异常捕获
- 在关键路径添加异常处理
- 记录错误日志便于排查
#### 5.3.2 防御性编程
- 检查参数合法性
- 处理空引用情况
---
## 六、常见问题
### 6.1 如何扩展核心库功能?
通过继承抽象类或实现接口来扩展,不要直接修改核心库代码。
### 6.2 核心库有Bug怎么办
提交Issue到框架团队由框架团队修复并发布新版本。
### 6.3 如何获取核心库的最新版本?
关注内部通知,定期更新核心库引用。
### 6.4 如何调试核心库代码?
可以设置断点调试,但不允许修改代码。
---
## 附录
### A. 常用核心库API
| 类别 | 管理器 | 常用方法 |
|-----|-------|---------|
| **对象池** | `HFObjectMemPool` | `GetItem()`, `GiveBack()` |
| **事件** | `IHFEventHandle` | `AddListener()`, `Dispatch()` |
| **资源** | `HFABMgr` | `OnStartLoad()` |
| **相机** | `HFCameraManager` | `AddCamera()`, `GetCamera()` |
### B. 核心库只读目录
```
Assets/StrayFog/Core/
Assets/Game/GameHFScripte/CopyToHF/
Assets/Game/GameGeneralScripte/
```
---
**版本**: v1.0
**生效日期**: 2024年
**适用范围**: OnlineGame项目业务开发人员