Skip to content

fix(Skel38BinWriter): 修复动画时间线计数错误,排除SLOT_ALPHA类型#25

Open
Agent-0808 wants to merge 1 commit intowang606:mainfrom
Agent-0808:fix/TimelineType_SlotAlpha
Open

fix(Skel38BinWriter): 修复动画时间线计数错误,排除SLOT_ALPHA类型#25
Agent-0808 wants to merge 1 commit intowang606:mainfrom
Agent-0808:fix/TimelineType_SlotAlpha

Conversation

@Agent-0808
Copy link
Copy Markdown

@Agent-0808 Agent-0808 commented Apr 7, 2026

修复 Slot 时间线数量计算问题(4.2 转 3.8)

:本提交由 LLM 分析定位问题并修复,经我人工测试验证通过。我不熟悉 Spine 内部格式细节。

问题描述

发现一个特定 Spine 4.2 版本的骨骼数据转换为 3.8 版本时,转换后的文件无法在 Spine 中打开的问题。

错误信息:

IndexOutOfBoundsException: index can't be >= size: 63 >= 0

修复说明

问题原因

Spine 4.2 引入了 SLOT_ALPHA 时间线类型,但 3.8 版本不支持此类型。

原代码在写入时间线数量时,写入了包含 SLOT_ALPHA 的总数,但在实际写入数据时跳过了 SLOT_ALPHA 时间线。这导致 Spine 3.8 读取时期待的时间线数量与实际写入的数量不匹配,引发数组越界错误。

修复方案

在写入时间线数量前,先计算实际会写入的时间线数量(排除 SLOT_ALPHA)。

文件: src/SkeletonData38BinaryWriter.cpp

修改位置: writeAnimation() 函数中 Slot 时间线序列化部分(约第 244 行)

修改前:

writeVarint(binary, slotIndex, true);
writeVarint(binary, multiTimeline.size(), true);  // 错误:包含 SLOT_ALPHA
for (const auto& [timelineName, timeline] : multiTimeline) {
    SlotTimelineType timelineType = slotTimelineTypeMap.at(timelineName);
    if (timelineType == SlotTimelineType::SLOT_ALPHA) continue;
    // ... 写入时间线数据
}

修改后:

writeVarint(binary, slotIndex, true);
int timelineCount = 0;
for (const auto& [timelineName, timeline] : multiTimeline) {
    SlotTimelineType timelineType = slotTimelineTypeMap.at(timelineName);
    if (timelineType != SlotTimelineType::SLOT_ALPHA) timelineCount++;
}
writeVarint(binary, timelineCount, true);  // 正确:排除 SLOT_ALPHA
for (const auto& [timelineName, timeline] : multiTimeline) {
    SlotTimelineType timelineType = slotTimelineTypeMap.at(timelineName);
    if (timelineType == SlotTimelineType::SLOT_ALPHA) continue;
    // ... 写入时间线数据
}

测试验证

测试文件

ch0309_home.zip

  • 输入: CH0309_home.skel(Spine 4.2 版本,包含 Alpha 时间线)
  • 输出: 转换为 Spine 3.8 .skel 格式
SpineSkeletonDataConverter.exe CH0309_home.skel ./38/CH0309_home.skel -v 3.8.75

测试结果

  • 转换前:文件在 Spine 3.8 中无法打开,报错 IndexOutOfBoundsException
  • 转换后:文件在 Spine 3.8 中可正常打开

影响范围

  • 仅影响 4.2 → 3.8 的转换路径
  • 风险较低:代码改动简单,逻辑清晰
  • 不影响其他版本转换

检查清单

  • 修复了特定问题(4.2 转 3.8 失败)
  • 经测试验证可正常使用
  • 代码符合项目风格

修改动画二进制写入逻辑,正确计算非SLOT_ALPHA类型的时间线数量。
原实现错误地包含了所有时间线,现通过遍历检查类型来准确计数。
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant