Initial commit: Client Doc docs Server Tools

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
ud18010
2026-07-10 10:24:29 +08:00
co-authored by Cursor
commit 7e35d8da31
3374 changed files with 680813 additions and 0 deletions
+85
View File
@@ -0,0 +1,85 @@
# Unity 项目规则
## 美术资源目录
通用资源目录:
- Shader 目录:`Client\Assets\Game\shader`
- UI 资源贴图目录:`Assets\Game\Art\UI\Texture`
- 通用控件贴图目录:`Assets\Game\Art\UI\Texture\Common`
- UI 预设目录:`Assets\Game\Art\UI\Prefab`
- UI 字体目录:`Assets\Game\Art\UI\Font`
- UI 默认字体:思源黑体 CN Regular,源文件 `Assets\Game\Art\UI\Font\SourceHanSansCN-Regular.otf`
- 场景资源目录:`Assets\Game\Art\Scene`
- 角色资源目录:`Assets\Game\Art\Actor`
- 物件资源目录:`Assets\Game\Art\Object`
- 特效资源目录:`Assets\Game\Art\Effect`
- 声音资源目录:`Assets\Game\Art\Sound`
小游戏资源目录是以上通用资源目录中的Game换为小游戏名
## 小游戏代码规则
1. 小游戏的逻辑代码全部用 C# 实现(热更 C#,通过 HybridCLR 加载更新),不使用 Lua;小游戏专属逻辑以 C# 脚本(MonoBehaviour 控制器等)组织。
2. UI 由 C# 直接访问 Unity 组件驱动:用 `transform.Find(路径)`,或 `Transform.childCount` + `transform.GetChild(i)` 递归按名查找节点(可使用 `Utility.FindTransform` 等 C# 扩展方法),再用 `GetComponent<类型>()` 获取 `TextMeshProUGUI`/`Button`/`Image`/`RectTransform` 等组件,按钮点击用 `button.onClick.AddListener(回调)` 绑定。
3. Prefab 的 JSON`Doc/UIPrefabCreater`)可声明指向小游戏 C# 控制器的 `MonoBehaviour` 组件(通过 `typeName` 指定,例如 `"typeName": "XGame.XxxController"`);运行时由该 MonoBehaviour 驱动界面与业务逻辑。
4. 通用基础设施(资源加载、网络、协程等)继续复用引擎已有的 C# 框架。
## 资源加载规则
1. **本项目所有游戏资源加载一律用异步**,禁止同步加载。原因:本项目 DLL 与资源是两套独立更新机制,资源包只在**异步加载**时按需从 CDN 下载;**同步加载只读本地、不下载**,会读到旧 APK 底包里的旧资源(编辑器走 AssetDatabase 看不出问题,真机才暴露)。
2. 协程上下文里用 `XResLoader.coLoadRes(path, type, obj => {...})``yield return`);非协程/纯逻辑层用回调版 `XResLoader.LoadRes(path, type, Action<UObject[]>)`(内部自驱动协程,fire-and-forget)。
3. 同步 `XResLoader.LoadRes(path,type)` / `LoadResAB(path,type)` 已标记 `[Obsolete]`,**禁止新用**(新写会触发编译警告)。
4. 路径前缀:异步接口带不带 `Assets/` 前缀都可(内部自动剥离),如 `"Assets/Game/Art/UI/Prefab/X.prefab"``"Game/Art/UI/Prefab/X.prefab"`
5. 加载从"同帧返回"变为"延迟若干帧返回":把"加载完成后才用资源"的逻辑放进回调/协程续接里;对必须立即可见的对象,先放占位再在回调里替换为真实资源(参考 `LobbyWorldController` 角色胶囊占位→真实角色的升级方式)。
6. 小游戏框架 `IAssetLoader.Load(path, onLoaded)` 也是异步回调式(`MiniGameDownloader` 已预下载全部包,回调里返回对象)。唯一例外:启动期一次性读本地的 Lua 字节码/config`LoadLuaAB`),不涉热更资源更新,不在本规则约束内。
## UI 挂载规则
UI 预设统一挂在 `UIRoot` 节点下对应的子节点,按界面类型分层:
- **HUD**:抬头信息(血条、状态、摇杆、小地图等常驻 HUD)
- **Normal**:普通功能界面(背包、设置、商城等常规面板)
- **Dialog**:弹出对话框(确认框、二次确认等模态弹窗)
- **Tips**:弹出的文字信息(飘字、轻提示 Toast 等)
层级从下到上一般为 HUD → Normal → Dialog → Tips,越靠上的层显示在越上层。新建界面时按其类型挂到对应节点,不要直接挂到 `UIRoot` 或随意父节点下。
## UI 制作规则
1. 设计分辨率:2048X1024,ui设计的时候考虑能适配多种分辨率
2. 设计新界面时,先使用 UI 通用控件(有MeshTextPro版本的只用MeshTextPro版本)贴图生成 JSON 界面描述文件,并记录 Unity 所使用的控件类型、层级、RectTransform、资源、文本、事件和业务绑定。
3. 保存 JSON 后切回或重新激活 Unity 编辑器,由 Unity 自动检测新增或变更的 JSON 并生成对应 PrefabLayer设置为UI。
4. 根据功能说明,使用 Prefab 和相关资源开发游戏功能。
5. 设计风格参考Doc\Design\ui_design.jpg
6. 如果有需要生成新的贴图,使用gptimage2技能生成到对应目录中;小游戏使用的贴图必须放回小游戏自己的目录结构下(即通用资源目录中的 `Game` 换为小游戏名),不要生成到通用 `Game` 目录。
## JSON 转 Unity Prefab 参数规则
- JSON 界面描述文件统一放在 `Doc/UIPrefabCreater` 目录,文件名使用界面名,例如 `MatchWaitingControls.json`
- JSON 根对象必须声明 `schemaVersion``prefabName``prefabPath``canvas``assets``nodes``bindings``events` 按业务需要声明。
- `canvas.referenceResolution` 使用 `[2048, 1024]` 作为设计分辨率,后置工具按该设计分辨率换算 RectTransform;特殊界面需要使用其他分辨率时必须在 `description` 中说明原因。
- 每个需要转换成 Unity 节点的对象必须放入 `nodes` 数组,并声明 `name``parent``active``rect``components`
- 节点层级由 `parent` 指定;同一父节点下按 `nodes` 数组顺序生成,同级越靠后的节点显示在越上层。
- `components.type` 可选值:`Canvas``CanvasScaler``GraphicRaycaster``Image``Button``TextMeshProUGUI``TMP_InputField``TMP_Dropdown``Toggle``Slider``Scrollbar``ScrollView``Empty``MonoBehaviour`
- `rect` 使用 Unity RectTransform 参数,优先声明 `anchorMin``anchorMax``pivot``anchoredPosition``sizeDelta`;全屏拉伸节点可使用 `offsetMin``offsetMax`
- 图片资源统一在 `assets.sprites` 中登记短名,节点 `Image` 组件使用 `sprite` 引用短名;资源路径由转换工具按项目资源目录解析,例如 `ui_button_primary_normal` 对应 `Assets/Game/Art/UI/Texture/Common/ui_button_primary_normal.png`;小游戏专属贴图按小游戏目录结构解析(即路径中的 `Game` 换为小游戏名),不解析到通用 `Game` 目录。
- 九宫格图片必须声明 `"imageType": "Sliced"`;普通图片使用 `"imageType": "Simple"`;进度填充可使用 `"imageType": "Filled"`
- 文字节点统一使用 `TextMeshProUGUI`,文本内容使用 `text`,字体大小使用 `fontSize`,颜色使用 `color`,对齐使用 `alignment`
- 浅色文字在复杂背景、图片背景、半透明面板或高亮按钮上必须使用深色描边或阴影保证可读性;描边颜色优先使用深蓝或深灰,例如 `#0B1724``#102033`,不默认使用纯黑。
- 标题、按钮文字、状态提示、倒计时等关键 UI 文本可使用轻描边或阴影;普通正文、列表、输入框文本不默认加描边,优先通过背景对比度保证可读性。
- TextMeshProUGUI 描边建议保持轻量,常规 UI 使用较小 Outline Width,避免粗黑边导致界面变脏。
- 按钮节点使用 `Button` 组件,`transition` 优先使用 `SpriteSwap`;需要点击事件时在组件中声明 `onClick`,并在根对象 `events` 中登记事件名和节点名。
- 输入框节点使用 `TMP_InputField`,必须声明 `placeholder``characterLimit``contentType`;密码输入使用 `"contentType": "Password"`
- Toggle 节点必须声明 `toggleGroup``isOn`,并分别用子节点声明背景和选中标记。
- 需要业务绑定的控件必须加入根对象 `bindings`,例如 `login.username``register.password`;事件统一加入根对象 `events`,例如 `{ "name": "Auth.Login", "node": "Btn_Login" }`
- 需要挂载运行时脚本时使用 `MonoBehaviour` 组件,并声明 `typeName`,例如 `"typeName": "XGame.MatchWaitingController"`
- Unity 编辑器重新激活时,自动转换工具应只读取新增或变更的 JSON 文件生成 Prefab;JSON 字段冲突时以节点 `components` 内显式声明的参数为准。
## UI 通用控件贴图
- 目录:`Assets\Game\Art\UI\Texture\Common`
- 风格:轻松、扁平化游戏风格,色彩饱和度略高,圆角轮廓,轻微高光和阴影。
- 导入设置:贴图类型使用 `Sprite (2D and UI)`,启用 Alpha 透明,通用拉伸背景使用 `Sliced` 九宫格。
- 命名规则:统一使用 `ui_控件类型_状态或用途.png`,例如 `ui_button_primary_normal.png`
### 控件贴图清单
Doc\UI_Pic_Set.md