Files
2026-07-10 10:24:29 +08:00

86 lines
8.5 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 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