spine-runtimes/spine-unity/Assets/Spine/Documentation/4.3-split-component-upgrade-guide.md

22 KiB

spine-unity 4.3 Split Component Upgrade Guide

Component Architecture Restructuring

Note: You can find Chinese and Japanese translations of this upgrade guide right next to this file.


📋 Scope of This Document

This document covers only the spine-unity component split migration. From version 4.2 to 4.3, there have been additional breaking changes in both spine-csharp and spine-unity that you need to address before handling the component split:

  • spine-csharp API changes: New pose system affecting bone, slot, and constraint properties

For complete migration steps covering all 4.2 to 4.3 changes, please refer to:

Important: Complete the spine-csharp API migration first, then proceed with the component split migration described in this document.


⚠️ IMPORTANT: Before You Upgrade

This warning only applies to existing projects being upgraded. New projects can safely ignore this section.

What Will Happen

Components will be automatically upgraded and split into separate animation and rendering components:

  • SkeletonAnimationSkeletonAnimation + SkeletonRenderer components
  • SkeletonMecanimSkeletonMecanim + SkeletonRenderer components
  • SkeletonGraphicSkeletonAnimation + SkeletonGraphic components

All component settings and fields will be automatically transferred - nothing will be lost.

However: Due to these type changes, existing references in your custom scripts may be lost because the component types no longer match (e.g., SkeletonAnimation is no longer a subclass of SkeletonRenderer).

Required Upgrade Steps (In Order):

  1. 🔒 BACKUP YOUR PROJECT Create a complete backup before upgrading. These changes will modify your scenes and prefabs.

  2. 📖 READ THIS ENTIRE DOCUMENT Understand all breaking changes before proceeding.

  3. ✏️ TEST AND UPDATE YOUR CODE

    • Update your scripts: Fix custom scripts that reference Spine components according to this document, as your code may no longer compile when members were moved to the split classes
    • Test: Open a few test scenes to see which component references are lost. Unsaved scenes still contain the old component data and serve as a safety backup - only when you save will the split components replace the old ones and references be lost. ⚠️ WARNING: Prefabs behave differently! Opening a prefab in Prefab Edit Mode will automatically save the component migration due to Unity's prefab auto-save feature. Always test with scenes first, not prefabs.
    • Decide: Either manually re-assign lost references, or write migration code (explained below) to handle this automatically

    ⚠️ IMPORTANT: Automatic component splitting only happens when scenes/prefabs are opened in the Unity Editor. You must choose 'Upgrade All' or save each scene/prefab before building your game, otherwise the old single components won't be split and half the required components might be missing in the build!

    💡 HINT: If you encounter the Console log output "SendMessage cannot be called during Awake, CheckConsistency, or OnValidate", this is a sign that old un-migrated assets were present in the scene which were just auto-upgraded. These messages will be followed by a log message confirming that an old component was auto-migrated to split components.

  4. 🔄 CHOOSE YOUR UPGRADE PATH

    Option A - Manual re-assignment (recommended for small projects):

    • Open each scene and prefab individually
    • Manually re-assign lost references in the Inspector
    • Save when satisfied

    Option B - Automatic migration (for large projects with many scenes/prefabs):

    • Write migration code first:
      • Implement the reference migration pattern (see "Preventing Lost Component References" section below)
      • For SkeletonGraphic references, see "Changing Existing References to SkeletonAnimation" section
    • Test migration code on a few files
    • Then use Upgrade All:
      • Go to Edit → Preferences → Spine
      • Under "Upgrade Scenes & Prefabs"
      • Click Upgrade All button

What Will Break If You Don't Prepare:

  • Component references in scenes or prefabs may be lost (set to null) once you save your scenes or prefabs
  • Building before upgrading all scenes/prefabs may result in missing components in the build

Do not proceed without completing steps 1-3, or you risk breaking your project.


📦 Optional Two-Step Migration from 4.2

If you're migrating from spine-unity 4.2, you may find it easier to upgrade in two steps to isolate potential issues:

Step 1: Upgrade to a 4.3-beta pre-split version

First upgrade to a 4.3-beta version before the component split changes:

This intermediate step allows you to:

  • Fix any issues related to the 4.2 → 4.3 spine-csharp API changes first and ensures your project works
  • Verify your project is stable before proceeding
  • Once your project is working with this 4.3-beta version, create another backup before proceeding to step 2

Step 2: Upgrade to latest 4.3-beta version (with split components)

Once your project is working with 4.3-beta:

  • Upgrade to the latest 4.3-beta package
  • Follow the component split migration guide above
  • Handle the separated animation and rendering components

This two-step approach helps isolate issues - if something breaks, you'll know whether it's due to the 4.2 → 4.3 spine-csharp changes or the component split specifically.


📋 Introduction

The spine-unity 4.3 runtime introduces a major architectural change: separation of animation from rendering by using two separate components instead of component inheritance. This enables flexible combinations like using SkeletonMecanim for animation with SkeletonGraphic for rendering, which was previously not possible.

Key Changes:

  • Component Split: The previously monolithic components have been split into separate rendering and animation components.
  • Separate Components: SkeletonAnimation and SkeletonMecanim no longer inherit from SkeletonRenderer. They now work alongside a separate renderer component (a subclass of ISkeletonRenderer), such as SkeletonRenderer and SkeletonGraphic.
  • Interface Updates: New ISkeletonRenderer and ISkeletonAnimation interfaces with updated property names.
  • Settings Grouping: Mesh generation settings are now grouped under MeshSettings property.
  • Automatic Migration: The Unity Editor will automatically upgrade your components to the new split components and transfer deprecated fields when AUTO_UPGRADE_TO_43_COMPONENTS is defined (the default).
  • Upgrade all Scenes and Prefabs: To upgrade all scenes and prefabs at once, go to Edit - Preferences - Spine and under Automatic Component Upgrade hit Upgrade Scenes & Prefabs - Upgrade All.

Component Relationships:

Old Architecture New Architecture
SkeletonAnimation inherits from SkeletonRenderer SkeletonAnimation + separate SkeletonRenderer component
SkeletonMecanim inherits from SkeletonRenderer SkeletonMecanim + separate SkeletonRenderer component
SkeletonGraphic provides embedded AnimationState SkeletonGraphic + separate SkeletonAnimation component

Adapting Your Code

Here's what changes for each component:

▶️ SkeletonRenderer

Breaking Changes

1. Interface Changes

  • IHasSkeletonRenderer interface changed property name from SkeletonRenderer to Renderer, type from SkeletonRenderer to ISkeletonRenderer.

2. Event Changes

  • SkeletonRendererDelegate type is no longer a nested type in SkeletonRenderer.
    To fix any compile errors, replace SkeletonRenderer.SkeletonRendererDelegate with SkeletonRendererDelegate.
  • BeforeApply delegate type changed from SkeletonRendererDelegate to SkeletonAnimationDelegate.
  • SkeletonRendererDelegate type changed from SkeletonRendererDelegate(SkeletonRenderer) to SkeletonRendererDelegate(ISkeletonRenderer). This affects events: OnRebuild, OnMeshAndMaterialsUpdated.
    To fix any compile errors, change your method parameter from SkeletonRenderer to ISkeletonRenderer.
  • Moved bone events UpdateLocal, UpdateWorld, and UpdateComplete from ISkeletonAnimation classes (SkeletonAnimation, SkeletonMecanim) to ISkeletonRenderer classes (SkeletonRenderer, SkeletonGraphic). Changed delegate type from UpdateBonesDelegate to SkeletonRendererDelegate, with parameter ISkeletonRenderer instead of ISkeletonAnimation.

2. Method Changes

  • LateUpdateMesh() has been changed to UpdateMesh().
  • Removed MeshGenerator.TryReplaceMaterials.

3. Execution Order

  • SkeletonRenderer and SkeletonGraphic components received DefaultExecutionOrder(1)] which makes them run after default (order=0) scripts. This ensures animations are applied before the skeleton is updated even if UpdateTiming is set to InLateUpdate.

4. Behaviour Changes

  • generateMeshOverride is now also called when singleSubmesh is enabled.

Field and Property Migration

Mesh Generation Settings

Old API New API Notes
skeletonRenderer.zSpacing skeletonRenderer.MeshSettings.zSpacing Moved to MeshSettings
skeletonRenderer.useClipping skeletonRenderer.MeshSettings.useClipping Moved to MeshSettings
skeletonRenderer.immutableTriangles skeletonRenderer.MeshSettings.immutableTriangles Moved to MeshSettings
skeletonRenderer.pmaVertexColors skeletonRenderer.MeshSettings.pmaVertexColors Moved to MeshSettings
skeletonRenderer.tintBlack skeletonRenderer.MeshSettings.tintBlack Moved to MeshSettings
skeletonRenderer.addNormals skeletonRenderer.MeshSettings.addNormals Moved to MeshSettings
skeletonRenderer.calculateTangents skeletonRenderer.MeshSettings.calculateTangents Moved to MeshSettings

Deprecated Lowercase Attributes

  • Lowercase attributes initialFlipX, initialFlipY and initialSkinName are now deprecated and will be removed in future runtime versions. Use the added properties of the same name but uppercase instead: InitialFlipX, InitialFlipY and InitialSkinName.

▶️ SkeletonAnimation

Breaking Changes

1. Component Architecture

  • SkeletonAnimation is now a separate component from SkeletonRenderer, no longer a subclass.
  • Access renderer via: skeletonAnimation.Renderer.
  • Access animation from renderer via: skeletonRenderer.Animation.

2. Property Changes

  • state is no longer public. Use AnimationState property instead.
  • valid removed. Use IsValid instead.

3. Method Changes

  • Added UpdateOncePerFrame() - updates if Update has not been called this frame. The existing Update(float time) still always updates when called.
  • Update() without parameters is no longer public, use either UpdateOncePerFrame() to update when no update has been performed this frame, or Update(0) to force an animation update.

Field and Property Migration

As SkeletonAnimation is now a separate component, methods and properties provided by SkeletonRenderer can no longer be accessed directly via a SkeletonAnimation object. There is a skeletonAnimation.Renderer property available to access the associated ISkeletonRenderer from a SkeletonAnimation object, and an skeletonRenderer.Animation property to access the associated ISkeletonAnimation from a SkeletonRenderer or SkeletonGraphic object. For members that are not exposed by the ISkeletonRenderer interface, you can cast skeletonAnimation.Renderer to SkeletonRenderer or SkeletonGraphic respectively to access the renderer member variables.

Example Code

// Old SkeletonRenderer property access from SkeletonAnimation
skeletonAnimation.zSpacing = 0.1f;
skeletonAnimation.AnySkeletonRendererProperty;

// New SkeletonRenderer property access from SkeletonAnimation
skeletonAnimation.Renderer.MeshSettings.zSpacing = 0.1f; // exposed in ISkeletonRenderer interface
var skeletonRenderer = (SkeletonRenderer)skeletonAnimation.Renderer;
skeletonRenderer.AnySkeletonRendererProperty; // not exposed in ISkeletonRenderer interface


▶️ SkeletonMecanim

Breaking Changes

1. Component Architecture

  • SkeletonMecanim is now a separate component from SkeletonRenderer, no longer a subclass.
  • Same access pattern as SkeletonAnimation.

2. Method Changes

  • Update() is no longer public.
  • Use UpdateIfNecessary() or Update(0) to force update.

Field and Property Migration

Same as SkeletonAnimation above.

▶️ SkeletonGraphic

Breaking Changes

1. Component Architecture

  • SkeletonGraphic no longer covers animation, add SkeletonAnimation as a separate animation component.
  • Animation accessed via: skeletonGraphic.Animation.

2. Changing Existing References to SkeletonAnimation

If your components are holding a reference to SkeletonGraphic only to modify its animation properties, it is recommended to change the reference type to SkeletonAnimation. This way you can access animation state like skeletonAnimation.AnimationState instead of having to cast it like ((SkeletonAnimation)skeletonGraphic.Animation).AnimationState. Note that if you want to change the name of serialized component variables, you can use the [FormerlySerializedAs("previousName")] attribute in front of a variable definition to automatically reassign your existing serialized value.

Example Code

// Automatically reassign previous serialized values
[FormerlySerializedAs("skeletonGraphic")]
public SkeletonAnimation skeletonAnimation; // Will maintain the reference after upgrade

3. Property Changes

  • Removed property AnimationState - query it from the SkeletonAnimation component instead.
  • MeshGenerator is no longer public - use MeshSettings property and SetMeshSettings() instead.
  • MaterialsMultipleCanvasRenderers type changed from ExposedList<Material> to Material[].

4. Creation Helper Methods

  • NewSkeletonGraphicGameObject now creates both SkeletonGraphic and SkeletonAnimation to maintain existing behaviour. Return type changed to return both component references in a single struct.
  • AddSkeletonGraphicComponent is removed and replaced by:
    • AddSkeletonGraphicAnimationComponents - creates both SkeletonGraphic and SkeletonAnimation components.
    • AddSkeletonGraphicRenderingComponent - creates only SkeletonGraphic component.

5. Event Changes

  • Delegate signature changed from SkeletonRendererDelegate(SkeletonGraphic) to SkeletonRendererDelegate(ISkeletonRenderer). This affects events: OnRebuild, OnMeshAndMaterialsUpdated.
    To fix any compile errors, change your method parameter from SkeletonGraphic to ISkeletonRenderer.

6. Execution Order

  • SkeletonRenderer and SkeletonGraphic components received DefaultExecutionOrder(1)] which makes them run after default (order=0) scripts. This ensures animations are applied before the skeleton is updated even if UpdateTiming is set to InLateUpdate.

7. Behaviour Changes - Material Updates

  • Materials at each CanvasRenderer are no longer updated every LateUpdate, instead they are updated when either:
    • a) the updated skeleton requires a change of materials, or
    • b) when CustomMaterialOverride or CustomTextureOverride were accessed and thus potentially modified.

Field and Property Migration

Animation Properties

Old API New API Notes
skeletonGraphic.AnimationState ((SkeletonAnimation)skeletonGraphic.Animation).AnimationState Cast required
skeletonGraphic.startingAnimation skeletonAnimation.AnimationName Via Animation component
skeletonGraphic.startingLoop skeletonAnimation.loop Via Animation component
skeletonGraphic.timeScale skeletonAnimation.timeScale Via Animation component
skeletonGraphic.unscaledTime skeletonAnimation.unscaledTime Via Animation component

Mesh Generator Settings

Old API New API Notes
skeletonGraphic.MeshGenerator.settings skeletonGraphic.MeshSettings Direct access to settings

⚠️ Additional Important Notes

Preventing Lost Component References

Any references by other components (e.g. SkeletonRenderSeparator) that reference a SkeletonRenderer component and had a SkeletonAnimation or SkeletonMecanim target will be pointing to null after the upgrade, since the SkeletonAnimation and SkeletonMecanim components are no longer subclasses of SkeletonRenderer and thus no valid reference. The manual solution is to leave the type as SkeletonRenderer and lose references to SkeletonAnimation (will be set to none). Then you need to manually re-assign the lost references in your scenes and prefabs. A semi-automatic alternative solution is as follows: change the type of your SkeletonRenderer variable to Component (to capture the object reference and not lose it) and add a second variable of type SkeletonRenderer (or SkeletonAnimation) and then programmatically read it from the Component variable and assign it to the newly added variable. You can e.g. do this automatically in the Unity Editor in Awake() with an [ExecuteAlways] tag added to your component.

Example code

// Old class before upgrading
public class TestMigrateReferences : MonoBehaviour {
  public SkeletonRenderer skeletonRenderer; // this SkeletonAnimation reference assigned here would be lost after upgrading.

  public void Foo () {
  	skeletonRenderer.skeleton.ScaleX = -1;
  }
}

// New class after upgrading
[ExecuteAlways] // or [ExecuteInEditMode]
public class TestMigrateReferences : MonoBehaviour {
#if UNITY_EDITOR
  [SerializeField, HideInInspector, FormerlySerializedAs("skeletonRenderer")] Component previousSkeletonRenderer; // this captures the old SkeletonAnimation reference assigned at the name skeletonRenderer.
#endif
  public SkeletonRenderer skeletonRenderer;

  public void Foo () {
  	skeletonRenderer.skeleton.ScaleX = -1;
  }

#if UNITY_EDITOR
  public void Awake () {
  	AutoUpgradeReferences();
  }

  public void AutoUpgradeReferences () {
  	if (previousSkeletonRenderer != null && skeletonRenderer == null) {
  		skeletonRenderer = previousSkeletonRenderer.GetComponent<SkeletonRenderer>();
  		if (skeletonRenderer != null)
  			Debug.Log("Upgraded SkeletonRenderer reference.");
  	}
  }
#endif
}

Component Enable/Disable

Since ISkeletonRenderer and ISkeletonAnimation components are now separate, scripts that enable/disable any of these components need adjustment to enable/disable both.

SkeletonUtilityBone Behaviour Change

In mode Override, SkeletonUtilityBone no longer adjusts the Transform in UpdatePhase.World, only in UpdatePhase.Complete (removes redundant update).

Automatic Migration

  • Unity Editor automatically transfers deprecated fields when AUTO_UPGRADE_TO_43_COMPONENTS is defined.
  • To upgrade all scenes and prefabs at once, go to Edit - Preferences - Spine and select Upgrade Scenes & Prefabs - Upgrade All.
  • The UpgradeTo43 and TransferDeprecatedFields() methods in each class handles serialized data migration.
  • Manual code updates are still required for runtime access.

Summary of Most Common Changes

  1. Add .Renderer. prefix to access rendering properties from animation components.
  2. Add .MeshSettings. to access mesh generation settings.
  3. Cast to SkeletonAnimation when accessing AnimationState from SkeletonGraphic.
  4. Update delegate method signatures from concrete types to interfaces.
  5. Re-assign lost references after upgrade using the migration pattern above.

Disabling Automatic Upgrade Checks

Once you have completed the migration of all your Spine assets, scenes, and prefabs, you can disable the automatic upgrade checks to improve editor performance:

  1. Go to Edit → Preferences → Spine
  2. Under Automatic Component Upgrade, click Split Component UpgradeDisable

This will stop the Unity Editor from performing in-editor checks upon scene or prefab loading to determine whether components need to be migrated. You can re-enable it at any time if you need to migrate additional assets.


Need Help?

If you encounter any unexpected problems during migration or find that component properties are incorrectly migrated, please post on the Spine forum. We're happy to help and fix any issues to make automatic migration as painless as possible.