【初始化】上传UnityAI框架文档,包含StrayFog框架架构分析、业务开发指南、核心库保护规范
This commit is contained in:
567
业务开发指南.md
Normal file
567
业务开发指南.md
Normal file
@@ -0,0 +1,567 @@
|
||||
# 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项目业务开发人员
|
||||
Reference in New Issue
Block a user