Files
UnityAI/rules/20-开发规则.md
2026-10-20 11:04:12 +08:00

9.7 KiB
Raw Blame History

开发规则

基本原则

  • 先读取附近代码和模块文档,再决定实现方式。
  • 修改范围保持聚焦,优先复用项目已有模式和公开入口。
  • 真实源码、生成代码、业务代码和资源必须按 架构说明 区分。
  • 不回退任务开始前已有的修改,不顺带格式化或重序列化无关文件。
  • 一个长期事实只在一处完整定义,其他文档使用链接。

C# 规则

命名与结构

  • 类型、属性和方法使用 PascalCase。
  • 私有字段沿用项目 m_ 前缀,例如 m_UserName。
  • 方法参数沿用项目 _ 前缀,例如 _userName。
  • 一个文件原则上只放一个主要类型;partial 和小型辅助类型遵循附近实现。
  • public API 添加简洁中文 XML 注释,说明用途、参数和返回值。
  • 日志包含方法、资源路径、PackageId 或平台等关键上下文,不只输出“失败”。

语言兼容性

  • 先读取 Unity 版本、asmdef 和附近代码风格,不默认使用最新 C# 语法。
  • 不使用 C# 新特性;使用项目已有的显式类型、普通属性、传统 switch 和清晰的回调/协程写法。
  • 禁止引入 record、init-only、范围索引、复杂模式匹配、目标类型推断等较新语法。
  • 避免超长方法、深层嵌套和为了封装而封装的辅助层。

代码格式

  • 能在一行内清晰写完的代码不要换行,尤其是方法声明、方法调用的参数列表和消息接收/注册代码。
  • if、else、for、foreach、while、do 等控制语句必须使用 {},即使语句体只有一行也不得省略。
  • 所有方法必须完整书写方法体和 {},禁止使用表达式体(=>)等省略写法。

面向对象设计六大原则(辅助参考)

以下原则仅用于辅助理解职责、依赖和扩展方式,不作为独立的强制开发规则或验收门槛。以现有开发规则、项目架构、兼容性要求和实际需求为准;存在取舍时,不用六大原则覆盖这些约定。

遇到相关设计问题时按需参考,无需每次开发逐条检查或说明不采用的理由。优先复用项目现有结构,选择最小可行实现;不能仅因某段代码不符合某项原则就要求拆类、增加接口、引入模式或重构。

1. 单一职责原则(SRP)

  • 一个类或模块应围绕一个内聚职责组织,具有同一类变更原因;不按方法数量或代码行数机械拆类。
  • 展示、业务状态、网络传输和资源加载等独立变化的职责应有明确边界,避免集中到一个窗口、MonoBehaviour 或万能管理器中。
  • 方法围绕一个明确目的组织;可以组合步骤,但不夹带无关副作用。拆分时复用现有模块,避免只有转发作用的空壳层。

2. 开闭原则(OCP)

  • 对已经确认的变化点,优先通过现有配置、组合、策略或扩展入口增加行为,减少反复修改稳定核心流程。
  • 不为尚不存在的变化预建扩展体系,也不为了消除所有 if / switch 强行引入模式。
  • 修复缺陷或调整已有行为仍可直接修改源码;涉及公共接口、协议或数据兼容性时,按工作流确认影响并验证现有调用。

3. 里氏替换原则(LSP)

  • 子类型替换基类型后,必须继续满足调用者依赖的契约:不加强前置条件、不削弱结果保证,并保持基类不变量及约定的失败行为。
  • 不以空实现、无条件抛出“不支持”异常或额外类型判断掩盖不成立的继承关系;无法满足契约时优先组合或拆分能力接口。
  • Unity 生命周期重写必须遵循当前基类的初始化、清理和完成回调契约;不能只看签名相同就认为可替换。对修改影响的基类调用路径做针对性验证。

4. 依赖倒置原则(DIP)

  • 高层业务规则与易变的底层细节通过稳定契约协作;抽象围绕业务需要定义,不能只是复制底层 SDK 的全部接口。
  • 沿用项目已有接口、事件和公开入口;底层框架不得反向依赖具体游戏业务。程序集方向仍遵循 架构说明。
  • 需要隔离网络、平台 SDK、存储等易变实现时,在明确边界使用接口、委托或现有桥接机制;不要求每个具体类都有接口,不新增无必要的容器或全局服务定位层。

5. 接口隔离原则(ISP)

  • 调用方只依赖自己需要的能力;不要让实现类因一个大接口被迫提供无关方法或无效实现。
  • 按内聚的角色与能力拆分接口,避免万能接口;也不机械拆成大量单方法接口。
  • 扩展共享接口前检查所有实现者与调用者,评估兼容性;独立能力优先使用独立契约,不随意给既有公共接口加成员。

6. 迪米特法则(LoD,最少知识原则)

  • 模块通过直接协作对象的公开能力完成工作,避免穿透多个对象的内部结构、任意修改其他模块状态或依赖易变的深层节点路径。
  • 优先通过项目现有管理器入口、查询方法或事件交互,减少对他人内部实现的了解;合法的数据读取和集合访问不因调用链长就机械包装。
  • 不为了缩短调用链添加无意义的转发层,也不把所有调用改成全局事件或单例。状态由所属模块维护,生命周期与事件解绑责任必须明确。

辅助使用边界

  • 需要分析职责或依赖问题时,可借助相关原则判断;不要求逐项打勾,不靠类名或模式数量评价代码,也不把完全符合六大原则作为完成条件。
  • 不顺带重构无关历史代码;发现既有问题时说明影响,只有阻碍当前需求且获得对应范围授权时才调整。
  • 原则与现有开发规则、兼容性、性能或交付范围发生取舍时,以当前规则与实际需求为准;仅对影响本次行为或维护成本的实际取舍作必要说明。公共接口和架构调整仍遵守 工作流清单。
  • Unity 中同时核对序列化、Prefab 引用、生命周期、资源释放与目标平台限制;原则不能成为破坏这些约束的理由。
  • 验证与改动匹配:检查受影响的调用者和实现者,必要时验证替换行为、边界失败路径及资源清理。文档检查或编译通过不代表运行时契约已经得到验证。

框架与业务边界

  • 业务代码通过 HFFunCatalogue 等统一入口访问资源、UI、场景和其他框架能力。
  • 业务功能直接修改 GameFunction、GameMono 和对应资源。
  • 框架维护任务可以修改 Assets/StrayFog/Core、Assets/StrayFog/Editor 和 CopyToX 源码,不套用“业务不得改框架”的限制。
  • CopyToX 生成目录禁止手改;生成结果有问题时修正 ESF/General 源码或生成器。
  • 修改 ESF 后必须执行 CopyToX,并检查生成后的 HF 差异。

Unity 与异步规则

  • Unity API 只在 Unity 主线程调用;后台线程只做不触碰 UnityEngine 对象的工作。
  • StreamingAssets、UnityWebRequest、CDN 和 WebGL 下载使用协程或回调。
  • 禁止在主线程用阻塞式 while、忙等或同步等待网络与文件结果。
  • 下载进度只在单文件完整写入并通过 MD5/完整性校验后计数。
  • 平台路径、只读 StreamingAssets、PersistentData 和外部存储回调分别验证。

UI 与 Prefab

  • 修改前同时读取窗口脚本、UIMono、Prefab 层级和相关资源。
  • 动态列表使用项目的 SFUI_ScrollRect,接口选择、模板和布局约束统一见 UI 开发指南,不把某种包装的 API 套用到其他实现。
  • Prefab 修改检查锚点、pivot、sizeDelta、组件启用状态、序列化引用和实际显示。
  • 避免文本方式大范围重写 Prefab;优先使用 Unity Editor、MCP 或结构化序列化工具。

窗口框架见 UI 窗口系统;根据示意图拼 UI 的分辨率确认、切图、资源效率与验收规则统一见 界面拼接。

资源与生成规则

  • Prefab、图集、配置、AssetBundle 和代码生成优先修改源资源或生成配置。
  • SpriteAtlas 按模块组织;打图集设置以项目生成器为准。
  • 网络消息以 proto/schema 为源头,生成输出只用于检查。
  • 资源加载、分包、MD5、下载和卸载规则见 资源管理。
  • 生成操作后检查 Git 差异,确认没有删除或覆盖用户维护的非生成文件。

验证与 Git

  • 验证范围随改动范围扩大,最低要求见 工作流清单。
  • 编译通过后仍需检查 Unity Console;UI 和平台逻辑继续做实际运行验证。
  • UnityAI 与目标 Unity 项目分别检查 Git 状态。
  • Git 提交规则见 项目规则入口。

文档规则

  • 长期文档只记录稳定架构、公共 API、生成流程和使用规则。
  • 重大变更的讨论和文档落盘方式遵循 工作流清单。
  • 文档使用相对链接;代码示例必须可编译或明确标注伪代码。
  • 模块入口或状态变化时更新 模块索引。

文档关联

文档 关联原因
架构说明 源码与生成目录边界
工作流清单 实施与验证流程
文档同步规则 长期文档更新条件
UI 窗口系统 UI 专项规范
资源管理 资源专项规范