# 角色外观自定义系统设计文档 ## 概述 本设计文档描述了为现有 Godot AI 小镇游戏添加角色外观自定义功能的完整方案。该系统将在现有角色创建流程的基础上,添加一个专门的外观自定义界面,允许用户自定义角色的头部、身体、脚部颜色,并通过流畅的UI动效提升用户体验。 ### 技术栈 - **游戏引擎**: Godot 4.x - **编程语言**: GDScript - **UI框架**: Godot Control 节点系统 - **动画系统**: Godot Tween 和 AnimationPlayer - **数据格式**: Dictionary (GDScript 原生) - **颜色系统**: Godot Color 类 ## 架构 ### 整体架构 角色外观自定义系统采用模块化设计,与现有的角色创建系统集成: ``` ┌─────────────────────────────────────────┐ │ 角色创建流程 (CharacterCreation) │ ├─────────────────────────────────────────┤ │ 1. 默认外观生成 │ │ 2. 角色名称输入 │ │ 3. 自定义外观按钮 │ │ 4. 创建角色按钮 │ └─────────────────────────────────────────┘ ↓ 点击自定义外观 ┌─────────────────────────────────────────┐ │ 外观自定义界面 (AppearanceCustomizer) │ ├─────────────────────────────────────────┤ │ ┌─────────────────────────────────────┐ │ │ │ 头部颜色调整区域 │ │ │ │ ┌─────────────┐ ┌─────────────┐ │ │ │ │ │ 颜色选择器 │ │ 预设颜色 │ │ │ │ │ └─────────────┘ └─────────────┘ │ │ │ └─────────────────────────────────────┘ │ │ ┌─────────────────────────────────────┐ │ │ │ 身体颜色调整区域 │ │ │ │ ┌─────────────┐ ┌─────────────┐ │ │ │ │ │ 颜色选择器 │ │ 预设颜色 │ │ │ │ │ └─────────────┘ └─────────────┘ │ │ │ └─────────────────────────────────────┘ │ │ ┌─────────────────────────────────────┐ │ │ │ 脚部颜色调整区域 │ │ │ │ ┌─────────────┐ ┌─────────────┐ │ │ │ │ │ 颜色选择器 │ │ 预设颜色 │ │ │ │ │ └─────────────┘ └─────────────┘ │ │ │ └─────────────────────────────────────┘ │ │ ┌─────────────────────────────────────┐ │ │ │ 角色预览区域 │ │ │ │ ┌─────────────────────────────┐ │ │ │ │ │ 实时预览显示 │ │ │ │ │ └─────────────────────────────┘ │ │ │ └─────────────────────────────────────┘ │ │ ┌─────────────────────────────────────┐ │ │ │ 操作按钮区域 │ │ │ │ [返回] [重置] [随机生成] [保存] │ │ │ └─────────────────────────────────────┘ │ └─────────────────────────────────────────┘ ↓ 点击返回/保存 ┌─────────────────────────────────────────┐ │ 角色创建流程 (更新后) │ ├─────────────────────────────────────────┤ │ 1. 显示自定义外观预览 │ │ 2. 角色名称输入 │ │ 3. 创建角色按钮 (应用自定义外观) │ └─────────────────────────────────────────┘ ``` ### 组件架构 系统主要包含以下核心组件: ``` AppearanceCustomizer (主控制器) ├─ DefaultAppearanceGenerator (默认外观生成器) ├─ ColorAdjustmentPanel (颜色调整面板) │ ├─ HeadColorAdjuster (头部颜色调整器) │ ├─ BodyColorAdjuster (身体颜色调整器) │ └─ FootColorAdjuster (脚部颜色调整器) ├─ AppearancePreview (外观预览器) ├─ UIAnimationController (UI动画控制器) └─ AppearanceDataManager (外观数据管理器) ``` ## 组件和接口 ### 1. 默认外观生成器 (DefaultAppearanceGenerator) **职责**: 为新角色生成协调的默认外观 **接口**: ```gdscript class_name DefaultAppearanceGenerator static func generate_default_appearance() -> Dictionary static func generate_coordinated_colors() -> Dictionary static func get_fallback_appearance() -> Dictionary static func validate_appearance_data(appearance: Dictionary) -> bool ``` **生成规则**: - 头部颜色:使用肤色色调范围 - 身体颜色:使用服装色调范围,与头部形成对比 - 脚部颜色:使用鞋子色调范围,与身体协调 - 确保颜色对比度适中,视觉效果和谐 ### 2. 颜色调整器 (ColorAdjuster) **职责**: 处理单个身体部位的颜色调整 **接口**: ```gdscript class_name ColorAdjuster extends Control signal color_changed(new_color: Color) var current_color: Color var preset_colors: Array[Color] var color_picker: ColorPicker var preset_buttons: Array[Button] func set_color(color: Color) -> void func get_color() -> Color func setup_presets(colors: Array[Color]) -> void func reset_to_default() -> void ``` **预设颜色方案**: - 头部:5种肤色选项 - 身体:8种服装颜色选项 - 脚部:6种鞋子颜色选项 ### 3. 外观预览器 (AppearancePreview) **职责**: 实时显示角色外观预览 **接口**: ```gdscript class_name AppearancePreview extends Control var character_sprite: CharacterSprite var head_sprite: Sprite2D var body_sprite: Sprite2D var foot_sprite: Sprite2D func update_appearance(appearance_data: Dictionary) -> void func set_head_color(color: Color) -> void func set_body_color(color: Color) -> void func set_foot_color(color: Color) -> void func animate_color_change(part: String, color: Color) -> void ``` **预览特性**: - 实时颜色更新(延迟 < 100ms) - 平滑的颜色过渡动画 - 支持不同身体部位的独立渲染 ### 4. UI动画控制器 (UIAnimationController) **职责**: 管理界面切换和元素动画 **接口**: ```gdscript class_name UIAnimationController static func hide_creation_elements(elements: Array[Control], duration: float = 0.5) -> void static func show_creation_elements(elements: Array[Control], duration: float = 0.5) -> void static func slide_in_customizer(customizer: Control, direction: String = "right") -> void static func slide_out_customizer(customizer: Control, direction: String = "left") -> void static func fade_transition(from_scene: Control, to_scene: Control) -> void ``` **动画类型**: - 淡出动画:透明度从1.0到0.0 - 滑动动画:位置偏移动画 - 缩放动画:大小变化动画 - 组合动画:多种效果结合 ### 5. 外观数据管理器 (AppearanceDataManager) **职责**: 管理外观数据的存储、加载和验证 **接口**: ```gdscript class_name AppearanceDataManager static func create_appearance_data(head: Color, body: Color, foot: Color) -> Dictionary static func validate_appearance_data(data: Dictionary) -> bool static func serialize_appearance(data: Dictionary) -> String static func deserialize_appearance(json_str: String) -> Dictionary static func merge_with_defaults(custom_data: Dictionary) -> Dictionary ``` **数据结构**: ```gdscript { "head_color": "#F5DEB3", # 头部颜色 (十六进制) "body_color": "#4169E1", # 身体颜色 "foot_color": "#8B4513", # 脚部颜色 "created_at": 1234567890, # 创建时间戳 "version": "1.0" # 数据版本 } ``` ## 数据模型 ### 外观数据结构 ```gdscript # 完整的外观数据模型 { "appearance": { "head_color": "#F5DEB3", "body_color": "#4169E1", "foot_color": "#8B4513", "style": "default", "created_at": 1234567890, "version": "1.0" }, "metadata": { "is_custom": true, "last_modified": 1234567890, "modification_count": 3 } } ``` ### 颜色预设数据 ```gdscript # 预设颜色方案 const COLOR_PRESETS = { "head": [ Color("#F5DEB3"), # 浅肤色 Color("#DEB887"), # 中等肤色 Color("#D2B48C"), # 小麦色 Color("#CD853F"), # 深肤色 Color("#A0522D") # 棕色肤色 ], "body": [ Color("#FF6B6B"), # 红色 Color("#4ECDC4"), # 青色 Color("#45B7D1"), # 蓝色 Color("#96CEB4"), # 绿色 Color("#FFEAA7"), # 黄色 Color("#DDA0DD"), # 紫色 Color("#F0E68C"), # 卡其色 Color("#FFB6C1") # 粉色 ], "foot": [ Color("#8B4513"), # 棕色 Color("#000000"), # 黑色 Color("#FFFFFF"), # 白色 Color("#FF0000"), # 红色 Color("#0000FF"), # 蓝色 Color("#008000") # 绿色 ] } ``` ## 正确性属性 *属性是一个特征或行为,应该在系统的所有有效执行中保持为真——本质上是关于系统应该做什么的正式陈述。属性作为人类可读规范和机器可验证正确性保证之间的桥梁。* ### 属性反思 在编写正确性属性之前,我需要识别和消除冗余: **识别的冗余属性**: 1. 属性3、4、5(头部、身体、脚部颜色调整控件)可以合并为一个通用属性 2. 属性6、7(外观数据保存和预览更新)在逻辑上相关,可以合并 3. 属性8、9(重置和随机生成按钮存在性)可以合并为操作按钮完整性属性 **合并后的属性**: - 将3个独立的颜色调整属性合并为"颜色调整控件完整性" - 将数据保存和预览更新合并为"外观数据一致性" - 将按钮存在性检查合并为"操作按钮完整性" ### 属性 1: 默认外观生成完整性 *对于任意*角色创建请求,系统应该生成包含头部、身体、脚部颜色的完整外观数据 **验证需求: 1.1, 1.3** ### 属性 2: 外观预览实时更新 *对于任意*外观数据的修改,角色预览应该在100毫秒内反映这些变化 **验证需求: 1.2, 3.5, 6.3** ### 属性 3: 界面切换动画触发 *对于任意*自定义外观按钮的点击操作,系统应该触发界面切换动画并在0.5秒内完成 **验证需求: 2.1, 2.3** ### 属性 4: UI元素动画隐藏 *对于任意*界面切换操作,创建角色按钮和角色名称输入框应该通过动画被隐藏 **验证需求: 2.2** ### 属性 5: 自定义场景正确加载 *对于任意*隐藏动画完成事件,系统应该正确加载并显示角色外观自定义场景 **验证需求: 2.4** ### 属性 6: 颜色调整控件完整性 *对于任意*自定义界面的加载,应该显示头部、身体、脚部的独立颜色调整控件 **验证需求: 3.1, 3.2, 3.3, 3.4** ### 属性 7: 返回按钮规范性 *对于任意*自定义界面,返回按钮应该显示文字"返回"且尺寸满足最小触摸目标要求(44x44像素) **验证需求: 4.1, 4.2, 4.3, 4.5** ### 属性 8: 外观数据一致性 *对于任意*外观自定义操作,点击返回后角色创建界面的预览应该显示与自定义界面相同的外观 **验证需求: 5.1, 5.2** ### 属性 9: 角色创建外观应用 *对于任意*包含自定义外观的角色创建操作,创建的角色应该在游戏中显示相同的外观 **验证需求: 5.3, 5.4** ### 属性 10: 外观数据序列化往返 *对于任意*外观数据,序列化后再反序列化应该得到等价的数据对象 **验证需求: 5.5** ### 属性 11: 错误处理友好性 *对于任意*操作错误情况,系统应该显示用户友好的错误提示信息 **验证需求: 6.4** ### 属性 12: 移动设备适配性 *对于任意*移动设备尺寸,界面中的按钮应该满足最小触摸目标要求(44x44像素) **验证需求: 6.5** ### 属性 13: 系统扩展性 *对于任意*新增的颜色调整控件,系统应该能够动态集成并正常工作 **验证需求: 7.2** ### 属性 14: 数据结构扩展性 *对于任意*外观数据结构的新增字段,系统应该能够正确处理而不影响现有功能 **验证需求: 7.3** ### 属性 15: 渲染系统灵活性 *对于任意*类型的外观元素,预览系统应该能够正确渲染显示 **验证需求: 7.4** ### 属性 16: 操作按钮完整性 *对于任意*自定义界面的显示,应该提供重置和随机生成按钮 **验证需求: 8.1, 8.3** ### 属性 17: 重置功能正确性 *对于任意*外观自定义状态,点击重置按钮应该将所有设置恢复到进入界面时的初始状态 **验证需求: 8.2** ### 属性 18: 随机生成功能完整性 *对于任意*随机生成操作,应该为所有身体部位生成颜色并立即更新预览 **验证需求: 8.4, 8.5** ## 错误处理 ### 外观生成错误 **默认外观生成失败**: - 使用预设的备用外观方案 - 记录错误日志用于调试 - 显示友好的错误提示 **颜色数据无效**: - 验证颜色格式(十六进制) - 使用默认颜色替换无效值 - 提示用户重新选择 ### UI交互错误 **界面切换失败**: - 回退到上一个稳定状态 - 显示错误提示信息 - 提供重试选项 **动画执行错误**: - 跳过动画直接切换状态 - 确保功能正常可用 - 记录性能相关信息 ### 数据持久化错误 **外观数据保存失败**: - 保持当前界面状态 - 显示保存失败提示 - 提供重新保存选项 **数据序列化错误**: - 使用备用序列化方案 - 记录详细错误信息 - 确保数据不丢失 ## 测试策略 ### 单元测试 使用 Godot 的 GUT (Godot Unit Test) 框架进行单元测试。 **测试覆盖范围**: - 默认外观生成逻辑 - 颜色调整器功能 - 外观数据序列化/反序列化 - UI动画控制器 **示例测试**: ```gdscript # test_default_appearance_generator.gd extends GutTest func test_generate_default_appearance(): var appearance = DefaultAppearanceGenerator.generate_default_appearance() assert_true(appearance.has("head_color")) assert_true(appearance.has("body_color")) assert_true(appearance.has("foot_color")) assert_true(DefaultAppearanceGenerator.validate_appearance_data(appearance)) func test_fallback_appearance(): var fallback = DefaultAppearanceGenerator.get_fallback_appearance() assert_true(DefaultAppearanceGenerator.validate_appearance_data(fallback)) ``` ### 属性基础测试 使用 GDScript 实现的属性测试框架。 **测试库**: 自定义实现的 PropertyTester 类 **测试配置**: 每个属性测试至少运行 100 次迭代 **测试标注格式**: `# Feature: character-appearance-customization, Property X: [属性描述]` **属性测试覆盖**: 1. **属性 1: 默认外观生成完整性** - 生成多个随机角色创建请求 - 验证每次都生成完整的外观数据 2. **属性 2: 外观预览实时更新** - 生成随机外观修改操作 - 测量预览更新的响应时间 3. **属性 10: 外观数据序列化往返** - 生成随机外观数据 - 验证序列化往返的数据一致性 **示例属性测试**: ```gdscript # test_appearance_properties.gd extends GutTest # Feature: character-appearance-customization, Property 1: 默认外观生成完整性 func test_property_default_appearance_completeness(): for i in range(100): var appearance = DefaultAppearanceGenerator.generate_default_appearance() assert_true(appearance.has("head_color"), "应该包含头部颜色") assert_true(appearance.has("body_color"), "应该包含身体颜色") assert_true(appearance.has("foot_color"), "应该包含脚部颜色") assert_true(DefaultAppearanceGenerator.validate_appearance_data(appearance), "生成的外观数据应该有效") # Feature: character-appearance-customization, Property 10: 外观数据序列化往返 func test_property_appearance_serialization_roundtrip(): for i in range(100): var original_data = generate_random_appearance_data() var serialized = AppearanceDataManager.serialize_appearance(original_data) var deserialized = AppearanceDataManager.deserialize_appearance(serialized) assert_eq_deep(deserialized, original_data, "序列化往返应该保持数据一致性") func generate_random_appearance_data() -> Dictionary: return { "head_color": "#%06X" % (randi() % 0xFFFFFF), "body_color": "#%06X" % (randi() % 0xFFFFFF), "foot_color": "#%06X" % (randi() % 0xFFFFFF), "created_at": Time.get_unix_time_from_system(), "version": "1.0" } ``` ### 集成测试 **UI集成测试**: - 测试完整的外观自定义流程 - 验证界面切换的正确性 - 检查动画效果的执行 **数据集成测试**: - 测试外观数据在不同组件间的传递 - 验证预览与实际角色的一致性 - 检查数据持久化的完整性 ### 用户体验测试 **响应时间测试**: - 测试颜色调整的响应延迟 - 目标: 预览更新 < 100ms **动画流畅性测试**: - 测试界面切换动画的帧率 - 目标: 保持 30+ FPS **触摸友好性测试**: - 验证移动设备上的按钮尺寸 - 目标: 最小触摸目标 44x44 像素 ## 实现细节 ### 界面布局设计 **自定义界面布局**: ``` ┌─────────────────────────────────────────┐ │ [返回] 角色外观自定义 │ ├─────────────────────────────────────────┤ │ │ │ ┌─────────────────────────────────────┐ │ │ │ 角色预览区域 │ │ │ │ ┌─────────────────────────────┐ │ │ │ │ │ [角色预览图像] │ │ │ │ │ └─────────────────────────────┘ │ │ │ └─────────────────────────────────────┘ │ │ │ │ 头部颜色: │ │ ┌───┐┌───┐┌───┐┌───┐┌───┐ [颜色选择器] │ │ │ ● ││ ● ││ ● ││ ● ││ ● │ │ │ └───┘└───┘└───┘└───┘└───┘ │ │ │ │ 身体颜色: │ │ ┌───┐┌───┐┌───┐┌───┐┌───┐ [颜色选择器] │ │ │ ● ││ ● ││ ● ││ ● ││ ● │ │ │ └───┘└───┘└───┘└───┘└───┘ │ │ │ │ 脚部颜色: │ │ ┌───┐┌───┐┌───┐┌───┐┌───┐ [颜色选择器] │ │ │ ● ││ ● ││ ● ││ ● ││ ● │ │ │ └───┘└───┘└───┘└───┘└───┘ │ │ │ │ ┌─────────┐ ┌─────────┐ ┌─────────┐ │ │ │ 重置 │ │ 随机生成 │ │ 保存 │ │ │ └─────────┘ └─────────┘ └─────────┘ │ └─────────────────────────────────────────┘ ``` ### 动画时序设计 **界面切换动画序列**: 1. 用户点击"自定义外观"按钮 (0ms) 2. 开始淡出动画:创建按钮和名称输入框 (0-300ms) 3. 开始滑入动画:自定义界面从右侧滑入 (200-500ms) 4. 完成所有动画,自定义界面完全显示 (500ms) **颜色更新动画**: 1. 用户选择新颜色 (0ms) 2. 触发颜色变化事件 (0-10ms) 3. 开始预览更新动画 (10-60ms) 4. 完成颜色过渡效果 (60-100ms) ### 性能优化 **渲染优化**: - 使用对象池管理颜色按钮 - 延迟加载颜色选择器 - 缓存预览渲染结果 **内存优化**: - 及时释放未使用的UI元素 - 使用弱引用避免循环引用 - 压缩颜色预设数据 **响应性优化**: - 异步处理颜色计算 - 使用防抖机制减少频繁更新 - 优先处理用户交互事件 ## 扩展性考虑 ### 未来功能预留 **更多自定义选项**: - 发型选择 - 服装样式 - 配饰系统 - 表情自定义 **高级功能**: - 外观模板保存/加载 - 社区外观分享 - AI辅助外观生成 - 外观历史记录 ### 数据结构扩展 **版本化数据格式**: ```gdscript { "version": "2.0", "appearance": { "head": { "color": "#F5DEB3", "style": "default", "accessories": [] }, "body": { "color": "#4169E1", "clothing": "shirt", "pattern": "solid" }, "foot": { "color": "#8B4513", "shoe_type": "sneakers" } }, "metadata": { "created_at": 1234567890, "last_modified": 1234567890, "tags": ["custom", "colorful"] } } ``` ### API设计 **外观系统API**: ```gdscript # 外观管理器接口 class_name AppearanceManager static func create_customizer() -> AppearanceCustomizer static func register_part_adjuster(part: String, adjuster: ColorAdjuster) -> void static func get_supported_parts() -> Array[String] static func validate_appearance_data(data: Dictionary, version: String) -> bool static func migrate_appearance_data(data: Dictionary, from_version: String, to_version: String) -> Dictionary ``` 这种设计确保了系统的可扩展性,为未来添加更多自定义功能提供了坚实的基础。