Files
2025-12-05 19:00:14 +08:00

23 KiB
Raw Permalink Blame History

角色外观自定义系统设计文档

概述

本设计文档描述了为现有 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)

职责: 为新角色生成协调的默认外观

接口:

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)

职责: 处理单个身体部位的颜色调整

接口:

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)

职责: 实时显示角色外观预览

接口:

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)

职责: 管理界面切换和元素动画

接口:

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)

职责: 管理外观数据的存储、加载和验证

接口:

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

数据结构:

{
    "head_color": "#F5DEB3",      # 头部颜色 (十六进制)
    "body_color": "#4169E1",      # 身体颜色
    "foot_color": "#8B4513",      # 脚部颜色
    "created_at": 1234567890,     # 创建时间戳
    "version": "1.0"              # 数据版本
}

数据模型

外观数据结构

# 完整的外观数据模型
{
    "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
    }
}

颜色预设数据

# 预设颜色方案
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动画控制器

示例测试:

# 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: 外观数据序列化往返

    • 生成随机外观数据
    • 验证序列化往返的数据一致性

示例属性测试:

# 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辅助外观生成
  • 外观历史记录

数据结构扩展

版本化数据格式:

{
    "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:

# 外观管理器接口
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

这种设计确保了系统的可扩展性,为未来添加更多自定义功能提供了坚实的基础。