diff --git a/spine-unity/Assets/Spine/Documentation/4.3-split-component-upgrade-guide-zh.md b/spine-unity/Assets/Spine/Documentation/4.3-split-component-upgrade-guide-zh.md index 7284934bd..365a3147e 100644 --- a/spine-unity/Assets/Spine/Documentation/4.3-split-component-upgrade-guide-zh.md +++ b/spine-unity/Assets/Spine/Documentation/4.3-split-component-upgrade-guide-zh.md @@ -1,207 +1,233 @@ -# spine-unity 4.3 分离组件升级指南 +# spine-unity 4.3 模块化组件升级指南 + ## 组件架构重构 --- -## 📋 本文档范围 +## 📋 本指南的适用范围 -**本文档仅涵盖 spine-unity 组件分离迁移。** 从 4.2 版本到 4.3 版本,spine-csharp 和 spine-unity 中还有其他破坏性更改,您需要在处理组件分离之前解决这些问题: +**本文档仅涵盖 spine-unity 模块化组件迁移流程.** 当从 4.2 升级至 4.3 时, spine-csharp 和 spine-unity 中仍包含其他破坏性更改, 在着手模块化组件升级前应先解决这些问题: -- **spine-csharp API 更改:** 影响骨骼、插槽和约束属性的新姿势系统 +* **spine-csharp API 变更:** 全新引入的姿态(pose)系统显著地改变了访问骨骼、槽位和约束属性的方式 -有关涵盖所有 4.2 到 4.3 更改的完整迁移步骤,请参阅: -- [CHANGELOG.md](https://github.com/EsotericSoftware/spine-runtimes/blob/4.3-beta/CHANGELOG.md#c-2) 文档(C# 和 Unity 部分) -- 论坛帖子 ["Spine-Unity 4.2 to 4.3 Upgrade Guide"](https://esotericsoftware.com/forum) 以获取全面的迁移指南 +如需获取涵盖 4.2 至 4.3 所有变更的完整迁移步骤, 请参阅以下官方文档: -**重要:** 首先完成 spine-csharp API 迁移,然后继续执行本文档中描述的组件分离迁移。 +* 运行时 [CHANGELOG.md](https://github.com/EsotericSoftware/spine-runtimes/blob/4.3-beta/CHANGELOG.md#c-2) 的 C# 和 Unity 一节 +* 论坛置顶帖 ["Spine-Unity 4.2 to 4.3升级指南"](https://zh.esotericsoftware.com/forum/d/29263-zh-cnspine-unity-42-to-43%E5%8D%87%E7%BA%A7%E6%8C%87%E5%8D%97) + +**重要提示:** 请务必优先完成 spine-csharp API 的迁移, 再依据本指南执行模块化组件迁移操作. --- -## ⚠️ 重要提示:升级前必读 +## ⚠️ 重要提醒: 升级前须知 -**此警告仅适用于正在升级的现有项目。新项目可以安全地忽略此部分。** +**本提醒仅用于升级现有项目, 新项目可忽略本节内容.** -### 将会发生什么 +### 升级后将发生的变化 -组件将**自动升级**并分离为独立的动画和渲染组件: -- `SkeletonAnimation` → `SkeletonAnimation` + `SkeletonRenderer` 组件 -- `SkeletonMecanim` → `SkeletonMecanim` + `SkeletonRenderer` 组件 -- `SkeletonGraphic` → `SkeletonAnimation` + `SkeletonGraphic` 组件 +组件将**自动升级**并分离为相互独立的动画与渲染组件: -所有组件设置和字段将自动转移 - 不会丢失任何内容。 +* `SkeletonAnimation` → `SkeletonAnimation` + `SkeletonRenderer` 组件 +* `SkeletonMecanim` → `SkeletonMecanim` + `SkeletonRenderer` 组件 +* `SkeletonGraphic` → `SkeletonAnimation` + `SkeletonGraphic` 组件 -**但是:** 由于这些类型更改,您自定义脚本中的现有引用可能会丢失,因为组件类型不再匹配(例如,`SkeletonAnimation` 不再是 `SkeletonRenderer` 的子类)。 +所有组件设置与字段将被自动迁移 - 不会造成数据丢失. -### 必需的升级步骤(按顺序): +**但请注意:** 由于变更了组件类型, 项目脚本中对原组件的引用可能失效 (例如, `SkeletonAnimation` 不再继承自 `SkeletonRenderer`). -1. **🔒 备份您的项目** - 在升级之前创建完整备份。这些更改将修改您的场景和预制件。 +### 必须****依序****执行的项目升级步骤 -2. **📖 阅读整个文档** - 在继续之前了解所有破坏性更改。 +1. **🔒 备份项目** + 在升级前请完整备份项目. 升级操作将修改场景与预制件文件. -3. **✏️ 测试并更新您的代码** - - **更新您的脚本:** 根据本文档修复引用 Spine 组件的自定义脚本,因为当成员被移动到分离的类时,您的代码可能无法编译 - - **测试:** 打开一些测试场景以查看哪些组件引用丢失。未保存的场景仍然包含旧的组件数据并作为安全备份 - 只有当您保存时,分离的组件才会替换旧组件并且引用会丢失。 - **⚠️ 警告:** 预制件的行为不同!在 Prefab Edit Mode 中打开预制件会由于 Unity 的预制件自动保存功能而自动保存组件迁移。请始终先用场景进行测试,而不是预制件。 - - **决定:** 要么手动重新分配丢失的引用,要么编写迁移代码(下面说明)来自动处理 +2. **📖 通读本指南全文** + 在执行升级操作前, 务必充分理解全部的破坏性变更点. - **⚠️ 重要:** 自动组件分离仅在 Unity 编辑器中打开场景/预制件时发生。您必须选择 `Upgrade All` 或保存每个场景/预制件后再构建游戏,否则旧的单一组件不会被分离,构建中可能会缺少一半所需的组件! +3. **✏️ 测试并更新你的代码** + * **更新代码:** 根据本指南修正所有引用了 Spine 组件的脚本, 由于类成员已迁移至模块化类, 项目代码将可能无法编译. + * **测试:** 打开若干测试场景, 检查丢了失哪些引用. 未保存的场景仍会保留旧组件数据, 不妨将其作为安全备份——仅当你保存场景后旧组件才会被替换为模块化组件, 此时旧的组件引用便会失效. + **⚠️ 警告:** 小心对待预制件(Prefab)! 在预制件编辑模式中打开预制件的话, 它会因 Unity 的自动保存机制立即触发组件迁移. 请优先在场景范围内测试, 避免直接操作预制体. + * **可选操作:** 也可以一个个地手动重新分配丢失的引用, 或编写一套自动化迁移脚本(详见下文)来自动迁移组件. - **💡 提示:** 如果您遇到控制台日志输出 "SendMessage cannot be called during Awake, CheckConsistency, or OnValidate",这表明场景中存在旧的未迁移资产,它们刚刚被自动升级。这些消息之后会跟随一条日志消息,确认旧组件已自动迁移为分离组件。 + **⚠️ 重要提示:** 自动组件升级仅在 Unity 编辑器打开了场景或预制件时触发. 在构建项目前, 你必须选择 'Upgrade All' 或逐一保存所有场景与预制件来确保没有残留旧组件, 否则可能导致构建中缺失必要组件而失败! -4. **🔄 选择您的升级路径** + **💡 提示:** 若控制台输出信息中包含 "SendMessage cannot be called during Awake, CheckConsistency, or OnValidate" 字样,则表明场景中的旧资产已完成自动升级. 此消息将后附日志信息来确认旧组件已成功迁移至模块化组件. - **选项 A - 手动重新分配(推荐用于小型项目):** - - 逐个打开每个场景和预制件 - - 在检查器中手动重新分配丢失的引用 - - 满意后保存 +4. **🔄 选择升级方式** - **选项 B - 自动迁移(用于具有许多场景/预制件的大型项目):** - - 首先编写迁移代码: - - 实现引用迁移模式(参见下面的"防止丢失组件引用"部分) - - 对于 `SkeletonGraphic` 引用,请参见"将现有引用更改为 SkeletonAnimation"部分 - - 在几个文件上测试迁移代码 - - 然后使用 `Upgrade All`: - - 转到 `Edit → Preferences → Spine` - - 在 `Upgrade Scenes & Prefabs` 下 - - 点击 `Upgrade All` 按钮 + **选项 A - 手动重分配 (推荐小型项目采用):** + * 逐一打开各场景与预制件 + * 在检查器(Inspector)中手动分配缺失的引用 + * 确认无误后保存 -### 如果您不准备会发生什么破坏: -- 一旦您保存场景或预制件,场景或预制件中的组件引用可能会丢失(设置为 null) -- 在升级所有场景/预制件之前构建将导致构建中缺少组件 + **选项 B - 自动化迁移 (推荐含大量场景/预制件的大型项目采用):** + * 首先编写迁移代码: + * 实现引用迁移模式 (详见下文中的 "防止丢失组件引用" 一节) + * 对于 `SkeletonGraphic` 的引用, 请见 "将已有引用迁至 SkeletonAnimation" 一节 + * 在少量文件上测试迁移代码 + * 使用 `Upgrade All` 按钮: + * 打开 `Edit → Preferences → Spine` + * 在 "Upgrade Scenes & Prefabs" 中 + * 点击 `Upgrade All` 按钮 -**在完成步骤 1-3 之前不要继续,否则您可能会破坏您的项目。** +### 若仓促升级可能会导致以下后果 + +* 场景或预制件中的 Spine 组件引用在保存后将丢失 (引用被置null) + +* 在未能升级全部场景/预制件便匆忙执行构建, 可能导致构建过程中缺失必要组件而失败 + +**请勿跳过步骤 1-3, 否则项目极有可能遭到破坏.** --- -## 📦 从 4.2 的可选两步迁移 +## 📦 可选方案: 4.2 版的两阶段迁移 -如果您正在从 spine-unity 4.2 迁移,您可能会发现分两步升级更容易隔离潜在问题: +若你正从 spine-unity 4.2 升级至最新版, 建议遵循两阶段迁移方案来隔离潜在问题: -### 步骤 1:升级到 4.3-beta 预分离版本 -首先升级到组件分离更改之前的 4.3-beta 版本: -- **提交哈希**: `a07b1de` -- **通过 Git URL 添加包**: `https://github.com/EsotericSoftware/spine-runtimes.git?path=spine-csharp/src#a07b1de` -- 或 **unitypackage**: https://esotericsoftware.com/files/runtimes/unity/spine-unity-4.2-2025-09-26.unitypackage +### 阶段 1: 升级至 4.3-beta 非模块化组件版本 -此中间步骤允许您: -- 首先修复与 4.2 → 4.3 spine-csharp API 更改相关的任何问题并确保您的项目正常工作 -- 在继续之前验证您的项目是否稳定 -- 一旦您的项目使用此 4.3-beta 版本正常工作,在继续步骤 2 之前创建另一个备份 +First upgrade to a 4.3-beta version before the component split changes: -### 步骤 2:升级到最新的 4.3-beta 版本(带有分离的组件) -一旦您的项目使用 4.3-beta 正常工作: -- 升级到最新的 4.3-beta 包 -- 按照上面的组件分离迁移指南 -- 处理分离的动画和渲染组件 +* **Commit Hash**: `a07b1de` +* **使用 Git URL 添加包**: `https://github.com/EsotericSoftware/spine-runtimes.git?path=spine-csharp/src#a07b1de` +* 或使用 **unitypackage**: -这种两步方法有助于隔离问题 - 如果出现问题,您将知道是由于 4.2 → 4.3 spine-csharp 更改还是组件分离特定导致的。 +这一阶段可以: + +* 优先解决 4.2 → 4.3 spine-csharp API 变更问题, 同时确保项目正常 +* 在升级模块化组件前验证项目稳定性 +* 确认项目在 4.3-beta 下稳定后, 有机会再次备份完整项目, 为阶段 2的迁移工作作出充分准备 + +### 阶段 2: 升级至最新的 4.3-beta 模块化组件版本 + +当项目能够在 4.3-beta 非模块化组件版下稳定工作后: + +* Up升级至最新 4.3-beta 包 +* 按照本指南所述执行模块化组件迁移 +* 处理独立的动画与渲染组件 + +这种两阶段策略可有效隔离问题源头: 项目出现故障时, 可以明确地判断出是 4.2 → 4.3 的 spine-csharp API 变更导致的, 还是模块化组件所致. --- -## 📋 介绍 +## 📋 简介 -spine-unity 4.3 运行时引入了一个重大的架构更改:**通过使用两个独立的组件而不是组件继承来分离动画和渲染**。这使得灵活的组合成为可能,例如使用 `SkeletonMecanim` 进行动画和 `SkeletonGraphic` 进行渲染,这在以前是不可能的。 +spine-unity 4.3 运行时引入了重大架构变更: **相互独立的动画与渲染组件取代原有的继承结构**. 该设计让用户可灵活地选用组件, 例如在项目中让 `SkeletonMecanim` 负责控制动画, 同时采用 `SkeletonGraphic` 执行渲染——这是此前无法实现的. -### 主要更改: -- **组件分离**: 以前的单一组件已分离为独立的渲染和动画组件。 -- **独立组件**: `SkeletonAnimation` 和 `SkeletonMecanim` 不再继承自 `SkeletonRenderer`。它们现在与单独的渲染器组件(`ISkeletonRenderer` 的子类)一起工作,例如 `SkeletonRenderer` 和 `SkeletonGraphic`。 -- **接口更新**: 新的 `ISkeletonRenderer` 和 `ISkeletonAnimation` 接口具有更新的属性名称。 -- **设置分组**: 网格生成设置现在分组在 `MeshSettings` 属性下。 -- **自动迁移**: 当定义了 `AUTO_UPGRADE_TO_43_COMPONENTS`(*默认*)时,Unity 编辑器将自动升级您的组件到新的分离组件并转移已弃用的字段。 -- **升级所有场景和预制件**: 要一次升级所有场景和预制件,请转到 `Edit - Preferences - Spine` 并在 `Automatic Component Upgrade` 下点击 `Upgrade Scenes & Prefabs` - `Upgrade All`。 +### 关键更改 -### 组件关系: +* **模块化组件**: 旧组件被拆分为了相互独立的渲染与动画组件. + +* **独立组件架构**: `SkeletonAnimation` 和 `SkeletonMecanim` 不再继承自 `SkeletonRenderer`, 而是与独立渲染器组件(`ISkeletonRenderer` 的子类)协同工作, 例如 `SkeletonRenderer` 和 `SkeletonGraphic`. +* **接口更新**: 新增了命名统一的 `ISkeletonRenderer` 和 `ISkeletonAnimation` 接口. +* **设置分组**: 网格生成的相关设置集中到了 `MeshSettings` 属性中. +* **自动化迁移**: 当启用 `AUTO_UPGRADE_TO_43_COMPONENTS` (*此版本默认启用*)后, Unity 编辑器将自动升级组件并迁移已废弃的字段. +* **升级全部场景和预制件**: 如需一键升级全部场景与预制件, 请打开 `Edit - Preferences - Spine`, 并在 `Automatic Component Upgrade` 中点击 `Upgrade Scenes & Prefabs` - `Upgrade All` 即可. + +### 各组件关系 | **旧架构** | **新架构** | |---------------------|---------------------| | `SkeletonAnimation` 继承自 `SkeletonRenderer` | `SkeletonAnimation` + 独立的 `SkeletonRenderer` 组件 | | `SkeletonMecanim` 继承自 `SkeletonRenderer` | `SkeletonMecanim` + 独立的 `SkeletonRenderer` 组件 | -| `SkeletonGraphic` 提供嵌入式 AnimationState | `SkeletonGraphic` + 独立的 `SkeletonAnimation` 组件 | +| `SkeletonGraphic` 内置 AnimationState | `SkeletonGraphic` + 独立的 `SkeletonAnimation` 组件 | --- -## 调整您的代码 +## 适配你的代码 -以下是每个组件的更改: +以下为各组件的具体变更说明: ## ▶️ SkeletonRenderer -### 破坏性更改 +### 破坏性变更 -#### 1. 接口更改 -- `IHasSkeletonRenderer` 接口属性名称从 `SkeletonRenderer` 更改为 `Renderer`,类型从 `SkeletonRenderer` 更改为 `ISkeletonRenderer`。 +#### 1. 接口变更 -#### 2. 事件更改 -- `SkeletonRendererDelegate` 类型不再是 `SkeletonRenderer` 中的嵌套类型。 - 要修复任何编译错误,请将 `SkeletonRenderer.SkeletonRendererDelegate` 替换为 `SkeletonRendererDelegate`。 -- `BeforeApply` 委托类型从 `SkeletonRendererDelegate` 更改为 `SkeletonAnimationDelegate`。 -- `SkeletonRendererDelegate` 类型从 `SkeletonRendererDelegate(SkeletonRenderer)` 更改为 `SkeletonRendererDelegate(ISkeletonRenderer)`。这影响事件:`OnRebuild`、`OnMeshAndMaterialsUpdated`。 - 要修复任何编译错误,请将您的方法参数从 `SkeletonRenderer` 更改为 `ISkeletonRenderer`。 -- 将骨骼事件 `UpdateLocal`、`UpdateWorld` 和 `UpdateComplete` 从 `ISkeletonAnimation` 类(`SkeletonAnimation`、`SkeletonMecanim`)移动到 `ISkeletonRenderer` 类(SkeletonRenderer、SkeletonGraphic)。委托类型从 `UpdateBonesDelegate` 更改为 `SkeletonRendererDelegate`,参数为 `ISkeletonRenderer` 而不是 `ISkeletonAnimation`。 +* 接口 `IHasSkeletonRenderer` 中的属性名 `SkeletonRenderer` 改为 `Renderer`, 类型由 `SkeletonRenderer` 改为 `ISkeletonRenderer`. -#### 2. 方法更改 -- `LateUpdateMesh()` 已更改为 `UpdateMesh()`。 -- 移除 `MeshGenerator.TryReplaceMaterials`。 +#### 2. 事件变更 + +* `SkeletonRendererDelegate` 类型不再为 `SkeletonRenderer` 的嵌套类型. + 如需修复编译错误, 只需将 `SkeletonRenderer.SkeletonRendererDelegate` 替换为 `SkeletonRendererDelegate`. + +* `BeforeApply` 委托类型由 `SkeletonRendererDelegate` 更改为 `SkeletonAnimationDelegate`. +* `SkeletonRendererDelegate` 委托签名由 `SkeletonRendererDelegate(SkeletonRenderer)` 更改为 `SkeletonRendererDelegate(ISkeletonRenderer)`. 该更改会影响以下事件: `OnRebuild`, `OnMeshAndMaterialsUpdated`. + 如需修复编译错误, 只需将方法实参从 `SkeletonRenderer` 更改为 `ISkeletonRenderer`. +* 骨骼事件 `UpdateLocal`, `UpdateWorld`, 和 `UpdateComplete` 从 `ISkeletonAnimation` 类 (`SkeletonAnimation`, `SkeletonMecanim`) 迁移至 `ISkeletonRenderer (SkeletonRenderer, SkeletonGraphic)` 类中. 委托类型由 `UpdateBonesDelegate` 改为 `SkeletonRendererDelegate`, 参数由 `ISkeletonRenderer` 改为了 `ISkeletonAnimation`. + +#### 2. 方法变更 + +* `LateUpdateMesh()` 改为了 `UpdateMesh()`. + +* 移除了 `MeshGenerator.TryReplaceMaterials`. #### 3. 执行顺序 -- `SkeletonRenderer` 和 `SkeletonGraphic` 组件收到 `DefaultExecutionOrder(1)]`,使它们在默认*(order=0)*脚本之后运行。这确保即使 `UpdateTiming` 设置为 `InLateUpdate`,动画也会在骨架更新之前应用。 -#### 4. 行为更改 -- 当 `singleSubmesh` 启用时,`generateMeshOverride` 现在也会被调用。 +* `SkeletonRenderer` 和 `SkeletonGraphic` 组件接受 `DefaultExecutionOrder(1)]` 参数, 以确保其在默认脚本*(即 order=0)*之后执行. 此举保证了即使 `UpdateTiming` 置为 `InLateUpdate`, 动画仍能先于 skeleton 更新. -### 字段和属性迁移 +#### 4. 行为变更 -#### 网格生成设置 -| **旧 API** | **新 API** | **备注** | +* 在启用 `singleSubmesh` 后, 现在也会调用 `generateMeshOverride`. + +### 字段与属性迁移 + +#### 网格生成器设置 + +| **旧 API** | **新 API** | **说明** | |-------------------|-------------------|-----------| -| `skeletonRenderer.zSpacing` | `skeletonRenderer.MeshSettings.zSpacing` | 移动到 MeshSettings | -| `skeletonRenderer.useClipping` | `skeletonRenderer.MeshSettings.useClipping` | 移动到 MeshSettings | -| `skeletonRenderer.immutableTriangles` | `skeletonRenderer.MeshSettings.immutableTriangles` | 移动到 MeshSettings | -| `skeletonRenderer.pmaVertexColors` | `skeletonRenderer.MeshSettings.pmaVertexColors` | 移动到 MeshSettings | -| `skeletonRenderer.tintBlack` | `skeletonRenderer.MeshSettings.tintBlack` | 移动到 MeshSettings | -| `skeletonRenderer.addNormals` | `skeletonRenderer.MeshSettings.addNormals` | 移动到 MeshSettings | -| `skeletonRenderer.calculateTangents` | `skeletonRenderer.MeshSettings.calculateTangents` | 移动到 MeshSettings | +| `skeletonRenderer.zSpacing` | `skeletonRenderer.MeshSettings.zSpacing` | 已迁移至 MeshSettings | +| `skeletonRenderer.useClipping` | `skeletonRenderer.MeshSettings.useClipping` | 已迁移至 MeshSettings | +| `skeletonRenderer.immutableTriangles` | `skeletonRenderer.MeshSettings.immutableTriangles` | 已迁移至 MeshSettings | +| `skeletonRenderer.pmaVertexColors` | `skeletonRenderer.MeshSettings.pmaVertexColors` | 已迁移至 MeshSettings | +| `skeletonRenderer.tintBlack` | `skeletonRenderer.MeshSettings.tintBlack` | 已迁移至 MeshSettings | +| `skeletonRenderer.addNormals` | `skeletonRenderer.MeshSettings.addNormals` | 已迁移至 MeshSettings | +| `skeletonRenderer.calculateTangents` | `skeletonRenderer.MeshSettings.calculateTangents` | 已迁移至 MeshSettings | #### 已弃用的小写属性 -- 小写属性 `initialFlipX`、`initialFlipY` 和 `initialSkinName` 现已弃用,将在未来的运行时版本中删除。使用添加的相同名称但大写的属性:`InitialFlipX`、`InitialFlipY` 和 `InitialSkinName`。 + +* 小写属性 `initialFlipX`, `initialFlipY` 和 `initialSkinName` 已被弃用并将于后续版本中移除. 请转用同名大写属性 `InitialFlipX`, `InitialFlipY` 和 `InitialSkinName`. --- ## ▶️ SkeletonAnimation -### 破坏性更改 +### 破坏性变更 #### 1. 组件架构 -- **SkeletonAnimation 现在是与 SkeletonRenderer 分离的组件**,不再是子类。 -- 通过以下方式访问渲染器:`skeletonAnimation.Renderer`。 -- 从渲染器访问动画:`skeletonRenderer.Animation`。 -#### 2. 属性更改 -- `state` 不再是公共的。使用 `AnimationState` 属性代替。 -- `valid` 已移除。使用 `IsValid` 代替。 +* **SkeletonAnimation 现为独立于 SkeletonRenderer 的组件**, 不再继承自 SkeletonRenderer. -#### 3. 方法更改 -- 添加 `UpdateOncePerFrame()` - 如果本帧尚未调用 `Update` 则更新。现有的 `Update(float time)` 仍然在调用时始终更新。 -- 不带参数的 `Update()` 不再是公共的,使用 `UpdateOncePerFrame()` 在本帧未执行更新时更新, -或使用 `Update(0)` 强制动画更新。 +* 如需访问渲染器: `skeletonAnimation.Renderer`. +* 如需通过渲染器访问动画: `skeletonRenderer.Animation`. -### 字段和属性迁移 +#### 2. 属性变更 -由于 `SkeletonAnimation` 现在是一个独立的组件,`SkeletonRenderer` 提供的方法和属性不能再通过 `SkeletonAnimation` 对象直接访问。有一个 `skeletonAnimation.Renderer` 属性可用于从 `SkeletonAnimation` 对象访问关联的 `ISkeletonRenderer`, -以及一个 `skeletonRenderer.Animation` 属性从 `SkeletonRenderer` 或 `SkeletonGraphic` 对象访问关联的 `ISkeletonAnimation`。对于 `ISkeletonRenderer` 接口未公开的成员,您可以将 `skeletonAnimation.Renderer` 转换为 `SkeletonRenderer` 或 `SkeletonGraphic` 以访问渲染器成员变量。 +* `state` 不再是公开属性. 请转用 `AnimationState` 属性. + +* 移除了 `valid`. 请转用 `IsValid` 属性. + +#### 3. 方法变更 + +* 新增 `UpdateOncePerFrame()` - 仅在该帧未调用 `Update` 时执行更新. 已有的 `Update(float time)` 保持行为不变. + +* 不再公开无参 `Update()` 方法, 如需仅在该帧无更新时执行更新, 请使用 `UpdateOncePerFrame()`, 而 `Update(0)` 可用于强制执行一次动画更新. + +### 字段与属性迁移 + +由于 `SkeletonAnimation` 现已成为独立组件, 曾由 `SkeletonRenderer` 提供的方法与属性将无法直接通过 `SkeletonAnimation` 实例访问. 请通过 `SkeletonAnimation` 实例的 `ISkeletonRenderer` 访问渲染器属性 `skeletonAnimation.Renderer`, 而 `skeletonRenderer.Animation` 属性则可通过 `SkeletonRenderer` 或 `SkeletonGraphic` 实例中的 `ISkeletonAnimation` 访问. 对于未在 `ISkeletonRenderer` 接口中暴露的成员, 可将 `skeletonAnimation.Renderer` 显式转换为 `SkeletonRenderer` 或 `SkeletonGraphic` 以访问渲染器成员变量. ### 示例代码 + ```csharp -// 旧的从 SkeletonAnimation 访问 SkeletonRenderer 属性 +// 升级前: 直接访问 SkeletonRenderer 属性 skeletonAnimation.zSpacing = 0.1f; skeletonAnimation.AnySkeletonRendererProperty; -// 新的从 SkeletonAnimation 访问 SkeletonRenderer 属性 -skeletonAnimation.Renderer.MeshSettings.zSpacing = 0.1f; // 在 ISkeletonRenderer 接口中公开 +// 升级后: 通过 Renderer 对象访问 +skeletonAnimation.Renderer.MeshSettings.zSpacing = 0.1f; // 访问 ISkeletonRenderer 接口暴露出的成员 var skeletonRenderer = (SkeletonRenderer)skeletonAnimation.Renderer; -skeletonRenderer.AnySkeletonRendererProperty; // 未在 ISkeletonRenderer 接口中公开 +skeletonRenderer.AnySkeletonRendererProperty; // 访问 ISkeletonRenderer 接口未暴露的成员 ``` @@ -209,159 +235,180 @@ skeletonRenderer.AnySkeletonRendererProperty; // 未在 ISkeletonRenderer 接口 ## ▶️ SkeletonMecanim -### 破坏性更改 +### 破坏性变更 #### 1. 组件架构 -- **SkeletonMecanim 现在是与 SkeletonRenderer 分离的组件**,不再是子类。 -- 与 [SkeletonAnimation](#▶️-skeletonanimation) 相同的访问模式。 -#### 2. 方法更改 -- `Update()` 不再是公共的。 -- 使用 `UpdateIfNecessary()` 或 `Update(0)` 强制更新。 +* **SkeletonMecanim 现为独立于 SkeletonRenderer 的组件**, 不再继承自 SkeletonRenderer. -### 字段和属性迁移 +* 访问方式同 [SkeletonAnimation](#▶️-skeletonanimation). -与上面的 [SkeletonAnimation](#▶️-skeletonanimation) 相同。 +#### 2. 方法变更 + +* 不再公开 `Update()`. + +* 请改用 `UpdateIfNecessary()`, 如需强制更新请使用 `Update(0)`. + +### 字段与属性迁移 + +与上文中的 [SkeletonAnimation](#▶️-skeletonanimation) 相同 --- ## ▶️ SkeletonGraphic -### 破坏性更改 +### 破坏性变更 #### 1. 组件架构 -- **SkeletonGraphic 不再涵盖动画,添加 SkeletonAnimation 作为独立的动画组件**。 -- 通过以下方式访问动画:`skeletonGraphic.Animation`。 -#### 2. 将现有引用更改为 SkeletonAnimation +* **SkeletonGraphic 不再涉及动画逻辑, 请额外添加 SkeletonAnimation 组件以使用动画**. -如果您的组件仅为了修改其动画属性而持有对 `SkeletonGraphic` 的引用,建议将引用类型更改为 `SkeletonAnimation`。 -这样您可以像 `skeletonAnimation.AnimationState` 一样访问动画状态 -而不必像 `((SkeletonAnimation)skeletonGraphic.Animation).AnimationState` 那样进行转换。请注意,如果您想更改序列化组件变量的名称,可以在变量定义前使用 `[FormerlySerializedAs("previousName")]` 属性来自动重新分配您现有的序列化值。 +* 如需访问动画: `skeletonGraphic.Animation`. + +#### 2. 将已有引用迁至 SkeletonAnimation + +若你组件仅通过引用 `SkeletonGraphic` 来修改其动画属性, 那么建议将引用类型更改为 `SkeletonAnimation`. +此举便可直接访问动画状态而无需像 `((SkeletonAnimation)skeletonGraphic.Animation).AnimationState` 这样进行显式转换, 例如: `skeletonAnimation.AnimationState`. 请注意, 若希望重命名序列化组件变量, 可在变量声明前添加 `[FormerlySerializedAs("previousName")]` 特性, Unity 将自动将原字段中保存的序列化值迁移至新变量, 从而保留你在场景或预制件中的已有配置. #### 示例代码 + ```csharp -// 自动重新分配先前的序列化值 +// Automatically reassign previous serialized values [FormerlySerializedAs("skeletonGraphic")] -public SkeletonAnimation skeletonAnimation; // 升级后将保持引用 +public SkeletonAnimation skeletonAnimation; // Will maintain the reference after upgrade ``` -#### 3. 属性更改 -- 移除属性 `AnimationState` - 改为从 `SkeletonAnimation` 组件查询。 -- `MeshGenerator` 不再是公共的 - 使用 `MeshSettings` 属性和 `SetMeshSettings()` 代替。 -- `MaterialsMultipleCanvasRenderers` 类型从 `ExposedList` 更改为 `Material[]`。 +#### 3. 属性变更 -#### 4. 创建辅助方法 -- `NewSkeletonGraphicGameObject` 现在创建 `SkeletonGraphic` 和 `SkeletonAnimation` 以保持现有行为。返回类型已更改为在单个结构中返回两个组件引用。 -- `AddSkeletonGraphicComponent` 被移除并替换为: - - `AddSkeletonGraphicAnimationComponents` - 创建 `SkeletonGraphic` 和 `SkeletonAnimation` 组件。 - - `AddSkeletonGraphicRenderingComponent` - 仅创建 `SkeletonGraphic` 组件。 +* 已移除属性 `AnimationState` - 请通过 `SkeletonAnimation` 组件查询该属性. + +* 不再公开 `MeshGenerator` - 请改用 `MeshSettings` 属性和 `SetMeshSettings()` 方法. +* `MaterialsMultipleCanvasRenderers` 类型由 `ExposedList` 改为 `Material[]`. + +#### 4. 创建辅助器(Creation Helper)方法 + +* `NewSkeletonGraphicGameObject` 现在默认同时创建 `SkeletonGraphic` 和 `SkeletonAnimation`, 以对齐原有行为. 返回类型改为了一个包含了这两个组件引用的结构体. + +* 已移除 `AddSkeletonGraphicComponent`, 可用替换为: + * `AddSkeletonGraphicAnimationComponents` - 同时创建 `SkeletonGraphic` 和 `SkeletonAnimation` 组件. + * `AddSkeletonGraphicRenderingComponent` - 仅创建 `SkeletonGraphic` 组件. #### 5. 事件更改 -- 委托签名从 `SkeletonRendererDelegate(SkeletonGraphic)` 更改为 `SkeletonRendererDelegate(ISkeletonRenderer)`。这影响事件:`OnRebuild`、`OnMeshAndMaterialsUpdated`。 -要修复任何编译错误,请将您的方法参数从 SkeletonGraphic 更改为 ISkeletonRenderer。 + +* 委托签名从 `SkeletonRendererDelegate(SkeletonGraphic)` 改为 `SkeletonRendererDelegate(ISkeletonRenderer)`. 该更改会影响以下事件: `OnRebuild`, `OnMeshAndMaterialsUpdated`. +如需修复编译错误, 只需将方法实参从 `SkeletonGraphic` 更改为 `ISkeletonRenderer`. #### 6. 执行顺序 -- `SkeletonRenderer` 和 `SkeletonGraphic` 组件收到 `DefaultExecutionOrder(1)]`,使它们在默认*(order=0)*脚本之后运行。这确保即使 `UpdateTiming` 设置为 `InLateUpdate`,动画也会在骨架更新之前应用。 -#### 7. 行为更改 - 材质更新 -- 每个 `CanvasRenderer` 的材质不再在每个 `LateUpdate` 中更新,而是在以下情况下更新: - - a) 更新的骨架需要更改材质,或 - - b) 当 `CustomMaterialOverride` 或 `CustomTextureOverride` 被访问并因此可能被修改时。 +* `SkeletonRenderer` 和 `SkeletonGraphic` 组件现可接收 `DefaultExecutionOrder(1)]` 参数,, 以确保其在默认脚本*(即 order=0)*之后执行. 此举保证了即使 `UpdateTiming` 置为 `InLateUpdate`, 动画仍能先于 skeleton 更新. -### 字段和属性迁移 +#### 7. 行为变更 - Material 更新 -#### 动画属性 -| **旧 API** | **新 API** | **备注** | +* 各 `CanvasRenderer` 的 material 不再于每个 `LateUpdate` 中更新, 而仅在以下情况时更新: + * a) 当 skeleton 更新需更换 materials, 或者 + * b) 代码访问了 `CustomMaterialOverride` 或 `CustomTextureOverride` 并可能修改它们. + +### 字段与属性迁移 + +#### A动画属性 + +| **旧 API** | **新 API** | **说明** | |-------------------|-------------------|-----------| -| `skeletonGraphic.AnimationState` | `((SkeletonAnimation)skeletonGraphic.Animation).AnimationState` | 需要转换 | -| `skeletonGraphic.startingAnimation` | `skeletonAnimation.AnimationName` | 通过动画组件 | -| `skeletonGraphic.startingLoop` | `skeletonAnimation.loop` | 通过动画组件 | -| `skeletonGraphic.timeScale` | `skeletonAnimation.timeScale` | 通过动画组件 | -| `skeletonGraphic.unscaledTime` | `skeletonAnimation.unscaledTime` | 通过动画组件 | +| `skeletonGraphic.AnimationState` | `((SkeletonAnimation)skeletonGraphic.Animation).AnimationState` | 需显式转换 | +| `skeletonGraphic.startingAnimation` | `skeletonAnimation.AnimationName` | 通过 Animation 组件访问 | +| `skeletonGraphic.startingLoop` | `skeletonAnimation.loop` | 通过 Animation 组件访问 | +| `skeletonGraphic.timeScale` | `skeletonAnimation.timeScale` | 通过 Animation 组件访问 | +| `skeletonGraphic.unscaledTime` | `skeletonAnimation.unscaledTime` | 通过 Animation 组件访问 | #### 网格生成器设置 -| **旧 API** | **新 API** | **备注** | + +| **旧 API** | **新 API** | **说明** | |-------------------|-------------------|-----------| | `skeletonGraphic.MeshGenerator.settings` | `skeletonGraphic.MeshSettings` | 直接访问设置 | --- -## ⚠️ 其他重要说明 +## ⚠️ 其他重要注意事项 ### 防止丢失组件引用 -任何引用 `SkeletonRenderer` 组件并具有 `SkeletonAnimation` 或 `SkeletonMecanim` 目标的其他组件(例如 `SkeletonRenderSeparator`)在升级后将指向 *null*,因为 `SkeletonAnimation` 和 `SkeletonMecanim` 组件不再是 `SkeletonRenderer` 的子类,因此不是有效的引用。手动解决方案是将类型保留为 `SkeletonRenderer` 并丢失对 `SkeletonAnimation` 的引用(将设置为 *none*)。然后您需要在场景和预制件中手动重新分配丢失的引用。半自动替代解决方案如下:将您的 `SkeletonRenderer` 变量的类型更改为 `Component`(以捕获对象引用而不丢失它)并添加类型为 `SkeletonRenderer`(或 `SkeletonAnimation`)的第二个变量,然后以编程方式从 `Component` 变量读取它并将其分配给新添加的变量。例如,您可以在 Unity 编辑器中的 `Awake()` 中自动执行此操作,并向您的组件添加 `[ExecuteAlways]` 标签。 + +其他组件(例如 `SkeletonRenderSeparator`)若持有对 `SkeletonRenderer` 的引用, 且其目标引用曾为 `SkeletonAnimation` 或 `SkeletonMecanim`, 则升级后该引用将被置为 *null*. 这是由于 `SkeletonAnimation` 与 `SkeletonMecanim` 不再继承自 `SkeletonRenderer`, 因而不再构成有效的类型引用. 对此, 手动解决方案是直接不管, 变量类型保持 `SkeletonRenderer` 不变, 任凭 `SkeletonAnimation` 的引用被置为 *none*. 随后再在各场景与预制件中手动分配丢失的引用. 而半自动方案则是: 将项目中 `SkeletonRenderer` 变量的类型改为 `Component` (保持对象引用避免丢失目标), 新增一个类型为 `SkeletonRenderer`(或 `SkeletonAnimation`)的变量,然后在代码中从 `Component` 类型变量读取目标对象, 并将其赋给新变量. 例如, 在 Unity 编辑器中给组件添加 [ExecuteAlways] 特性标记, 并在 `Awake()` 方法中自动执行此操作. #### 示例代码 - ```csharp -// 升级前的旧类 -public class TestMigrateReferences : MonoBehaviour { - public SkeletonRenderer skeletonRenderer; // 升级后此处分配的 SkeletonAnimation 引用将丢失。 - public void Foo () { - skeletonRenderer.skeleton.ScaleX = -1; - } + ```csharp +// 升级前的类代码 +public class TestMigrateReferences : MonoBehaviour { + public SkeletonRenderer skeletonRenderer; // 赋给这个 SkeletonAnimation 的引用将在升级后丢失. + + public void Foo () { + skeletonRenderer.skeleton.ScaleX = -1; + } } -// 升级后的新类 -[ExecuteAlways] // 或 [ExecuteInEditMode] +// 升级后的类代码 +[ExecuteAlways] // 或者用 [ExecuteInEditMode] public class TestMigrateReferences : MonoBehaviour { #if UNITY_EDITOR - [SerializeField, HideInInspector, FormerlySerializedAs("skeletonRenderer")] Component previousSkeletonRenderer; // 这捕获在名称 skeletonRenderer 处分配的旧 SkeletonAnimation 引用。 + [SerializeField, HideInInspector, FormerlySerializedAs("skeletonRenderer")] Component previousSkeletonRenderer; // 如此便能捕获原名为 skeletonRenderer 的 `SkeletonAnimation` 引用. #endif - public SkeletonRenderer skeletonRenderer; + public SkeletonRenderer skeletonRenderer; - public void Foo () { - skeletonRenderer.skeleton.ScaleX = -1; - } + public void Foo () { + skeletonRenderer.skeleton.ScaleX = -1; + } #if UNITY_EDITOR - public void Awake () { - AutoUpgradeReferences(); - } + public void Awake () { + AutoUpgradeReferences(); + } - public void AutoUpgradeReferences () { - if (previousSkeletonRenderer != null && skeletonRenderer == null) { - skeletonRenderer = previousSkeletonRenderer.GetComponent(); - if (skeletonRenderer != null) - Debug.Log("Upgraded SkeletonRenderer reference."); - } - } + public void AutoUpgradeReferences () { + if (previousSkeletonRenderer != null && skeletonRenderer == null) { + skeletonRenderer = previousSkeletonRenderer.GetComponent(); + if (skeletonRenderer != null) + Debug.Log("Upgraded SkeletonRenderer reference."); + } + } #endif } ``` -### 组件启用/禁用 -由于 `ISkeletonRenderer` 和 `ISkeletonAnimation` 组件现在是分离的,启用/禁用任何这些组件的脚本需要调整以**启用/禁用两者**。 +### 组件的启用/禁用 + +由于 `ISkeletonRenderer` 和 `ISkeletonAnimation` 组件现已一分为二, 任何控制组件启用/禁用的脚本都必须**同时启用/禁用这两个组件**. ### SkeletonUtilityBone 行为更改 -在 Override 模式下,`SkeletonUtilityBone` 不再在 `UpdatePhase.World` 中调整 Transform,仅在 `UpdatePhase.Complete` 中(移除冗余更新)。 -### 自动迁移 -- 当定义了 `AUTO_UPGRADE_TO_43_COMPONENTS` 时,Unity 编辑器会自动转移已弃用的字段。 -- 要一次升级所有场景和预制件,请转到 `Edit - Preferences - Spine` 并选择 `Upgrade Scenes & Prefabs` - `Upgrade All`。 -- 每个类中的 `UpgradeTo43` 和 `TransferDeprecatedFields()` 方法处理序列化数据迁移。 -- 运行时访问仍需要手动代码更新。 +在 Override 模式下, `SkeletonUtilityBone` 仅在 `UpdatePhase.Complete` 阶段调整变换(Transform), 不再于 `UpdatePhase.World` 阶段重复更新, 以减少冗余操作. -### 最常见更改的摘要 -1. **添加 `.Renderer.`** 前缀以从动画组件访问渲染属性。 -2. **添加 `.MeshSettings.`** 以访问网格生成设置。 -3. **转换为 SkeletonAnimation** 当从 SkeletonGraphic 访问 AnimationState 时。 -4. **更新委托方法签名** 从具体类型到接口。 -5. **重新分配丢失的引用** 使用上述迁移模式升级后。 +### 自动化迁移 + +* 当启用了 `AUTO_UPGRADE_TO_43_COMPONENTS` 后, Unity 编辑器将自动迁移废弃字段. +* 如需一键升级全部场景与预制件, 请打开 `Edit - Preferences - Spine`, 并在 `Automatic Component Upgrade` 中点击 `Upgrade Scenes & Prefabs` - `Upgrade All` 即可. +* 各类中的 `UpgradeTo43` 和 `TransferDeprecatedFields()` 方法负责其各自的序列化数据的迁移. +* 运行时访问仍需手动更新代码. + +### 常见变更总结 + +1. **添加 `.Renderer.`** 前缀便可从动画组件访问渲染属性. +2. **添加 `.MeshSettings.`** 前缀可以访问网格生成设置. +3. 从 SkeletonGraphic 访问 AnimationState 时, 需 **显式类型转换为 SkeletonAnimation**. +4. **更新委托方法签名**: 签名中的具体类型应改为接口类型. +5. 使用上述迁移模式升级后要**重新绑定丢失的引用**. --- ## 禁用自动升级检查 -一旦您完成了所有 Spine 资产、场景和预制件的迁移,您可以禁用自动升级检查以提高编辑器性能: +当完成了 Spine 资源、场景和预制件的全部迁移工作后, 可禁用自动升级检查来提升编辑器性能: 1. 转到 `Edit → Preferences → Spine` -2. 在 `Automatic Component Upgrade` 下,点击 `Split Component Upgrade` → `Disable` +2. 在 `Automatic Component Upgrade` 中点击 `Split Component Upgrade` → `Disable` -这将阻止 Unity 编辑器在场景或预制件加载时执行编辑器内检查以确定组件是否需要迁移。如果您需要迁移其他资产,您可以随时重新启用它。 +此操作将停止 Unity 编辑器在加载场景或预制件时的迁移检测. 如有新资源需要迁移, 可随时重启此功能. --- -## 需要帮助? +## 需要帮助? -如果您在迁移期间遇到任何意外问题或发现组件属性迁移不正确,请在 [Spine 论坛](https://esotericsoftware.com/forum) 发帖。我们很乐意提供帮助并修复任何问题,使自动迁移尽可能无痛。 \ No newline at end of file +若在迁移过程中遇到棘手问题, 或发现组件迁移有误, 请前往 [Spine 论坛](https://esotericsoftware.com/forum) 发帖反馈. 我们将全力协助,确保自动迁移过程尽可能顺畅无痛.