# spine-unity Runtime Documentation

Licensing

Integrating an official Spine Runtime into your applications requires a valid Spine license, though you are welcome to use the Spine Runtimes for evaluation purposes.

!! # Getting Started ## Installation To use the spine-unity runtime in your Unity project: 1. Download and install [Unity](http://unity3d.com/get-unity). 2. Create a new empty project in the Unity Editor. 3. Download the [latest spine-unity unitypackage](/spine-unity-download). Alternatively you can get the latest changes via Git as described below. 4. Import the unitypackage (you can double-click on it and Unity will open it). > **Getting latest changes via Git instead of the unitypackage** 1. Clone the [spine-runtimes Git repository](https://github.com/esotericsoftware/spine-runtimes). 2. Copy the contents of `spine-runtimes/spine-unity/Assets/` to your project's `Assets/` folder. 3. Copy the folder `spine-runtimes/spine-csharp/src` to your project's `Assets/Spine/Runtime/spine-csharp` folder. ### Alternative Installation via Package Manager > **Using Unity Package Manager - 'Add package from git URL' instead of the unitypackage** > If your Unity version is rather recent and your Unity Package Manager provides the `Add package from git URL...` option, you can also directly use add the three packages with these URLs: > 1. `https://github.com/EsotericSoftware/spine-runtimes.git?path=spine-csharp/src#4.2` > 2. `https://github.com/EsotericSoftware/spine-runtimes.git?path=spine-unity/Assets/Spine#4.2` > 3. `https://github.com/EsotericSoftware/spine-runtimes.git?path=spine-unity/Assets/Spine Examples#4.2` > > To open the example scenes of the `Spine Examples` package, please copy the scene files from the package directory to your `Assets` directory using your system's file manager (*Explorer* or *Finder* respectively). Unfortunately a bug in Unity causes the error `"Opening scene in read-only package!"` when trying to directly open a scene within a package downloaded via git URL: > ![Opening scene in readonly package](/img/spine-runtimes-guide/spine-unity/opening-scene-readonly-package.png) Open the `Package Manager` in Unity (via `Window > Package Manager`). For each of the three packages, select the `+` icon, choose `Add package from git URL...`, and enter the git URL above (or from the [download page](/spine-unity-download)). The part `#4.2` determines the branch and can also be set to a specific git commit hash like `#5e8e4c21f11603ba1b72c220369d367582783744` to ensure everyone on your project has the same consistent state of the package. ![Window - Package Manager](/img/spine-runtimes-guide/spine-unity/lwrp/window-package-manager.png) ![Add Package from git URL](/img/spine-runtimes-guide/spine-unity/lwrp/window-package-manager-git.png) ![Enter git URL](/img/spine-runtimes-guide/spine-unity/lwrp/window-package-manager-git-url-empty.png) The `Package Manager` window will now list the added package entry. ![Listed spine-unity packages](/img/spine-runtimes-guide/spine-unity/lwrp/spine-unity-package-listed.png) In the `Project` panel you will now find `spine-unity Runtime` and `spine-unity Runtime Examples` entries under `Packages`. ![Project panel lists packages](/img/spine-runtimes-guide/spine-unity/lwrp/project-panel-package-spineunity.png) If the entry is not yet listed in the `Project` panel, you may need to close and re-open Unity. ### 2D Toolkit Compatibility spine-unity supports [2D Toolkit](http://www.unikronsoftware.com/2dtoolkit/) and can render Spine skeletons using TK2D's texture atlas system. To enable 2D Toolkit compatibility, open Unity's `Preferences` via `Edit - Preferences` (`Unity - Preferences` on Mac) and in section `Spine` select `Define TK2D` - `Enable`. ### Optional Extension UPM Packages The spine-unity runtime works without additional plugins. Some optional features, such as Timeline or Universal Render Pipeline support, are provided via separate Unity Package Manager (UPM) extension packages. #### Why separate extension packages Unity has moved many of their optional modules to the new Unity Package Manager (UPM) ecosystem. For example, their Universal Render Pipeline base shader files are also provided as a UPM package under the name `Universal RP` and not part of every new Unity project out of the box. Including our Universal RP Spine shaders in the spine-unity runtime would lead to confusing error messages and additional configuration steps in case Unity's `Universal RP` package has not been installed in a project. By providing our Universal RP Spine shaders as a UPM package, such dependencies are automatically resolved, making it easier to use this additional functionality. #### Installation ##### **Option A - Download the UPM package** 1. Download the desired UPM package via the [download page](/spine-unity-download) or find it in the [spine-unity/Modules](https://github.com/EsotericSoftware/spine-runtimes/tree/4.2/spine-unity/Modules) subdirectory in the Git repository. 2. Having your Unity project open, it is recommended to close any scene containing Spine components (e.g. by opening a new empty scene). 3. After unzipping or cloning, you can make use of the package in one of these two ways: - a) **Copy into your project** Copy the package contents to the `Packages` directory in your project. Unity will load it automatically. - b) **Via the Package Manager** Copy the package contents anywhere outside your `Assets` directory, then open the `Package Manager` in Unity (via `Window > Package Manager`), select the `+` icon, choose `Add package from disk...`, and point it to the `package.json` file. ![Window - Package Manager](/img/spine-runtimes-guide/spine-unity/lwrp/window-package-manager.png) ![Add Package from Disk](/img/spine-runtimes-guide/spine-unity/lwrp/window-package-manager-add.png) ![Select package.json](/img/spine-runtimes-guide/spine-unity/lwrp/select-package-json-small.png) The `Package Manager` window will now list a `Spine Lightweight RP Shaders` entry: ![Listed LWRP package](/img/spine-runtimes-guide/spine-unity/lwrp/lwrp-package-listed.png) In the `Project` panel you will now also find a `Spine Lightweight RP Shaders` entry under `Packages`: ![Project panel lists package](/img/spine-runtimes-guide/spine-unity/lwrp/project-panel-package.png) If the entry is not yet listed in the `Project` panel, you may need to close and re-open Unity. ##### **Option B - Add package from git URL** If your Unity version is rather recent and your Unity Package Manager provides the `Add package from git URL...` option, you can also directly use the git URL. > **Important Note:** When installing the `URP Shaders UPM package` from git URL, it is required that you also have the `spine-csharp` and `spine-unity` packages installed via the Unity Package Manager, and not from a unitypackage to the `Assets` folder. Otherwise `URP Shaders UPM package` shader include paths point to a spine-unity package directory which does not exist, leading to shader compile errors. 1. Find the git URL for your UPM package on the [download page](/spine-unity-download). 2. Having your Unity project open, it is recommended to close any scene containing Spine components (e.g. by opening a new empty scene). 3. Open the `Package Manager` in Unity (via `Window > Package Manager`), select the `+` icon, choose `Add package from git URL...`, and enter the git URL from the [download page](/spine-unity-download). E.g. `https://github.com/EsotericSoftware/spine-runtimes.git?path=spine-unity/Modules/com.esotericsoftware.spine.urp-shaders#4.2`. The part `#4.2` determines the branch and can also be set to a specific git commit hash like `#5e8e4c21f11603ba1b72c220369d367582783744` to ensure everyone on your project has the same consistent state of the package. ![Window - Package Manager](/img/spine-runtimes-guide/spine-unity/lwrp/window-package-manager.png) ![Add Package from git URL](/img/spine-runtimes-guide/spine-unity/lwrp/window-package-manager-git.png) ![Enter git URL](/img/spine-runtimes-guide/spine-unity/lwrp/window-package-manager-git-url.png) The `Package Manager` window will now list a `Spine Lightweight RP Shaders` entry: ![Listed LWRP package](/img/spine-runtimes-guide/spine-unity/lwrp/lwrp-package-listed.png) In the `Project` panel you will now also find a `Spine Lightweight RP Shaders` entry under `Packages`: ![Project panel lists package](/img/spine-runtimes-guide/spine-unity/lwrp/project-panel-package.png) If the entry is not yet listed in the `Project` panel, you may need to close and re-open Unity. To open the example scenes contained in the package, please copy the scene files from the package directory to your `Assets` directory using your system's file manager (*Explorer* or *Finder* respectively). Unfortunately a bug in Unity causes the error `"Opening scene in read-only package!"` when trying to directly open a scene within a package downloaded via git URL: ![Opening scene in readonly package](/img/spine-runtimes-guide/spine-unity/opening-scene-readonly-package.png) ## Samples To explore the spine-unity runtime example scenes: 1. Download and install [Unity](http://unity3d.com/get-unity). 2. Create a new empty project in the Unity Editor. 3. Download the [latest spine-unity unitypackage](/spine-unity-download). Alternatively you can get the latest changes via Git as described below. 4. Import the unitypackage (you can double-click on it and Unity will open it). 5. Open the project in the Unity Editor, then checkout the different example scenes in the `Spine Examples/Getting Started` folder in the Project panel. Each example scene has text instructions on how to run it and a description of what you see. > **Getting latest changes via Git instead of the unitypackage** 1. Clone the [spine-runtimes Git repository](https://github.com/esotericsoftware/spine-runtimes). 2. Copy the contents of `spine-runtimes/spine-unity/Assets/` to your project's `Assets/` folder. 3. Copy the folder `spine-runtimes/spine-csharp/src` to your project's `Assets/Spine/Runtime/spine-csharp` folder. > **Alternative installation from UPM package via Package Manager and git URL** > You may also choose to install the spine-unity runtime and the spine-unity examples from git UPM packages via the Unity Package Manager, by selecting `Add package from git URL`. > See section [Alternative Installation via Package Manager](#Alternative-Installation-via-Package-Manager) for additional information. You can inspect and modify the C# code of both the samples and the spine-unity runtime by opening the project in Unity Editor and selecting `Assets -> Open C# Project`. For additional information on the example scenes, please see section [Example Scenes](#Example-Scenes). ## Updating the spine-unity Runtime Before updating your project' spine-unity runtime, please consult our [guide on Spine editor and runtime version management](/spine-runtime-architecture#Versioning). > **Note:** Json and binary skeleton data files exported from Spine 4.1 or earlier will **not** be readable by the spine-unity 4.2 runtime! The skeleton data files need to be re-exported using Spine 4.2. > > If you have many projects, we suggest automating exporting your project files as described [here](#Advanced---Automating-Exports). > For example, we use this script to export all the Spine example projects and to create texture atlases: [export.sh](https://github.com/EsotericSoftware/spine-runtimes/blob/4.2/examples/export/export.sh) Please consult the following upgrade guides when updating from spine-unity 3.6, 3.7, 3.8, 4.0 or 4.1 to newer versions: - [spine-unity 3.6 to 3.7 Upgrade-Guide](/forum/Spine-Unity-3-6-to-3-7-Upgrade-Guide-10446) - [spine-unity 3.7 to 3.8 Upgrade-Guide](/forum/Spine-Unity-3-7-to-3-8-Upgrade-Guide-12415) - [spine-unity 3.8 to 4.0 Upgrade-Guide](/forum/Spine-Unity-3-8-to-4-0-Upgrade-Guide-15981) - [spine-unity 4.0 to 4.1 Upgrade-Guide](/forum/Spine-Unity-4-0-to-4-1-Upgrade-Guide-17699) - [spine-unity 4.1 to 4.2 Upgrade-Guide](/forum/d/26006-spine-unity-41-to-42-upgrade-guide) It is recommended to perform the following steps to prevent potential problems: 1. As with Unity updates, it is always recommended that you back up your whole Unity project before performing an update. 1. Always check with your Lead Programmer and Technical Artist before updating your Spine runtime. Spine runtimes are source-available and designed to be user-modifiable based on varying project needs. Your project's Spine runtime may have been modified by your programmer. In this case, updating to the latest runtime also requires reapplying those modifications to the new version of the runtime. 1. Read the `CHANGELOG.md` file included in the downloaded unitypackage or on [github](/git/spine-runtimes/CHANGELOG.md). You can find the necessary documentation here when obsolete methods have been replaced with new counterparts. Once you are sure you want to update to the latest spine-unity runtime: 1. Get the latest spine-unity runtime by downloading the [latest spine-unity unitypackage](/spine-unity-download). Alternatively you can update by pulling the latest changes from the [spine-runtimes Git repository](https://github.com/esotericsoftware/spine-runtimes) via Git as described below. 2. Close the Unity Editor and Visual Studio/Xcode. 3. When upgrading to a different major or minor version (e.g. from 3.7 to 3.8), delete the previous spine-unity installation directories `Assets/Spine` and `Assets/Spine Examples` from your project. 4. Open the project in the Unity Editor. In case you removed the previous spine-unity installation, ignore any logged errors. 5. Import the unitypackage (you can double-click on it and Unity will open it). 6. When upgrading to a different major or minor version, re-import the skeleton assets by selecting `right-click - Reimport All` in the Project panel. Alternatively to not re-import all assets, you can locate the folder containing your Spine skeleton assets in the Project panel that you want to re-import, right-click on the folder, then select `Reimport`. > **Getting latest changes via Git instead of the unitypackage** 1. Get the latest spine-unity runtime by pulling the latest changes from the [spine-runtimes Git repository](https://github.com/esotericsoftware/spine-runtimes). 2. When upgrading to a different major or minor version (e.g. from 3.7 to 3.8), delete the previous spine-unity installation directories `Assets/Spine` and `Assets/Spine Examples` from your project. 3. Copy the contents of `spine-runtimes/spine-unity/Assets/` to your project's `Assets/` folder. 4. Copy the folder `spine-runtimes/spine-csharp/src` to your project's `Assets/Spine/Runtime/spine-csharp` folder. > **Note:** The spine-unity runtime is based on the generic [spine-csharp](/spine-csharp) runtime. Make sure to watch changes to both the spine-unity and spine-csharp runtime on [GitHub](https://github.com/esotericsoftware/spine-runtimes). > **Updating via Package Manager when using `Add package from git URL`** > > If you have added the spine-unity runtime as packages from a remote git URL via `Add package from git URL` you can use the Unity Package Manager to update the packages. Open the `Package Manager` in Unity (via `Window > Package Manager`), select each of the packages `spine-csharp Runtime`, `spine-unity Runtime` and `spine-unity Runtime Examples` and hit the `Update` button to re-download the latest version from the specified branch from git. Note that if your URL has the ending `#4.2` as in `https://github.com/EsotericSoftware/spine-runtimes.git?path=spine-csharp/src#4.2`, it will re-download the latest version from the `4.2` branch of the git repository. ## Updating an Extension UPM Package When upgrading an [optional extension UPM package](#Optional-Extension-UPM-Packages): - The same principles as [updating the Spine Unity runtime](#Updating-the-spine-unity-Runtime) apply. - As mentioned above, it is always recommended that you back up your whole Unity project before performing an update. ### Option A - In-place Update 1. If you have your Unity project open, it is recommended to either a) close Unity or b) close any scene containing Spine components (e.g. by opening a new empty scene). 2. Copy the content of the new UPM package zip file or git directory over the existing one. Depending on how you have installed the UPM package, this will be either the `project_root/Packages/package_name` directory in your project or the arbitrary directory outside the `Assets` directory from where you have loaded it via `Add package from disk..`. 3. If you have closed Unity, open your project again in Unity. 4. Unity will import the new assets and display a loading progress bar. ### Option B - 'Add package from git URL' If you have added the package from a remote git URL via `Add package from git URL` you can use the Unity Package Manager to update the package. Open the `Package Manager` in Unity (via `Window > Package Manager`), select the package that you want to update and hit the `Update` button to re-download the latest version from the specified branch from git. Note that if your URL has the ending `#4.2` as in `https://github.com/EsotericSoftware/spine-runtimes.git?path=spine-unity/Modules/com.esotericsoftware.spine.timeline#4.2`, it will re-download the latest version from the `4.2` branch of the git repository. # Scripting in Unity If you are not familiar with programming in C# and using Unity in general, we recommend watching the [official Unity Tutorials](http://unity3d.com/learn/tutorials) first. The [Unity Essentials](https://learn.unity.com/pathway/unity-essentials) and then [Scripting](https://learn.unity.com/project/beginner-gameplay-scripting) topics are a good place to start. Note that the Animation topic is not directly applicable to spine-unity since Spine provides its own animation workflow. # Using the spine-unity Runtime ## Overview The spine-unity runtime is a Unity plugin supporting playback and manipulation of animations created with Spine. The [spine-unity](/git/spine-runtimes/tree/spine-unity) runtime is written in C# and based on the generic [spine-csharp runtime](/git/spine-runtimes/spine-csharp). The spine-unity runtime wraps the spine-csharp structs and functions and exposes them as Unity components. Additionally, the spine-unity runtime imports files exported from the Spine Editor and stores them in custom Unity asset types. Please consult the [Spine Runtimes Guide](/spine-runtimes-guide) for a detailed overview of the Spine Runtime architecture. ## Asset Management ### Exporting Spine Assets for Unity ![](/img/spine-runtimes-guide/spine-unity/spine-unity-export-settings.png) #### Export User Guide You can find complete instructions in the Spine User Guide on how to 1. [Export skeleton & animation data](/spine-export) 2. [Export texture atlases containing the images of your skeleton](/spine-texture-packer) #### Spine Unity Export for Beginners The following shows a simple way to export Spine assets for Unity. 1. After you have created your skeleton and animations, click on `Spine Menu`>`Export...` (`CTRL`+`E`). This opens the **Export window**. ![](/img/spine-runtimes-guide/spine-unity/spinemenu-export-s.png) 1. Choose `JSON` on the upper-left of the Export window. ![](/img/spine-runtimes-guide/spine-unity/exportwindow-json-s.png) > Note: For production you should later prefer [binary skeleton](#Binary-Export-for-Unity) exports over JSON exports, as they are smaller in size and faster to load. 1. Check the `Texture Atlas` `Pack` checkbox. (Checking `Nonessential data`, `Pretty print` are also recommended for beginners). Be sure to have `Animation cleanup` disabled, otherwise keys identical to setup pose will not be exported. ![](/img/spine-runtimes-guide/spine-unity/exportwindow-createatlas-s.png) 1. Click on `Pack Settings` below the `Pack` checkbox. This opens the **Texture Packer Settings** window. 1. On the lower-right, look for the textbox labeled `Atlas extension` and make sure it is set to `.atlas.txt`. ![](/img/spine-runtimes-guide/spine-unity/texture-packer-atlas-txt-s.png) 1. You're done with the Texture Packer Settings window. Click `OK` to close. 1. In the **Export window**, pick an output folder. (Recommendation: Create a new empty folder.) ![](/img/spine-runtimes-guide/spine-unity/exportwindow-json-outputfolder-s.png) 1. Click `Export`. ![](/img/spine-runtimes-guide/spine-unity/exportwindow-exportbutton-s.png) 1. This will export three files: ![](/img/spine-runtimes-guide/spine-unity/three-exported-files.png) 1. `skeleton-name.json` or `skeleton-name.skel.bytes`, containing your skeleton and animation data. 2. `skeleton-name.atlas.txt`, containing information about the texture atlas. 3. One or more `.png` files, each representing on page of your texture atlas containing the packed images your skeleton uses. > **Note:** For __2D Toolkit__ users, Step 3 (packing a `.png` and `.atlas.txt`) is not necessary. Instead, you will have the appropriate field in your SkeletonDataAsset to assign a reference to `tk2dSpriteCollectionData`. Please consult the [Installation](#Installation) section of this page on how to enable 2D Toolkit support. #### Binary Export for Unity Exporting in binary format instead of JSON will result in smaller file size and faster loading. The following shows how to change to binary export for spine-unity. ![](/img/spine-runtimes-guide/spine-unity/exportwindow-binary-s.png) 1. Choose `Binary` on the upper-left of the Export window instead of `JSON`. 1. Set the `Extension` to `.skel.bytes`. > **Note:** spine-unity cannot load files with extension `.skel`. Be sure to use extension `.skel.bytes`. #### Advanced - Automating Exports If you have many projects, it is recommended to automate the export of your skeleton and atlas assets using the Spine [command line interface](/spine-command-line-interface). This eliminates repetitive manual work and allows for easy re-export of all projects at once, should you decide to upgrade to a newer Spine version. You can explore examples of utilizing the command line interface [here](/spine-command-line-interface#Examples). For example, we use this script to export all the Spine example projects and to create texture atlases: [export.sh](https://github.com/EsotericSoftware/spine-runtimes/blob/4.2/examples/export/export.sh) #### Advanced - Single Texture Atlas Export and SkeletonGraphic It is recommended in general to use a single-texture (single-page) atlas where possible to reduce the number of draw calls caused by additional submeshes. This is especially true for [SkeletonGraphic](#SkeletonGraphic-Component). Due to limitations of the used Unity `CanvasRenderer`, [SkeletonGraphic](#SkeletonGraphic-Component) is limited to a single texture by default. You can enable `Advanced - Multiple CanvasRenderers` at the `SkeletonGraphic` component Inspector to generate a child `CanvasRenderer` `GameObject` for every submesh to raise the texture limit. For performance reasons, this is best avoided where possible. This means Skeletons used in UI shall be packed as a single-texture (single-page) atlas, rather than multi-page atlases. If they do not fit into a single atlas page, you can pack texture atlas pages [grouped by folder](/spine-texture-packer#Folder-structure). This way you can ensure that each skin requires only a single atlas page. When the images are placed in the respective folders, you can export the skeleton with the following steps: 1. Press `Ctrl+E` or in the dropdown menu select `Export...` 2. Enable `Texture Atlas` `Pack` and select `Image Folder` instead of `Attachments` right to it. 3. (optional) Check in `Pack Settings` if under `Options` in the bottom right `Flatten Paths` and `Combine Subdirectories` is disabled (this is the default). 4. Click Export. #### Advanced - Premultiplied vs Straight Alpha Export Spine offers two basic workflows via Texture Packer Settings how atlas textures can be exported: 1. Premultiplied alpha (the default, premultiplied in Gamma color space) 1. Straight alpha Premultiplied alpha workflow offers some advantages over straight alpha, no additional draw calls for additive-blended attachments and [better mip-map generation](https://developer.nvidia.com/content/alpha-blending-pre-or-not-pre) being two of them. It is very important to match export and import settings correctly, see section [Advanced - Premultiplied vs Straight Alpha Import](#Advanced---Premultiplied-vs-Straight-Alpha-Import) for correct settings in Unity. ### Importing Spine Assets into Unity 1. Open your Unity project in the Unity Editor. It should already have a functioning spine-unity runtime in it, as described in section [Installation](#Installation). 2. Open the folder of the exported files. (`.json`, `.atlas.txt` and `.png`) 3. Copy the exported files (or the folder containing them) to your desired subfolder of your project's `Assets` folder. You can do this by dragging the exported files from an Explorer/Finder window into your desired folder in Unity's Project panel. ![](/img/spine-runtimes-guide/spine-unity/explorer-to-unity-project.gif) The spine-unity runtime will automatically generate the necessary additional Unity assets upon detecting the added files. The following assets are generated: ![](/img/spine-runtimes-guide/spine-unity/import-three-generated-assets.png) 1. an **_Atlas** asset for the texture atlas file (`.atlas.txt`). It holds a reference to the material and the `.atlas.txt` file. 2. a **_Material** asset for each texture atlas page (`.png`). It holds references to the shader and the `.png` texture. 3. a **_SkeletonData** asset for skeleton data files (`.json`, `.skel.bytes`). It holds a reference to the `.json` or `.skel.bytes` file and the generated **_Atlas** asset. It additionally provides custom import and animation settings for your skeleton, see section [Skeleton Data Asset](#Skeleton-Data-Asset). #### Advanced - Premultiplied vs Straight Alpha Import As described in [Advanced - Premultiplied vs Straight Alpha Export](#Advanced---Premultiplied-vs-Straight-Alpha-Export), Spine offers two basic workflows of how atlas textures can be exported: 1. Premultiplied alpha (the default, premultiplied in Gamma color space) 1. Straight alpha ##### **Preferences parameter `Atlas Texture Settings` for correct import settings** **Important Note:** It is very important that whenever the `Premultiply alpha` setting is enabled upon atlas texture export, both the Material's `Straight Alpha Texture` parameter and the Texture's `Alpha Is Transparency` setting in Unity are disabled and vice versa. The spine-unity runtime provides a [`Spine` preferences section](#Spine-Preferences) in Unity's `Preferences` window, accessible via `Edit - Preferences` (`Unity - Preferences` on Mac). It provides an *Atlas Texture Settings* parameter to automatically apply the proper texture and material import settings at newly imported atlas textures. Right below you can find material templates for `Additive Material`, `Multiply Material` and `Screen Material`. When switching to straight alpha workflow, these template material references need to be adjusted accordingly as well. ![Spine Preferences - Atlas Texture Settings](/img/spine-runtimes-guide/spine-unity/spine-preferences-pma-preset.png) ![Spine Preferences PMA Preset Selection](/img/spine-runtimes-guide/spine-unity/pma-preset-selection.png) ![Spine Preferences - Blend Mode Materials](/img/spine-runtimes-guide/spine-unity/spine-preferences-blendmode-materials.png) ![Spine Preferences Blend Mode Material Selection](/img/spine-runtimes-guide/spine-unity/blendmode-material-selection.png) When exporting atlas textures from Spine with `Premultiply alpha` enabled (the default), you can leave `Atlas Texture Settings` at `PMATexturePreset`, and the blend mode materials at `SkeletonPMAAdditive`, `SkeletonPMAMultiply` and `SkeletonPMAScreen`. If you have disabled `Premultiply alpha`, set `Atlas Texture Settings` to `StraightAlphaTexturePreset` and blend mode materials to `SkeletonStraightAdditive`, `SkeletonStraightMultiply` and `SkeletonStraightScreen`. You can also create your own `TextureImporter` `Preset` asset and blend mode material templates and assign them here. When creating your own, it is recommended to choose a name with `PMA` or `Straight` in it to reflect the used blend mode. Whenever you see dark borders around transparent areas, or colorful stripes around your attachment images, it is very likely because of incorrect import settings. ##### **Correct Texture Packer export and Texture and Material import settings:** 1. Premultiplied Alpha ![](/img/spine-runtimes-guide/spine-unity/premultiplied-alpha-export-import.png) Texture Packer setting `Premultiply alpha` enabled, Unity Texture settings `sRGB (Color Texture)` and `Alpha Is Transparency` disabled, Unity Material parameter `Straight Alpha Texture` disabled. > **Note:** `sRGB (Color Texture)` was previously recommended to be enabled, however when `Generate Mip Maps` is enabled, this combination may lead to white seams. To avoid these artifacts and because it has no drawbacks in Gamma space, it is now recommended to keep `sRGB (Color Texture)` disabled with PMA textures. 2. Straight Alpha ![](/img/spine-runtimes-guide/spine-unity/straight-alpha-export-import.png) Texture Packer setting `Premultiply alpha` disabled, `Bleed` enabled, Unity Texture settings `sRGB (Color Texture)` and `Alpha Is Transparency` enabled, Unity Material parameter `Straight Alpha Texture` enabled. The default texture packer settings use `Premultiply alpha`. All Spine shaders that come with the spine-unity runtime are also configured to use `Premultiply alpha` workflow by default, they have the `Straight Alpha Texture` parameter disabled as default. There might are use cases however, where you may want to use straight alpha workflow. Some of the use cases are: 1. When using **Linear color space**, you **must use straight alpha**. The premultiplication is performed in Gamma space upon export, which will cause incorrect borders when converted back to Linear space on import. You will receive a log warning message when this combination is detected at a material. 2. When you want to use a shader other than the included Spine shaders. Typically shaders will assume straight alpha textures, which will lead to incorrect black borders around attachment images. Be sure to configure all textures and materials accordingly as described above when switching to straight alpha workflow. You can check or modify the current color space via `Project Settings - Player - Other Settings - Color Space`. #### **Import Troubleshooting** When something goes wrong importing your skeleton into Unity there are a number of possible causes, from incorrect Spine export settings to incorrect settings in Unity. This video will help you better understand the correct settings for many common problems during import. !! #### Advanced - Using Unity SpriteAtlas as Atlas Provider > **Note:** It is encouraged to follow the normal Spine workflow and use sprite atlases created by Spine instead of Unity `Sprite Atlas` assets. Spine atlases provide superior packing, support multiple atlas pages and are less prone to problems. Use Unity's `Sprite Atlas` assets as an atlas provider only when you cannot use the normal Spine workflow. Also consider that you can [re-pack](#Combining-Skins) used texture regions of a collected skin to a single atlas texture at runtime. You can use Unity's [`SpriteAtlas`](https://docs.unity3d.com/Manual/class-SpriteAtlas.html) as atlas provider as an alternative to `.atlas.txt` and `.png` files alongside a skeleton data file. Import is handled via a special `Spine SpriteAtlas Import` tool window accessible via `Window - Spine - SpriteAtlas Import`. ![Spine SpriteAtlas Import Window](/img/spine-runtimes-guide/spine-unity/spriteatlas/spine-spriteatlas-import-window.png) Steps to prepare the `Sprite Atlas`: 1. Create a `Sprite Atlas` via `Assets - Create - Sprite Atlas`. 2. Add the folder containing the Sprites to be used as attachments to `Objects for Packing` in the [`Sprite Atlas` Inspector](https://docs.unity3d.com/Manual/class-SpriteAtlas.html). 3. (a) For Unity versions prior to 2018.2, please manually disable `Tight Packing` and enable `Read/Write Enabled`. (b) in Unity versions 2018.2 an newer, these settings are automatically adjusted for you. ![Spine SpriteAtlas Import Window](/img/spine-runtimes-guide/spine-unity/spriteatlas/spriteatlas-inspector.png) 4. Assign the `Sprite Atlas` to the `Sprite Atlas` property in the new `Spine SpriteAtlas Import` window. Additional assets are generated automatically. ![Spine SpriteAtlas Import Window](/img/spine-runtimes-guide/spine-unity/spriteatlas/spine-spriteatlas-import-window-top.png) 5. Hit `Load regions by entering Play mode` to briefly switch into play mode and back again to load the region information. Your `Sprite Atlas` is now ready for use as a Spine atlas. To use the atlas at a `.json` or `.skel.bytes` skeleton asset: 1. Place the `.json` or `.skel.bytes` file in the same directory as the newly created atlas assets. 2. Assign it to the `Skeleton json/skel file` property in the `Spine SpriteAtlas Import` window. ![Spine SpriteAtlas Import Window](/img/spine-runtimes-guide/spine-unity/spriteatlas/spine-spriteatlas-import-window-bottom.png) 3. Hit `Import Skeleton` to generate the `_SkeletonData` file using the `Sprite Atlas` assets. ### Spine Preferences The spine-unity runtime provides a `Spine` section in Unity's `Preferences` window, accessible via `Edit - Preferences` (`Unity - Preferences` on Mac). Here you can setup default values used upon skeleton import and instantiation, as well as customize appearance and update behavior of the spine-unity runtime. ![Spine Preferences Window](/img/spine-runtimes-guide/spine-unity/spine-preferences-window.png) * *Show Hierarchy Icons*. Show relevant icons next to `GameObjects` in the Hierarchy panel with Spine components on them. * *Auto-reload scene components*. Reloads skeleton components in the scene whenever their SkeletonDataAsset is modified. This may be slow when your scenes have large numbers of [SkeletonRenderer](#SkeletonRenderer-Component) or [SkeletonGraphic](#SkeletonGraphic-Component) components. * *Reload SkeletonData after Play*. When enabled, the shared SkeletonData of all skeletons in the active scene is reloaded (from the .json or .skel.bytes file) after exiting play-mode. This may add undesired delays, but prevents (accidental) modifications to the shared SkeletonData during play-mode carrying over its effect into subsequent plays. * *Auto-Import Settings* * *Default Mix*. The [Default Mix Duration](#Mix-Settings) for newly imported SkeletonDataAssets. * *Default SkeletonData Scale*. The default `Scale` value for newly imported SkeletonDataAssets. * *Default Shader*. The default shader assigned at materials created for newly imported skeleton atlas textures. * *Apply Atlas Texture Settings*. Apply reference `Atlas Texture Settings` at texture importers specified below. * *Atlas Texture Settings*. Apply the selected texture import settings at newly imported atlas textures and materials. When exporting atlas textures from Spine with `Premultiply alpha` enabled (the default), you can leave it at `PMATexturePreset`. If you have disabled `Premultiply alpha`, set it to `StraightAlphaTexturePreset`. You can also create your own `TextureImporter` `Preset` asset and assign it here. * *Additive Material*. Material template for slot blend mode `Additive`. See [`SkeletonData`](#Skeleton-Data) Blend Mode Materials. * *Multiply Material*. Material template for slot blend mode `Multiply`. See [`SkeletonData`](#Skeleton-Data) Blend Mode Materials. * *Screen Material*. Material template for slot blend mode `Screen`. See [`SkeletonData`](#Skeleton-Data) Blend Mode Materials. * *Warnings* * *Atlas Extension Warning*. Log a warning and recommendation whenever a `.atlas` file is found. * *Texture Settings Warning*. Log a warning and recommendation whenever texture import settings are detected that could lead to undesired effects, e.g. white border artifacts. * *Component & Material Warning*. Log a warning and recommendation whenever Component and Material settings are not compatible. * *SkeletonDataAsset no file Error*. Log an error when querying `SkeletonData` from `SkeletonDataAsset` with no json or binary file assigned. * *Editor Instantiation* * *Default Slot Z-Spacing*. The default [Z Spacing](#Setting-Advanced-Parameters) parameter of newly instantiated [SkeletonRenderer](#SkeletonRenderer-Component) or [SkeletonGraphic](#SkeletonGraphic-Component) components. * *Default Loop*. The default `Loop` parameter of newly instantiated [SkeletonRenderer](#SkeletonRenderer-Component) or [SkeletonGraphic](#SkeletonGraphic-Component) components. * *Physics Inheritance* * *Default Position*. The Default [Physics Inheritance - Position](#Setting-Advanced-Parameters) scale factor parameter of newly instantiated [SkeletonRenderer](#SkeletonRenderer-Component) or [SkeletonGraphic](#SkeletonGraphic-Component) components. * *Default Rotation*. The Default [Physics Inheritance - Rotation](#Setting-Advanced-Parameters) scale factor parameter of newly instantiated [SkeletonRenderer](#SkeletonRenderer-Component) or [SkeletonGraphic](#SkeletonGraphic-Component) components. * *Mecanim Bake Settings* * *Include Folder Name in Event*. When enabled, Mecanim events will call methods named `"FolderNameEventName"`, when disabled it will call `"EventName"`. * *Handles and Gizmos* * *Editor Bone Scale*. Size of bones and similar gizmo elements displayed in the Scene view. * *Prefabs* * *Fix Prefab Overr. MeshFilter*. Global setting for the equally named skeleton component Inspector parameter, section [Advanced](#Setting-Advanced-Parameters). When the component parameter is set to `Use Global Settings`, this setting is used. * *Optimize Preview Meshes*. When enabled, Spine prefab preview meshes will be removed in a pre-build step to reduce build size. This increases build time as all prefabs in the project will be processed. * *Timeline Extension* - relevant for the [Timeline Extension UPM Package](#Timeline-Extension-UPM-Package) * *Default Mix Duration*. The default value for the [`Default Mix Duration`](#SkeletonAnimation-Track-and-SkeletonGraphic-Track) parameter of newly created `Spine Animation State Clips`. * *Use Blend Duration*. The default value for the [`Use Blend Duration`](#SkeletonAnimation-Track-and-SkeletonGraphic-Track) parameter of newly created `Spine Animation State Clips`. ### Updating Spine Assets During development, you may frequently update your Spine skeleton data and texture atlas files. You can simply overwrite these files (`.json`, `.skel.bytes`, `.atlas.txt`, `.png`). Re-export the assets from the Spine Editor and copy the exported files to your subfolder of your project's `Assets` folder again, overwriting the existing files. Unity will detect changes to these files and automatically re-import the modified assets. After re-import, all references to previously imported Spine assets will be intact and use the latest data. > **Note:** Unity sometimes fails to recognize file changes. In this case, locate the folder containing the Spine assets in Unity's Project panel that you want to re-import, right-click on the folder, then select `Reimport` from the context menu. ### Skeleton Data Asset The skeleton data asset (named with suffix `_SkeletonData`) stores information about the bone hierarchy, slots, draw order, animations and other data that constitutes your skeleton. Other components provided by the spine-unity runtime reference and share this skeleton data asset to animate and display a skeleton. To inspect or modify a skeleton data asset, select it in Unity's Project panel. The Inspector panel will display all properties of the skeleton data for review and modification. ![](/img/spine-runtimes-guide/spine-unity/skeleton-data-settings.png) #### Skeleton Data The SkeletonData section provides general import settings of the skeleton. ![](/img/spine-runtimes-guide/spine-unity/skeleton-data-skeleton-data.png) * *Scale*. Allows you to specify a custom import scale value, affecting all skeleton instances referencing this data asset. Changing the value will immediately affect all instances of this skeleton. > **Note:** When you want to precisely match e.g. 32px of artwork to 1 game unit (and the attachment images have not been scaled in Spine), you can set this `Scale` parameter to `1/px_per_unit`. So for `32px/unit` you would set `Scale` to `1/32 = 0.03125`. * *SkeletonData Modifiers*. Provide a way for users to add additional processing to skeleton data assets after loading from a `.json` or `.skel.bytes` file has been completed. Please consult section [SkeletonData Modifier Assets](#SkeletonData-Modifier-Assets) below for additional information. * *Blend Modes - Upgrade*. Upgrades an obsolete `BlendModeMaterialAsset` to the native Blend Mode Materials properties shown below. * *Blend Mode Materials*. Skeleton slots with special blend modes require additional materials. These materials are setup automatically upon import, unless a `BlendModeMaterialAsset` is in use with older Unity and spine-unity versions. It is recommended to upgrade an assigned `BlendModeMaterialAsset` via the `Blend Modes - Upgrade` button above, as it prevents problems with newer Unity versions. You can customize material templates for each blend mode in the [Spine Preferences](#Spine-Preferences). * *Apply Additive Material*. When enabled, slots with `Additive` blend mode will also have materials generated for them. Enable this parameter when using [Straight alpha](#Advanced---Premultiplied-vs-Straight-Alpha-Export) workflow. It is not necessary when using [PMA](#Advanced---Premultiplied-vs-Straight-Alpha-Export) workflow as `Normal` and `Additive` slots can be drawn with the same PMA material. * *Additive Materials*, *Multiply Materials*, *Screen Materials*. These lists show the currently used blend mode materials for each blend mode. #### Atlas Atlas references are used by the skeleton to resolve the exported image name references to the respective image areas for rendering. ![](/img/spine-runtimes-guide/spine-unity/skeleton-data-atlas.png) Upon import the `Atlas Assets` array is automatically populated with one entry per atlas asset (ending with **_Atlas**). In case spine-unity failed to automatically assign all required atlas assets, you can change the `Atlas Assets` `Size` to the desired amount of atlas assets and manually assign the required atlas assets to `Element0` - `ElementN`. #### Mix Settings The skeleton data asset allows you to specify [animation mix times](/spine-applying-animations#Mix-times). ![](/img/spine-runtimes-guide/spine-unity/mix-settings-custom-duration.gif) `Default Mix Duration` allows you to enter the default mix time, in seconds. You can define mix times for two specific animations by clicking the `Add Custom Mix` button in the `Custom Mix Durations` section of the asset and setting specific mix durations, overriding the default mix duration value above. Components using the skeleton data asset, like the skeleton animation component, use these mix times when playing back animations. #### Preview The Preview section for a skeleton data asset allows you to inspect all bones, slots, animations, skins, and events contained in the asset. ![](/img/spine-runtimes-guide/spine-unity/skeleton-data-previewfull.png) You can playback animations via the play buttons to the left of each animation and view a live update of the respective slots via `Show Attachments` in the `Slots` section. The timeline bar shows all events as purple markers. Hover over the markers while playing to display the event name. ![](/img/spine-runtimes-guide/spine-unity/inspector-preview-small.gif) Use the `Create Animation Reference Assets` button to generate reference assets for all animations of the skeleton. An `AnimationReferenceAsset` acts as a Unity asset referencing a single `Spine.Animation` and can be assigned to component properties in the Inspector. ![](/img/spine-runtimes-guide/spine-unity/animation-reference-asset-usage.gif) #### Skeleton Mecanim In case you want to use Unity's Mecanim animation system instead of Spine's default animation system, you can generate and assign a Mecanim controller via `Generate Mecanim Controller`. ![](/img/spine-runtimes-guide/spine-unity/skeleton-data-mecanim.png) #### Skeleton Baking > **Note:** Baking is a specialized tool and is **not the recommended way** of using Skeletons in spine-unity! It is not used for [SkeletonMecanim](#SkeletonMecanim-Component), [SkeletonAnimation](#SkeletonAnimation-Component) or [SkeletonGraphic (UI)](#SkeletonGraphic-Component) components! It will instead bake a Skeleton down to a less flexible Prefab with a fixed hierarchy of `Transforms` with `MeshRenderers` and compatible animation clips. > A lot of Spine's features don't exist in Unity's Animation system so they can't be translated and are ignored in the process. ![](/img/spine-runtimes-guide/spine-unity/skeleton-baking-window.png) To open the `Skeleton Baking Window`, click on the gear icon at the top right of the `SkeletonDataAsset` Inspector and choose `Skeleton Baking`. A detailled list of supported and unsupported features can be found [here in SkeletonBaker.cs](https://github.com/EsotericSoftware/spine-runtimes/blob/4.2/spine-unity/Assets/Spine/Editor/spine-unity/Editor/Windows/SkeletonBaker.cs#L44-L67). > Note: Baking is not using the recently added Unity 2D animation system but the previously existing 3D `MeshRenderer` based system. ### Texture Atlas Asset The texture atlas asset contains information about the images used by your skeleton, namely on what texture atlas page an image is stored, as well as its UV texture coordinates on the texture atlas page. ![](/img/spine-runtimes-guide/spine-unity/atlas-inspector.png) You can view the material of the texture atlas pages by double clicking the material asset in the `Materials` array. > **Note:** You can modify the materials and textures referenced by the texture atlas asset. When modifying textures, make sure the UV texture coordinates stay valid. The `SkeletonRenderer` components use a normal `MeshRenderer` for rendering, so materials and textures are applied normally just like they would when assigned at e.g. a cube or quad. So you can replace or pre-process the textures at the materials of your Texture Atlas Asset as needed. The `Set Mipmap Bias to -0.5` button is intended for advanced users and can be used to compensate for blurry appearance when `Generate Mip Maps` is enabled on an atlas texture. You can generate sprites for each image element of an atlas by pressing the `Apply Regions as Texture Sprite Slices` button. The generated sprites reference areas of the texture atlas image (`png` file) and can be used as any Unity sprite asset. ### SkeletonData Modifier Assets SkeletonData modifier assets provide a way for users to add additional processing to skeleton data assets after loading from a `.json` or `.skel.bytes` file has been completed. SkeletonDataAsset's Inspector provides a `Skeleton Data Modifiers` list you can add assets to. ![](/img/spine-runtimes-guide/spine-unity/skeletondatamodifierasset-inspector-field.png) #### Included SkeletonData Modifiers - BlendModeMaterialsAsset *(obsolete)* > **Note:** spine-unity now provides **native support for slot blend modes** `Additive`, `Multiply` and `Screen` at each `SkeletonDataAsset`, with automatic setup at newly imported skeleton assets. `BlendModeMaterialAssets` are now obsolete and replaced by the native properties at `SkeletonDataAsset`. The `SkeletonDataAsset` Inspector provides a new `Blend Modes - Upgrade` button to upgrade an obsolete `BlendModeMaterialAsset` to the native blend modes properties. This upgrade will be performed automatically on imported and re-imported assets in Unity 2020.1 and newer to prevent reported `BlendModeMaterialAsset` issues in these Unity versions. spine-unity 4.0 and newer will automatically perform this upgrade regardless of the Unity version. `BlendModeMaterialsAsset` is a SkeletonData modifier asset class included in spine-unity. It holds references to materials that can be used to render attachments within slots that have the `Additive`, `Multiply` and `Screen` blend modes assigned to them in the Spine editor. The Material references stored in BlendModeMaterials assets are used as templates to generate new Materials that use the appropriate texture needed by the loaded attachments. The spine-unity runtime comes packaged with a ready-to-use `BlendModeMaterialsAsset` named `Default BlendModeMaterials`. Using this included asset allows the attachments in slots with special blend modes to use the included default `Multiply` and `Screen` shaders: `Spine/Blend Modes/Skeleton PMA Multiply` and `Spine/Blend Modes/Skeleton PMA Screen`. If you need to use different Materials or shaders or Materials with different settings, you can create new `BlendModeMaterialsAsset`s using `Create -> Spine -> SkeletonData Modifiers -> Blend Mode Materials`. Then assign your Material templates to the created asset. #### Writing a custom SkeletonDataModifierAsset class You can write your own custom `SkeletonDataModifierAsset` class to add additional processing to skeleton data assets after loading from a `.json` or `.skel.bytes` file. `SkeletonDataModifierAsset` is an abstract `ScriptableObject` class where you can derive your own classes from. 1. Create a new class derived from `SkeletonDataModifierAsset` and implement the `void Apply (SkeletonData skeletonData)` method. Add the `CreateAssetMenu` class attribute to list an entry for your class in the `Asset -> Create` menu. ```csharp [[CreateAssetMenu(menuName = "TopMenu/Submenu/SubSubmenu", order = 200)] public class BlendModeMaterialsAsset : SkeletonDataModifierAsset { public override void Apply (SkeletonData skeletonData) { ... } } ``` 2. Create an instance of your new class by selecting your desired folder in the Project panel and selecting your newly created `Asset -> Create` menu entry. Assign the created asset at an element of the `Skeleton Data Modifiers` list of your SkeletonData asset. `Apply(skeletonData)` will be called after loading data from the `.json` or `.skel.bytes` file has been completed. ## Main Components The spine-unity runtime provides you with a set of components that allow to display, animate, follow and modify skeletons exported from Spine. These components reference skeleton data and texture atlas assets you import as described above. ### Adding a Skeleton to a Scene To quickly display a Spine skeleton in your Unity project: 1. Import the skeleton data and texture atlas as described above. 2. Drag the **_SkeletonData** asset into the Scene view or the Hierarchy panel and choose `SkeletonAnimation`. A new GameObject will be instantiated, with the required Spine components already set up. ![](/img/spine-runtimes-guide/spine-unity/drag-and-drop-instantiate.gif) > **Note:** Alternatively to step 2, you can create the same GameObject from scratch: 1. Create a new empty GameObject via `GameObject -> Create Empty`. 2. Select the GameObject and in the inspector click `Add Component`, then select `SkeletonAnimation`. This will automatically add the additional `MeshRenderer` and `MeshFilter` components as well. 3. At the [SkeletonAnimation](#SkeletonAnimation-Component) component, assign the `Skeleton Data Asset` property by dragging the desired **_SkeletonData** asset into it. > **Note:** In case you only see bones of a skeleton in Scene view without any images attached, you might want to switch the `Initial Skin` property to a skin other than `default`. You can now use the components' C# API to animate the skeleton, react to events triggered by animations, etc. Refer to the component documentation below for more details. #### Alternatives to SkeletonAnimation - SkeletonGraphic (UI) and SkeletonMecanim Instantiating a skeleton as [SkeletonAnimation](#SkeletonAnimation-Component) is the recommended way to use a Spine skeleton in Unity, as it provides the most complete feature set of the three alternatives. The three alternatives to instantiate a skeleton are: 1. **[SkeletonAnimation](#SkeletonAnimation-Component)** - Uses Spine's custom animation and event system, providing highest customizability. Renders using a `MeshRenderer`, interacting with masks such as `SpriteMask` like a Unity sprite. *The recommended way of using a Spine skeleton in Unity.* 2. **[SkeletonGraphic (UI)](#SkeletonGraphic-Component)** - For use as UI element together with a Unity `Canvas`. Renders and interacts with UI masks such as `RectMask2D` like the built-in Unity UI elements. Animation and event behavior is identical to [SkeletonAnimation](#SkeletonAnimation-Component). 3. **[SkeletonMecanim](#SkeletonMecanim-Component)** - Uses Unity's Mecanim animation and event system for starting, mixing and transitioning between animations. Provides fewer animation mixing and transition options than [SkeletonAnimation](#SkeletonAnimation-Component). When using `SkeletonMecanim` it will not be guaranteed that transitions will look as previewed in the Spine Editor. #### Advanced - Instantiation at Runtime > **Note:** Prefer using the normal workflow of adding a skeleton to a scene and storing them in a prefabs or reusing pooled objects from an instance pool for instantiation. This makes customization and adjustments easier. While it's not the recommended workflow, the spine-unity API allows you to instantiate `SkeletonAnimation` and `SkeletonGraphic` GameObjects at runtime from a `SkeletonDataAsset`, or even directly from the three exported assets. Instantiation directly from the exported assets is only recommended if you can't use the normal Unity import pipeline to automatically create `SkeletonDataAsset` and `SpineAtlasAsset` assets beforehand. ```csharp // instantiating a SkeletonAnimation GameObject from a SkeletonDataAsset SkeletonAnimation instance = SkeletonAnimation.NewSkeletonAnimationGameObject(skeletonDataAsset); // instantiating a SkeletonGraphic GameObject from a SkeletonDataAsset SkeletonGraphic instance = SkeletonGraphic.NewSkeletonGraphicGameObject(skeletonDataAsset, transform, skeletonGraphicMaterial); ``` ```csharp // instantiation from exported assets without prior import // 1. Create the AtlasAsset (needs atlas text asset and textures, and materials/shader); // 2. Create SkeletonDataAsset (needs json or binary asset file, and an AtlasAsset) SpineAtlasAsset runtimeAtlasAsset = SpineAtlasAsset.CreateRuntimeInstance(atlasTxt, textures, materialPropertySource, true); SkeletonDataAsset runtimeSkeletonDataAsset = SkeletonDataAsset.CreateRuntimeInstance(skeletonJson, runtimeAtlasAsset, true); // 3. Create SkeletonAnimation (needs a valid SkeletonDataAsset) SkeletonAnimation instance = SkeletonAnimation.NewSkeletonAnimationGameObject(runtimeSkeletonDataAsset); ``` You can examine the example scene `Spine Examples/Other Examples/Instantiate from Script` and the used example scripts `SpawnFromSkeletonDataExample.cs`, `RuntimeLoadFromExportsExample.cs` and `SpawnSkeletonGraphicExample.cs` for additional information. ### SkeletonAnimation Component The `SkeletonAnimation` component is one of three ways to use a Spine skeleton in Unity. These alternatives are: [SkeletonAnimation](#SkeletonAnimation-Component), [SkeletonMecanim](#SkeletonMecanim-Component) and [SkeletonGraphic (UI)](#SkeletonGraphic-Component). The SkeletonAnimation component is the heart of the spine-unity runtime. It allows you to add a Spine skeleton to a GameObject, animate it, react to animation events, and so on. ![](/img/spine-runtimes-guide/spine-unity/skeleton-animation-component.png) #### Setting Skeleton Data A [SkeletonAnimation](#SkeletonAnimation-Component) component requires a reference to a skeleton data asset from which it can get the information about a skeleton's bone hierarchy, slots etc. If you have added a skeleton to a scene via [drag and drop](#Adding-a-Skeleton-to-a-Scene), the skeleton data asset is automatically assigned. In case you have an already set up GameObject and suddenly want to change the skeleton to a different asset, you can manually change it via the provided Inspector property. To set or change the skeleton data 1. Select the [SkeletonAnimation](#SkeletonAnimation-Component) GameObject 2. Assign a **_SkeletonData** asset at the `SkeletonData Asset` property in the Inspector. #### Setting Initial Skin and Animation The [SkeletonAnimation](#SkeletonAnimation-Component) Inspector exposes the following parameters 1. *Initial Skin*. This skin will be assigned upon start. Note: In case you only see bones of a skeleton without any images attached, you might want to switch to a skin other than `default` to show your skin. 2. *Animation Name*. This animation will be played upon start. 3. *Loop*. Defines whether the initial animation shall be looped or played only once. 4. *Time Scale*. You can set the time scale to slow down or speed up playback of animations. 5. *Unscaled Time*. When set to `true`, updates will be performed according to [Time.unscaledDeltaTime](https://docs.unity3d.com/ScriptReference/Time-unscaledDeltaTime.html) instead of [Time.deltaTime](https://docs.unity3d.com/ScriptReference/Time-deltaTime.html). This is useful to animate UI elements independently of slow-motion effects. #### Enabling Root Motion Root motion for `SkeletonAnimation` and [SkeletonGraphic (UI)](#SkeletonGraphic-Component) components is provided via a separate [SkeletonRootMotion](#SkeletonRootMotion) component. The `SkeletonAnimation` Inspector provides a `Root Motion` `Add Component` button to quickly add the suitable component to your skeleton GameObject. #### Setting Advanced Parameters Unfold the `Advanced` section in the [SkeletonAnimation](#SkeletonAnimation-Component) Inspector to show advanced configuration parameters. ![](/img/spine-runtimes-guide/spine-unity/skeleton-animation-component-advanced.png) The [SkeletonAnimation](#SkeletonAnimation-Component) Inspector exposes the following advanced parameters * *Initial Flip X, Initial Flip Y*. These parameters allow you to flip the skeleton horizontally and vertically upon start. This will set *ScaleX* and *ScaleY* to *-1* where flipped. * *Animation Update*. Whether to update the animation in normal `Update` *(the default)*, physics step `FixedUpdate`, or manually via a user call. When using a [SkeletonRootMotion](#SkeletonRootMotion) component with a `Rigidbody` or `Rigidbody2D` assigned, it is recommended to set the update mode to `In FixedUpdate`. Otherwise `In Update` is recommended. * *Update When Invisible*. Update mode used when the MeshRenderer becomes invisible. Update mode is automatically reset to `UpdateMode.FullUpdate` when the mesh becomes visible again. * *Use single submesh*. Can be enabled to simplify submesh generation by assuming you are only using one Material and need only one submesh. This is will disable multiple materials, render separation, and custom slot materials. * *Fix Draw Order*. Applies only when 3+ submeshes are used (2+ materials with alternating order, e.g. "A B A"). If true, MaterialPropertyBlocks are assigned at each material to prevent aggressive batching of submeshes by e.g. the LWRP renderer, leading to incorrect draw order (e.g. "A1 B A2" changed to "A1A2 B"). You can leave this parameter disabled when everything is drawn correctly to save the additional performance cost. * *Immutable triangles*. Can be enabled to optimize rendering for skeletons that never change attachment visbility. If true, triangles will not be updated. Enable this as an optimization if the skeleton does not make use of attachment swapping or hiding, or draw order keys. Otherwise, setting this to false may cause errors in rendering. * *Clear State on Disable*. Clears the state of the render and skeleton when this component or its GameObject is disabled. This prevents previous state from being retained when it is enabled again. When pooling your skeleton, setting this to true can be helpful. * *Fix Prefab Override MeshFilter*. Fixes the prefab always being marked as changed (sets the `MeshFilter's` hide flags to `DontSaveInEditor`), but at the cost of references to the `MeshFilter` by other components being lost. When set to `Use Global Settings`, the setting in [Spine Preferences](#Spine-Preferences) is used. * *Separator Slot Names*. Slots that determine where the render is split. This is used by components such as `SkeletonRenderSeparator` so that the skeleton can be rendered by two separate renderers on different GameObjects. * *Z-Spacing*. Attachments are rendered back to front in the x/y plane by the skeleton renderer component. Each attachment is offset by a customizable z-spacing value on the z-axis to avoid [z-fighting](https://en.wikipedia.org/wiki/Z-fighting). ![](/img/spine-runtimes-guide/spine-unity/z-spacing-small.gif) * *PMA Vertex Colors*. Multiply vertex color RGB with vertex color alpha. Enable this parameter if the shader used for rendering is a Spine shader (even with `Straight Alpha Texture`) or a thirdparty shader which uses PMA additive blend mode `Blend One OneMinusSrcAlpha`. Disable this parameter for normal shaders with regular blend mode `Blend SrcAlpha OneMinusSrcAlpha`. When enabled, additive slots can be rendered in a single draw call together with normal slots. When disabled, additive slots require [`SkeletonData`](#Skeleton-Data) *Blend Mode Materials - Apply Additive Material* enabled, leading to a separate draw call, which may adversely affect performance. * *Tint Black (!)*. Adds black tint vertex data to the mesh. Enable if the skeleton has any slots with tint black color set. Black tinting requires that the shader interprets UV2 and UV3 as black tint colors for this effect to work. You may use the included `Spine/Skeleton Tint Black` shader. If you only need to tint the whole skeleton and not individual parts, the `Spine/Skeleton Tint` shader is recommended for better efficiency and changing/animating the `_Black` material property via MaterialPropertyBlock. See section [Shaders](#Shaders) for additional information. To retain batching while tinting multiple skeletons differently, [tinting via Skeleton.R .G .B .A](#Changing-Materials-Per-Instance) is recommended. * *Add Normals*. When enabled, the mesh generator adds normals to the output mesh. Enable if your shader requires vertex normals. For better performance and reduced memory usage, you can instead use a shader such as the `Spine/Skeleton Lit` shader that assumes the desired normal. Note that the `Spine/Sprite` shaders can be configured to assume a `Fixed Normal` as well. * *Solve Tangents*. Some lit shaders require vertex tangents, usually for applying normal maps. When enabled, tangents are calculated every frame and added to the output mesh. * *Physics Inheritance.* Controls how Transform movement is applied to PhysicsConstraints of the skeleton. * *Position*. When set to non-zero, Transform position movement in X and Y direction is applied to skeleton PhysicsConstraints, multiplied by these X and Y scale factors. Typical (X,Y) values are: (1,1) to apply XY movement normally, (2,2) to apply movement with double intensity, (1,0) to apply only horizontal movement, or (0,0) to not apply any Transform position movement at all. * *Rotation*. When set to non-zero, Transform rotation movement is applied to skeleton PhysicsConstraints, multiplied by this scale factor. Typical values are: 1 to apply movement normally, 2 to apply movement with double intensity, or 0 to not apply any Transform rotation movement at all. * *Movement relative to*. To apply Transform movement relative to e.g. a parent Transform, set this to the reference Transform relative to which movement shall be calculated. Set this to *None* to use the absolute world location *(the default)*. * *Add Skeleton Utility*. This button can be used to quickly add a `SkeletonUtility` component to the GameObject for tracking or overriding bone positions. See [SkeletonUtility](#SkeletonUtility) for further info. * *Debug*. Sometimes you may want to know the current color of a slot or scale of a bone while the game is running. Pressing the *Debug* button opens the *Skeleton Debug* window which was created for this purpose. It allows you to inspect the current state of bones, slots, constraints, draw order, events and statistical information about your skeleton. ![](/img/spine-runtimes-guide/spine-unity/debug-window.png) #### Life-cycle ![](/img/spine-runtimes-guide/spine-unity/spine-unity-skeletonanimation-updates.png) In the [SkeletonAnimation](#SkeletonAnimation-Component) component, AnimationState holds the state of all currently playing and queued animations. Every `Update`, the AnimationState is updated so that the animations progress forward in time. And then the new frame is applied to the Skeleton as a new pose. Your scripts may run before or after SkeletonAnimation's `Update`. If your code takes Skeleton or bone values before SkeletonAnimation's Update, your code will read values from the previous frame instead of the current one. The component exposes the event callback delegates as properties that allow you to intercept this life-cycle before and after the world transforms of all bones are calculated. You can bind to these delegates to modify bone positions and other aspects of the skeleton without having to care for the update order of your actors and components. SkeletonAnimation Update Callbacks - `SkeletonAnimation.BeforeApply` is raised before the animations for the frame are applied. Use this callback when you want to change the skeleton state before animations are applied on top. - `SkeletonAnimation.UpdateLocal` is raised after the animations for the frame are updated and applied to the skeleton's local values. Use this if you need to read or modify bone local values. - `SkeletonAnimation.UpdateComplete` is raised after world values are calculated for all bones in the Skeleton. SkeletonAnimation makes no further operations in Update after this. Use this if you only need to read bone world values. Those values may still change if any of your scripts modify them after SkeletonAnimation's Update. - `SkeletonAnimation.UpdateWorld` is raised after the world values are calculated for all the bones in the Skeleton. If you subscribe to this event, it will call `skeleton.UpdateWorldTransform` a second time. Depending on the complexity of your skeleton or what you are doing, this may be unnecessary, or wasteful. Use this event if you need to modify bone local values based on bone world values. This is useful for implementing custom constraints in Unity code. ```csharp // your delegate method void AfterUpdateComplete (ISkeletonAnimation anim) { // this is called after animation updates have been completed. } // register your delegate method void Start() { skeletonAnimation.UpdateComplete -= AfterUpdateComplete; skeletonAnimation.UpdateComplete += AfterUpdateComplete; } ``` SkeletonRenderer Update Callbacks - `OnRebuild` is raised after the Skeleton is successfully initialized. - `OnMeshAndMaterialsUpdated` is raised at the end of `LateUpdate()` after the Mesh and all materials have been updated. ```csharp // your delegate method for OnMeshAndMaterialsUpdated void AfterMeshAndMaterialsUpdated (SkeletonRenderer renderer) { // this is called after mesh and materials have been updated. } // your delegate method for OnRebuild void AfterRebuild (SkeletonRenderer renderer) { // this is called after the Skeleton is successfully initialized. } // register your delegate method void Start() { skeletonAnimation.OnMeshAndMaterialsUpdated -= AfterMeshAndMaterialsUpdated; skeletonAnimation.OnMeshAndMaterialsUpdated += AfterMeshAndMaterialsUpdated; skeletonAnimation.OnRebuild -= AfterRebuild; skeletonAnimation.OnRebuild += AfterRebuild; } ``` As an alternative, you can change Script Execution Order to run after SkeletonAnimation's Update method. For more information on Unity's MonoBehaviour Lifecycle, see: [docs.unity3d.com/Manual/ExecutionOrder](https://docs.unity3d.com/Manual/ExecutionOrder.html) ##### **C#** Interacting with a skeleton via code requires accessing the SkeletonAnimation component. As applies to Unity components in general, it is recommended to query the reference once and store it for further use. ```csharp ... using Spine.Unity; public class YourComponent : MonoBehaviour { SkeletonAnimation skeletonAnimation; Spine.AnimationState animationState; Spine.Skeleton skeleton; void Awake () { skeletonAnimation = GetComponent(); skeleton = skeletonAnimation.Skeleton; //skeletonAnimation.Initialize(false); // when not accessing skeletonAnimation.Skeleton, // use Initialize(false) to ensure everything is loaded. animationState = skeletonAnimation.AnimationState; } ``` ### Skeleton The [SkeletonAnimation](#SkeletonAnimation-Component) component provides access to the underlying [skeleton](/spine-using-runtimes#Skeleton) via the `SkeletonAnimation.Skeleton` property. A Skeleton stores a reference to a skeleton data asset, which in turn references one or more atlas assets. The Skeleton allows you to set skins, attachments, reset bones to setup pose and scale and flip the whole skeleton. #### Setting Attachments To set an attachment, provide the slot and attachment name. ```csharp bool success = skeletonAnimation.Skeleton.SetAttachment("slotName", "attachmentName"); ``` ```csharp // using properties [SpineSlot] public string slotProperty = "slotName"; [SpineAttachment] public string attachmentProperty = "attachmentName"; ... bool success = skeletonAnimation.Skeleton.SetAttachment(slotProperty, attachmentProperty); ``` Note that `[SpineSlot]` and `[SpineAttachment]` in the above code are [String Property Attributes](#Scripting-String-Property-Attributes) described in [this section](#Scripting-String-Property-Attributes). #### Resetting to Setup Pose For [procedural animation](/spine-runtime-skeletons#Procedural-animation) it is sometimes necessary to reset bones and/or slots to their setup pose. After setting [skins](/spine-runtime-skins) you likely want to call [`Skeleton.SetSlotsToSetupPose`](/spine-runtime-skins#Skin-changes) as described in section [Setting Skins](#Setting-Skins) below. ```csharp skeleton.SetToSetupPose(); skeleton.SetBonesToSetupPose(); skeleton.SetSlotsToSetupPose(); ``` #### Setting Skins A Spine skeleton may have multiple [skins](/spine-runtime-skins) that define which attachment goes on which slot. The skeleton component provides a simple way to switch between skins. ```csharp bool success = skeletonAnimation.Skeleton.SetSkin("skinName"); skeletonAnimation.Skeleton.SetSlotsToSetupPose(); // see note below ``` ```csharp // using properties [SpineSkin] public string skinProperty = "skinName"; ... bool success = skeletonAnimation.Skeleton.SetSkin(skinProperty); skeletonAnimation.Skeleton.SetSlotsToSetupPose(); // see note below ``` You likely want to call `Skeleton.SetSlotsToSetupPose` after changing skins if you don't want previously set attachments to affect the visibility of your current attachments. See the documentation [here](/spine-runtime-skins#Skin-changes) for details. #### Combining Skins Spine skins can be combined to e.g. form a complete character skin from single cloth item skins. See the [new Skin API documentation](/blog/Spine-3-8-released#Improved-skin-API) for more details. ```csharp var skeleton = skeletonAnimation.Skeleton; var skeletonData = skeleton.Data; var mixAndMatchSkin = new Skin("custom-girl"); mixAndMatchSkin.AddSkin(skeletonData.FindSkin("skin-base")); mixAndMatchSkin.AddSkin(skeletonData.FindSkin("nose/short")); mixAndMatchSkin.AddSkin(skeletonData.FindSkin("eyelids/girly")); mixAndMatchSkin.AddSkin(skeletonData.FindSkin("eyes/violet")); mixAndMatchSkin.AddSkin(skeletonData.FindSkin("hair/brown")); mixAndMatchSkin.AddSkin(skeletonData.FindSkin("clothes/hoodie-orange")); mixAndMatchSkin.AddSkin(skeletonData.FindSkin("legs/pants-jeans")); mixAndMatchSkin.AddSkin(skeletonData.FindSkin("accessories/bag")); mixAndMatchSkin.AddSkin(skeletonData.FindSkin("accessories/hat-red-yellow")); skeleton.SetSkin(mixAndMatchSkin); skeleton.SetSlotsToSetupPose(); skeletonAnimation.AnimationState.Apply(skeletonAnimation.Skeleton); // skeletonMecanim.Update() for SkeletonMecanim ``` ##### Runtime Repacking While combining skins, multiple materials may be accumulated. This leads to additional draw calls. The `Skin.GetRepackedSkin()` method can be used to combine used texture regions of a collected skin to a single texture at runtime. ```csharp using Spine.Unity.AttachmentTools; // Create a repacked skin. Skin repackedSkin = collectedSkin.GetRepackedSkin("Repacked skin", skeletonAnimation.SkeletonDataAsset.atlasAssets[0].PrimaryMaterial, out runtimeMaterial, out runtimeAtlas); collectedSkin.Clear(); // Use the repacked skin. skeletonAnimation.Skeleton.Skin = repackedSkin; skeletonAnimation.Skeleton.SetSlotsToSetupPose(); skeletonAnimation.AnimationState.Apply(skeletonAnimation.Skeleton); // skeletonMecanim.Update() for SkeletonMecanim // You can optionally clear the cache after multiple repack operations. AtlasUtilities.ClearCache(); ``` > **Important Note:** If repacking fails or creates unexpected results, it is most likely due to any of the following causes: > 1. Read/Write is disabled: Depending on platform capabilities, you may need to set the `Read/Write Enabled` parameter at source textures that shall be combined to a repacked texture. > 2. Compression is enabled: Depending on the platform, ensure that the source texture has Texture import setting `Compression` set to `None` instead of `Normal Quality`. > 3. Quality tier uses half/quarter resolution textures: There is a known Unity bug that copies incorrect regions when half or quarter resolution rextures are used. Ensure that all Quality tiers in Project Settings are using full resolution textures. > 4. The source texture is not a power-of-two texture but Unity enlarges it to the closest power: Either a) export from Spine with [Pack Settings](/spine-texture-packer#Settings) `Power of two` enabled, or b) make sure the atlas Texture import settings in Unity has `Non-Power of Two` set to `None`. You can examine the example scenes `Spine Examples/Other Examples/Mix and Match` and `Spine Examples/Other Examples/Mix and Match Equip` and the used `MixAndMatch.cs` example script for further insights. ##### Advanced - Runtime Repacking with Normalmaps You can also repack normal maps and other additional texture layers alongside the main texture. Pass `int[] additionalTexturePropertyIDsToCopy = new int[] { Shader.PropertyToID("_BumpMap") };` as parameter to `GetRepackedSkin()` to repack both the main texture and the normal map layer. ```csharp Material runtimeMaterial; Texture2D runtimeAtlas; Texture2D[] additionalOutputTextures = null; int[] additionalTexturePropertyIDsToCopy = new int[] { Shader.PropertyToID("_BumpMap") }; Skin repackedSkin = prevSkin.GetRepackedSkin("Repacked skin", skeletonAnimation.SkeletonDataAsset.atlasAssets[0].PrimaryMaterial, out runtimeMaterial, out runtimeAtlas, additionalTexturePropertyIDsToCopy : additionalTexturePropertyIDsToCopy, additionalOutputTextures : additionalOutputTextures); // Use the repacked skin. skeletonAnimation.Skeleton.Skin = repackedSkin; skeletonAnimation.Skeleton.SetSlotsToSetupPose(); skeletonAnimation.AnimationState.Apply(skeletonAnimation.Skeleton); // skeletonMecanim.Update() for SkeletonMecanim ``` > **Note:** Typically the normal map property is named `"_BumpMap"`. When using a custom shader, be sure to use the respective property name. Note that this name is the property name in the shader, not the `"Normal Map"` label string shown in the Inspector. #### Changing Scale and Flipping a Skeleton Flipping a skeleton vertically or horizontally allows you to reuse animations, e.g. a walk animation facing left can be played back to face right. ```csharp bool isFlippedX = skeleton.ScaleX < 0; skeleton.ScaleX = -1; bool isFlippedY = skeleton.ScaleY < 0; skeleton.ScaleY = -1; skeleton.ScaleX = -skeleton.ScaleX; // toggle flip x state ``` #### Getting and Setting Bone Transforms Manually > **Note:** **Recommended for very special use cases only.** The Spine [BoneFollower](#BoneFollower) and Spine [SkeletonUtilityBone](#SkeletonUtilityBone) components are an easier way to interact with bones. The Skeleton lets you set and get bone transform values so you can implement IK terrain following or let other actors and components such as particle systems follow the bones in your skeleton. > **Note:** Make sure you get and apply new bone positions as part of the update world transform life-cycle by subscribing to the [`SkeletonAnimation.UpdateWorld`](#Life-cycle) delegate. Otherwise your modifications may be one frame too late when read, or overwritten by animations when set. ```csharp Bone bone = skeletonAnimation.Skeleton.FindBone("boneName"); Vector3 worldPosition = bone.GetWorldPosition(skeletonAnimation.transform); // note: when using SkeletonGraphic, all values need to be scaled by the parent Canvas.referencePixelsPerUnit. Vector3 position = ...; bone.SetPositionSkeletonSpace(position); Quaternion worldRotationQuaternion = bone.GetQuaternion(); ``` ### Animation - AnimationState #### Life-cycle The [SkeletonAnimation](#SkeletonAnimation-Component) component implements the `Update` method in which it updates the underlying [AnimationState](/spine-applying-animations#AnimationState-API) based on the delta time, applies the `AnimationState` to the skeleton, and updates the world transforms of all bones of the skeleton. The skeleton animation component exposes the [AnimationState](/spine-api-reference#AnimationState) API via the `SkeletonAnimation.AnimationState` property. This section assumes a familiarity with concepts like tracks, track entries, mix times, or animation queuing as described in the section [Applying Animations](/spine-applying-animations) in the generic Spine Runtime Guide. #### Time Scale You can set the time scale of the skeleton animation component to slow down or speed up the playback of animations. The delta time used to advance animations is simply multiplied with the time scale, e.g. a time scale of 0.5 slows the animation down to half the normal speed, a time scale of 2 speeds it up to twice the normal speed. ```csharp float timeScale = skeletonAnimation.timeScale; skeletonAnimation.timeScale = 0.5f; ``` #### Setting Animations To set an animation, provide the track index, animation name and whether to loop the animation. ```csharp TrackEntry entry = skeletonAnimation.AnimationState.SetAnimation(trackIndex, "walk", true); ``` ```csharp // using properties [SpineAnimation] public string animationProperty = "walk"; ... TrackEntry entry = skeletonAnimation.AnimationState.SetAnimation(trackIndex, animationProperty, true); ``` As an alternative, you can use an [AnimationReferenceAsset](#Preview) instead of a string as parameter. ```csharp // using AnimationReferenceAsset public AnimationReferenceAsset animationReferenceAsset; // assign a generated AnimationReferenceAsset to this property ... TrackEntry entry = skeletonAnimation.AnimationState.SetAnimation(trackIndex, animationReferenceAsset, true); ``` ##### Queueing Animations To queue an animation, provide the track index, animation name, whether to loop the animation, and the delay after which this animation should start playing on the track in seconds. ```csharp TrackEntry entry = skeletonAnimation.AnimationState.AddAnimation(trackIndex, "run", true, 2); ``` ```csharp // using properties [SpineAnimation] public string animationProperty = "run"; ... TrackEntry entry = skeletonAnimation.AnimationState.AddAnimation(trackIndex, animationProperty, true, 2); ``` #### Setting and Queueing Empty Animations, Clearing Tracks The skeleton animation component also provides methods to set an empty animation, queue an empty animation, or clear one or all tracks. All of these work analogous to the methods and nodes shown above. ```csharp TrackEntry entry = skeletonAnimation.AnimationState.SetEmptyAnimation(trackIndex, mixDuration); entry = skeletonAnimation.AnimationState.AddEmptyAnimation(trackIndex, mixDuration, delay); skeletonAnimation.AnimationState.ClearTrack(trackIndex); skeletonAnimation.AnimationState.ClearTracks(); ``` #### Track Entries You'll receive a [TrackEntry](/spine-api-reference#TrackEntry) from all the methods that allows you to further customize the playback of this specific animation, as well as bind to delegates of track entry specific events. See the section *Processing AnimationState Events* below. > **Note:** The returned track entries will only be valid until the corresponding animation is removed from the underlying animation state. The Unity garbage collector will automatically free them. After a dispose event is received for a track entry, it should no longer be stored or accessed. ```csharp TrackEntry entry = ... entry.EventThreshold = 2; float trackEnd = entry.TrackEnd; ``` #### Processing AnimationState Events While animations are played back by the underlying `AnimationState`, various events will be emitted that notify listeners that 1. An animation **started**. 2. An animation was **interrupted**, e.g. by clearing a track or setting a new animation. 4. An animation was **completed** without interruption, which may occur multiple times if looped. 3. An animation has **ended**. 5. An animation and its corresponding `TrackEntry` have been **disposed**. 6. A user defined **event** was fired. > **Note:** When setting a new animation which interrupts a previous one, no `complete` event will be raised but `interrupt` and `end` events will be raised instead. The skeleton animation component provides delegates to which C# code can bind in order to react to these events for all queued animations on all tracks. Listeners can also be bound to the corresponding delegates of a specific `TrackEntry` only. So you can register to e.g. `AnimationState.Complete` to handle event callbacks for any future animation `Complete` event, or instead register to a single `TrackEntry.Complete` event to handle `Complete` events issued by a single specific enqueued animation. ##### **C#** In the class that should react to `AnimationState` events, add delegates for the events you want to listen to: ```csharp SkeletonAnimation skeletonAnimation; Spine.AnimationState animationState; void Awake () { skeletonAnimation = GetComponent(); animationState = skeletonAnimation.AnimationState; // registering for events raised by any animation animationState.Start += OnSpineAnimationStart; animationState.Interrupt += OnSpineAnimationInterrupt; animationState.End += OnSpineAnimationEnd; animationState.Dispose += OnSpineAnimationDispose; animationState.Complete += OnSpineAnimationComplete; animationState.Event += OnUserDefinedEvent; // registering for events raised by a single animation track entry Spine.TrackEntry trackEntry = animationState.SetAnimation(trackIndex, "walk", true); trackEntry.Start += OnSpineAnimationStart; trackEntry.Interrupt += OnSpineAnimationInterrupt; trackEntry.End += OnSpineAnimationEnd; trackEntry.Dispose += OnSpineAnimationDispose; trackEntry.Complete += OnSpineAnimationComplete; trackEntry.Event += OnUserDefinedEvent; } public void OnSpineAnimationStart(TrackEntry trackEntry) { // Add your implementation code here to react to start events } public void OnSpineAnimationInterrupt(TrackEntry trackEntry) { // Add your implementation code here to react to interrupt events } public void OnSpineAnimationEnd(TrackEntry trackEntry) { // Add your implementation code here to react to end events } public void OnSpineAnimationDispose(TrackEntry trackEntry) { // Add your implementation code here to react to dispose events } public void OnSpineAnimationComplete(TrackEntry trackEntry) { // Add your implementation code here to react to complete events } string targetEventName = "targetEvent"; string targetEventNameInFolder = "eventFolderName/targetEvent"; public void OnUserDefinedEvent(Spine.TrackEntry trackEntry, Spine.Event e) { if (e.Data.Name == targetEventName) { // Add your implementation code here to react to user defined event } } // you can cache event data to save the string comparison Spine.EventData targetEventData; void Start () { targetEventData = skeletonAnimation.Skeleton.Data.FindEvent(targetEventName); } public void OnUserDefinedEvent(Spine.TrackEntry trackEntry, Spine.Event e) { if (e.Data == targetEventData) { // Add your implementation code here to react to user defined event } } ``` See the [Spine API Reference](/spine-api-reference#AnimationStateListener-Methods) for detailled information. ##### **Changing AnimationState or Game State in Callbacks** While you can modify `AnimationState` by e.g. calling `AnimationState.SetAnimation()` from within an `AnimationState` event callback, there are some potential timing issues to consider. This also applies when changing your game state from an event callback. 1. `AnimationState` event callbacks are issued when animations are applied in `SkeletonAnimation.Update()`, before the mesh is updated in `SkeletonAnimation.LateUpdate()`. 2. If you call `AnimationState.SetAnimation()` from the [`AnimationState.End`](/spine-api-reference#AnimationStateListener-end) callback, it will trigger an [`AnimationState.Start`](/spine-api-reference#AnimationStateListener-start) event in the same frame. 3. Because of mix transitions from one animation to another, the `Start` event of your second animation is issued _before_ the `End` event of your first animation. This is a common pitfall to consider when modifying game state. If you need to delay calls from within an event callback to the next `Update()` cycle, you could use `StartCoroutine` as follows: ```csharp trackEntry.End += e => { StartCoroutine(NextFrame(() => { YourCode(); })); }; ... IEnumerator NextFrame (System.Action call) { yield return 0; if (call != null) call(); } ``` ##### **Coroutine Yield Instructions** The spine-unity runtime provides a set of yield instructions for use with Unity's Coroutines. If you are new to Unity Coroutines, the [Coroutine tutorials](https://unity3d.com/learn/tutorials/topics/scripting/coroutines) and [Coroutine documentation](https://docs.unity3d.com/Manual/Coroutines.html) are a good place to start. The following yield instructions are provided: 1. **WaitForSpineAnimation**. Waits until a `Spine.TrackEntry` raises one of the specified events. ```csharp var track = skeletonAnimation.state.SetAnimation(0, "interruptible", false); var completeOrEnd = WaitForSpineAnimation.AnimationEventTypes.Complete | WaitForSpineAnimation.AnimationEventTypes.End; yield return new WaitForSpineAnimation(track, completeOrEnd); ``` 1. **WaitForSpineAnimationComplete**. Waits until a `Spine.TrackEntry` raises a `Complete` event. ```csharp var track = skeletonAnimation.state.SetAnimation(0, "talk", false); yield return new WaitForSpineAnimationComplete(track); ``` 1. **WaitForSpineAnimationEnd**. Waits until a `Spine.TrackEntry` raises an `End` event. ```csharp var track = skeletonAnimation.state.SetAnimation(0, "talk", false); yield return new WaitForSpineAnimationEnd(track); ``` 1. **WaitForSpineEvent**. Waits until a `Spine.AnimationState` raises a user-defined `Spine.Event` (named in Spine editor). ```csharp yield return new WaitForSpineEvent(skeletonAnimation.state, "spawn bullet"); // You can also pass a Spine.Event's Spine.EventData reference. Spine.EventData spawnBulletEvent; // cached in e.g. Start() .. yield return new WaitForSpineEvent(skeletonAnimation.state, spawnBulletEvent); ``` > **Note:** Like Unity's built-in yield instructions, instances of these spine-unity yield instructions can be reused to prevent additional memory allocations. ##### **Tutorial Page** You can find a tutorial page on spine-unity events [here](/spine-unity-events). #### Scripting String Property Attributes It is not convenient to type e.g. animation names manually in the Inspector. Thus spine-unity provides popup fields for string parameters instead. You can precede a `string` property with one of the following property attributes to automatically receive a popup selection field, populated with e.g. all available animations at a skeleton. If you can see such popup fields in one of the provided Spine components, you can also use the same popup via property attributes in your custom components. The following list shows available property attributes. ```csharp [SpineBone] public string bone; [SpineSlot] public string slot; [SpineAttachment] public string attachment; [SpineSkin] public string skin; [SpineAnimation] public string animation; [SpineEvent] public string event; [SpineIkConstraint] public string ikConstraint; [SpineTransformConstraint] public string transformConstraint; [SpinePathConstraint] public string pathConstraint; ``` Please take a look at the [example scenes](#Example-Scenes) that come with the spine-unity package to see the string property attributes in use. ### SkeletonMecanim Component The `SkeletonMecanim` component is one of three ways to use a Spine skeleton in Unity. These alternatives are: [SkeletonAnimation](#SkeletonAnimation-Component), [SkeletonMecanim](#SkeletonMecanim-Component) and [SkeletonGraphic (UI)](#SkeletonGraphic-Component). The `SkeletonMecanim` component is an alternative to the [SkeletonAnimation](#SkeletonAnimation-Component) component, using Unity's Mecanim animation system for high-level control in combination with the Spine animation system for posing and setup of the skeleton. The Mecanim system is used to determine which Spine animations shall be played back and determines track time and alpha of each animation. The respective Spine animations are then [applied to the Spine skeleton](/spine-applying-animations#Timeline-API) by the component. Like the [SkeletonAnimation](#SkeletonAnimation-Component) component, `SkeletonMecanim` allows you to add a Spine skeleton to a GameObject, animate it, react to animation events, and so on. After the animations are applied, before the skeleton is drawn, you can make changes to the skeleton just like you can when using [SkeletonAnimation](#SkeletonAnimation-Component) instead of SkeletonMecanim. In comparison to [SkeletonAnimation](#SkeletonAnimation-Component) it comes with some limitations and additional requirements: > **Note:** Compared to the [SkeletonAnimation component](#SkeletonAnimation-Component), `SkeletonMecanim` requires additional timeline keys at the first frame of an animation if it shall smoothly mix out the timeline state of a preceding animation. See section [Required Additional Keys](#Required-Additional-Keys) below for more information. > **Note:** [`TrackEntry.AttachmentThreshold`](/spine-api-reference#TrackEntry-attachmentThreshold) and similar mix threshold functionality is not available for `SkeletonMecanim`. ![](/img/spine-runtimes-guide/spine-unity/skeleton-mecanim-component.png) The `SkeletonMecanim` component provides similar parameters as the [SkeletonAnimation component](#SkeletonAnimation-Component), please consult the [SkeletonAnimation section](#SkeletonAnimation-Component) for additional information. #### Required Additional Keys To smoothly mix out a timeline state (e.g. bone rotation) from one animation to the next, the second animation requires an additional key at the first frame when in setup pose. Otherwise the previous animation would leave a leftover timeline state. This is one of the drawbacks of `SkeletonMecanim` compared to [SkeletonAnimation](#SkeletonAnimation-Component). > Short example: An `idle` animation shall smoothly mix out a preceding `jump` animation. Assuming `jump` ends with bones `bone1` and `bone2` keyed in non-setup-pose location, you have to add keys (in setup pose or any custom pose) at the first frame of the `idle` animation for `bone1` and `bone2` to properly mix out the `jump` state. The `Auto Reset` parameter resets the state, but will mix out sharply at the end of an animation transition, not creating a smooth transition. Also be sure to disable `Animation cleanup` upon exporting your skeleton as `.json` or `.skel.bytes`, otherwise keys identical to setup pose will not be exported! #### Parameters for animation blending control The `SkeletonMecanim` Inspector exposes the following additional parameters: * *Mecanim Translator* * *Auto Reset*. When set to `true`, the skeleton state is mixed out to setup pose when an animation finishes, according to the animation's keyed items. This may be especially important when an animation has changed attachment visibility state: when mixed out, attachment visibility will change back to setup pose state, otherwise current attachment state is held until another animation has a key set at the respective attachment timeline. * *Custom MixMode*. When disabled, the recommended `MixMode` is used according to the layer blend mode. When enabled, a `Mix Modes` section is shown below allowing you to specify a `MixMode` for each Mecanim layer. * *Mix Modes*. Shown when `Custom MixMode` parameter above is enabled. This parameter determines the animation mix mode between successive animations, and also across layers. * Mix Next *(recommended for `Base Layer` and `Override` layers)* Applies the previous track and then mixes in the next track on top using Mecanim transition weights. * Always Mix *(recommended for `Additive` layers)* Fades out the previous track (potentially to setup pose when `Auto Reset` is enabled), and mixes in the next track on top using Mecanim transition weights. Note that this may cause an unintended animation dipping effect when used on the base layer. * Hard *(previously called `Spine Style`)* Applies the next track immediately. ##### **Result of `Auto Reset` and layer `Mix Mode` parameters** When a transition is active, there are four poses - `current state last frame`, the `setup pose`, `previous clip pose` and `new clip pose` - which will be combined as follows: 1. Starts with `current state last frame` *(or other modifications this frame prior to SkeletonMecanim's update)*. 2. Apply `setup pose`: * When `Auto Reset` is enabled, the `setup pose` replaces the `current state last frame`. * When `Auto Reset` is disabled, `setup pose` is not part of the mix. 3. Apply `previous clip pose`: * When mode is set to `Always Mix`, the `previous clip pose` is mixed with the current state (so mixed with `setup pose` when `Auto Reset` is enabled). * When set to `Hard` or `Mix Next`, the `previous clip pose` is applied with full weight, overriding the current state (thus overriding `setup pose`). 4. Apply `new clip pose`: * When mode is set to `Always Mix` or `Mix Next`, the `new clip pose` is mixed with the current state. So at `Always Mix` with `Auto Reset` enabled it is a mix of `setup pose`, `previous clip pose` and `new clip pose`. * When mode is set to `Hard`, the `new clip pose` is applied with full weight, overriding all previously applied poses. The table below shows the case when both previous clip `P` and new clip `N` modify the same timeline value, e.g. the same bone rotation. `S` represents the setup pose when `Auto Reset` is enabled, and the current state (e.g. of the previous frame) if disabled. Transition weight (0 at transition start, 1 at transition end) is represented by the variable `w`. The default (recommended) mix mode at each layer blend mode is highlighted in bold.
Always Mix Mix Next Hard
Base Layer lerp(lerp(S, P, 1-w), N, w) lerp(P, N, w) N
Override lerp(
lerp(lower_layers_result,
P, (1-w) * layer_weight),
N, w * layer_weight)
lerp(
lerp(lower_layers_result,
P, layer_weight),
N, w * layer_weight)
lerp(lower_layers_result,
N,
layer_weight)
Additive lower_layers_result +
layer_weight * lerp(P, N, w))
counts as Always Mix lower_layers_result +
layer_weight * N
Abbreviation Meaning
S Setup pose
P Previous clip pose
N New clip pose
w Transition weight
lerp(a, b, weight) Linear interpolation from a to b by weight.
#### SkeletonMecanim Controller and Animator The `SkeletonMecanim` component uses the Controller asset assigned at the `Animator` component as usual with Unity Mecanim. The Controller asset is automatically generated and assigned when instantiating a skeleton as `SkeletonMecanim` via [drag and drop](#Adding-a-Skeleton-to-a-Scene). ![](/img/spine-runtimes-guide/spine-unity/skeleton-mecanim-animator.png) > **Note:** When enabling `Apply Root Motion` a [SkeletonMecanimRootMotion](#SkeletonMecanimRootMotion) component is automatically added to your `SkeletonMecanim` GameObject. You can add animations to the Controller's animation state machine via drag and drop of Spine animations to the Animator panel as usual. The animations can be found below the Controller asset. ![](/img/spine-runtimes-guide/spine-unity/skeleton-mecanim-anim.png) [Mix duration values](#Mix-Settings) set at the [SkeletonDataAsset](#SkeletonDataAsset) will be ignored by `SkeletonMecanim`. Instead, Mecanim transition times are used as setup via the Animator panel. #### SkeletonMecanim Events When using `SkeletonMecanim`, events are stored in each `AnimationClip` and are raised like other Unity animation events. For example, if you named your event `"Footstep"` in Spine, you need to provide a `MonoBehaviour` script on your `SkeletonMecanim` GameObject with a method named `Footstep()` to handle it. When using folders in Spine, the method name will be a concatenation of the folder name and the animation name. For example when the previous event is placed in a folder named `Foldername` it will be `FoldernameFootstep()`. ```csharp public class YourComponentReceivingEvents : MonoBehaviour { // to capture event "Footstep" when it's placed outside of folders void Footstep() { Debug.Log("Footstep event received"); } // to capture event "Footstep" when it's placed in a folder named "Foldername" void FoldernameFootstep () { Debug.Log("Footstep (in folder Foldername) received"); } } ``` For more information on Unity Mecanim events, see [Unity's Documentation on Animation Events](https://docs.unity3d.com/Manual/script-AnimationWindowEvent.html). ### SkeletonGraphic Component The `SkeletonGraphic` component is one of three ways to use a Spine skeleton in Unity. These alternatives are: [SkeletonAnimation](#SkeletonAnimation-Component), [SkeletonMecanim](#SkeletonMecanim-Component) and [SkeletonGraphic (UI)](#SkeletonGraphic-Component). The `SkeletonGraphic` component is an alternative to the [SkeletonAnimation](#SkeletonAnimation-Component) component, using Unity's UI system for layout, rendering and mask interaction. As the [SkeletonAnimation](#SkeletonAnimation-Component) component, it allows you to add a Spine skeleton to a GameObject, animate it, react to animation events, and so on. #### Why a specific UI Component The Unity UI (UnityEngine.UI) uses a system of `Canvas` and `CanvasRenderers` to sort and manage its renderable objects. Built-in renderable UI components such as `Text`, `Image`, and `RawImage`, rely on `CanvasRenderer` to function correctly. Putting objects like `MeshRenderers` (e.g. a default Cube object), or `SpriteRenderers` (e.g. a Sprite) under a UI will not render in a `Canvas`. `SkeletonAnimation` uses a `MeshRenderer` and thus behaves in the same way. The spine-unity runtime therefore provides the `SkeletonAnimation` variant `SkeletonGraphic`, a subclass of `UnityEngine.UI.MaskableGraphic` using `CanvasRenderer` components for rendering. #### Important Material Requirements Only use Materials with special `CanvasRenderer` compatible shaders at `SkeletonGraphic` components, such as the `Spine/SkeletonGraphic*` shaders which are assigned by default. Do not use URP, LWRP or normal shaders like `Spine/Skeleton` with a `SkeletonGraphic` component. Seeing no visual error does not mean that the shader works with `SkeletonGraphic`. We have seen cases where it renders incorrectly on target mobile devices while rendering without any issues in the Unity Editor. As other UI components, `SkeletonGraphic` uses a `CanvasRenderer` instead of a `MeshRenderer`, which uses a separate rendering pipeline. Normal Materials assigned at a `SpineAtlasAsset` are ignored when instantiating a `SkeletonDataAsset` as `SkeletonGraphic`, only the Textures are used. You can use a [SkeletonGraphicCustomMaterials](#SkeletonGraphicCustomMaterials) component to override Materials at a `SkeletonGraphic` component. > **Important Note:** due to limitations of the used Unity `CanvasRenderer`, [SkeletonGraphic](#SkeletonGraphic-Component) is limited to a single texture by default. You can enable `Advanced - Multiple CanvasRenderers` at the `SkeletonGraphic` component Inspector to generate a child `CanvasRenderer` `GameObject` for every submesh to raise the texture limit. For performance reasons, this is better avoided where possible. This means Skeletons used in UI shall be packed as a single-texture (single-page) atlas, rather than multi-page atlases. > See section [Advanced - Single Atlas Texture Export and SkeletonGraphic](#Advanced---Single-Texture-Atlas-Export-and-SkeletonGraphic) on how to pack attachments to a single atlas page texture. #### Choosing the Right Parameters and Materials Using special shaders like `"Spine/SkeletonGraphic Tint Black"` or using `SkeletonGraphic` below a [CanvasGroup](#CanvasGroup-alpha) requires vertex data to be generated accordingly. You can find the relevant parameters in the `Advanced - Vertex Data` Inspector section. The settings are `Tint Black`, `CanvasGroup Compatible` and `PMA Vertex Color`. We have provided `Detect` buttons next to each property which automatically derives the correct settings. There is also a `Detect Settings` button which detects settings for all three properties. After modifying `Advanced - Vertex Data` settings, the used materials need to be updated to fit the active settings. At `SkeletonGraphic`, materials are independent of textures, and can thus be shared across different skeletons which use the same material properties. For this reason, special shared SkeletonGraphic materials are provided for the main parameter and shader combinations. The suitable material can be assigned automatically according to the chosen `Advanced - Vertex Data` settings via the available `Detect` button next to the `Material` property. When the skeleton uses multiple blend modes and has `Advanced - Multiple CanvasRenderers` enabled, you can use the `Detect` button next to `Blend Mode Materials` to automatically assign the suitable blend mode materials in a similar way. If you receive incorrect results, likely your atlas texture's import settings are incorrect (see the documentation [here](#Advanced---Premultiplied-vs-Straight-Alpha-Import)). #### CanvasGroup alpha When using `Spine/SkeletonGraphic*` shaders with a [`CanvasGroup`](https://docs.unity3d.com/ScriptReference/CanvasGroup.html), you will notice the skeleton becoming brighter when reducing the `CanvasGroup` `Alpha` value, as can be seen in the image below. ![](/img/spine-runtimes-guide/spine-unity/CommonError-CanvasGroupBright.png) This is due to Unity modifying the vertex color alpha value behind the scenes, which unfortunately does not play well with the premultiplied-alpha vertex color shaders of the spine-unity runtime. > **Important Note:** The spine-unity 4.2 and newer runtimes provide `Detect` buttons to automatically assign correct settings at parameters of the `Advanced - Vertex Data` section and a `Detect Material` button to automatically assign the suitable material based on the active settings. You can skip the sections below unless you need detailed information. ##### **SkeletonGraphic without Tint Black** The following applies When using a material with the `Spine/SkeletonGraphic` shaders except for `Spine/SkeletonGraphic TintBlack*`. If you use such a material below a `CanvasGroup` with alpha fadeout, the material must have the parameter `CanvasGroup Compatible` enabled and the SkeletonGraphic component `PMA Vertex Colors` disabled: 1. a) With version 4.2 and newer of the spine-unity runtime, you can find a `CanvasGroup Compatible` variant of each material in the folders `Materials/SkeletonGraphic-PMATexture/CanvasGroupCompatible` and `Materials/SkeletonGraphic-StaightAlphaTexture/CanvasGroupCompatible` respectively. b) On older versions, best create a copy of the shared `SkeletonGraphicDefault` material and rename it to e.g. `SkeletonGraphic CanvasGroup` instead of modifying the original material. Note that this shared SkeletonGraphic material needs to be created only once, it can be used with different skeletons as it is independent of the used texture. 2. Assign this `CanvasGroup Compatible` material at any `SkeletonGraphic` components below a `CanvasGroup` instead of the original material. 3. Any `SkeletonGraphic` component using this `CanvasGroup` compatible material needs to also have `Advanced - PMA Vertex Colors` disabled to avoid a double-darkening effect of semi-transparent parts. This unfortunately prevents rendering of additive slots in a single batch together with normal slots and may thus increase the number of draw calls. ##### **SkeletonGraphic TintBlack** When using a material with the `Spine/SkeletonGraphic TintBlack*` shader below a `CanvasGroup` with alpha fadeout, the following setup is required: 1. a) As above, with spine-unity version 4.2 and newer, use the provided `SkeletonGraphic TintBlack` materials within the `CanvasGroupCompatible` folder, or b) on older versions create a copy of the shared `SkeletonGraphicTintBlack` material and rename it to e.g. `SkeletonGraphicTintBlack CanvasGroup` instead of modifying the original material. Note that this shared SkeletonGraphic material needs to be created only once, it can be used with different skeletons as it is independent of the used texture. 2. Assign this material at the `SkeletonGraphic` component instead of the original material. 3. Enable `Advanced - CanvasGroup Compatible` at the `SkeletonGraphic` component (`Advanced - Canvas Group Tint Black` on version 4.1 or older). 4. a) When using spine-unity 4.2 or newer, both enabled and disabled `Advanced - PMA Vertex Colors` `SkeletonGraphic` settings are supported. It is recommended to keep `Advanced - PMA Vertex Colors` enabled to benefit from rendering additive slots in a single draw call. b) On older versions, disable `Advanced - PMA Vertex Colors` to avoid a double-darkening effect of semi-transparent additive slots. #### Match RectTransform bounds for correct visibility Visibility of a `SkeletonGraphic` is determined via its RectTransform bounds. When a Skeleton is instantiated via drag-and-drop as a child of a `Canvas` GameObject, the RectTransform bounds are automatically matched to the initial pose. You can also manually fit the RectTransform to its current pose's dimensions by clicking the `Match RectTransform with Mesh` button. It is important that the RectTransform bounds are not smaller than the mesh, otherwise e.g. a `RectMask2D` will omit drawing the skeleton as soon as the RectTransform is completely outside, even when part of the mesh is still inside and should be rendered. The current RectTransform bounds are shown in Scene view when the [RectTransform Tool](https://docs.unity3d.com/Manual/PositioningGameObjects.html) of the five Transform modes is active. #### Parameters `SkeletonGraphic` provides similar parameters as the [SkeletonAnimation component](#SkeletonAnimation-Component), please consult the [SkeletonAnimation section](#SkeletonAnimation-Component) for additional information. ![](/img/spine-runtimes-guide/spine-unity/skeleton-graphic-component.png) The `SkeletonGraphic` Inspector exposes the following additional parameters: * *Material - Detect* button. Assigns the suitable `"Spine/SkeletonGraphic*"` material, according to `Advanced - Vertex Data` settings. Same as *Detect Material* parameter in the `Advanced` section below. * *Freeze*. When set to `true`, the `SkeletonGraphic` will no longer be updated. * *Layout Scale Mode*. `SkeletonGraphic` supports automatic uniform scaling based on its `RectTransform` bounds. Defaults to `None` to keep previous behaviour. Automatic scaling can be enabled by setting this parameter to `Width Controls Height`, `Height Controls Width`, `Fit In Parent` or `Envelope Parent` (details can be found [here](https://docs.unity3d.com/Packages/com.unity.ugui@1.0/manual/script-AspectRatioFitter.html)). To modify the reference layout bounds, hit the `Edit Layout Bounds` toggle button to enter edit-mode, allowing you to adjust the bounds to your skeleton. The skeleton will be scaled accordingly to fit the reference layout bounds to the object's `RectTransform`. * *Edit Layout Bounds*. To modify the reference layout bounds used by `Layout Scale Mode` above, hit this toggle button to enter edit-mode. You can then adjust the bounds manually or hit `Match RectTransform with Mesh` to fit the current pose. When done adjusting, hit the `Edit Layout Bounds` toggle button again to exit edit-mode. * *Match RectTransform with Mesh* You can make a `SkeletonGraphic`'s RectTransform fit its current pose's dimensions by clicking the `Match` button. It is important that the RectTransform bounds are not smaller than the mesh, otherwise e.g. a `RectMask2D` will omit drawing the skeleton as soon as the `RectTransform` is outside, even when part of the mesh is still inside and should be rendered. This option is grayed-out unless `Layout Scale Mode` is set to `None` or the `Edit Layout Bounds` toggle button is set to edit-mode. ![](/img/spine-runtimes-guide/spine-unity/skeleton-graphic-advanced.png) * *Advanced* * *Use Clipping*. When set to `false`, any [Spine clipping attachments](/spine-clipping) will be ignored. * *Tint Black (!)*. Adds black tint vertex data to the mesh. Enable if the skeleton has any slots with tint black color set. Black tinting requires that the shader interprets UV2 and UV3 as black tint colors, such as the provided `Spine/SkeletonGraphic Tint Black*` shaders. To allow UV2 and UV3 data at the parent Canvas, you need to select the Canvas and under `Additional Shader Channels` enable `TexCoord1` and `TexCoord2`. > A `Detect` button is provided which enables this parameter if the SkeletonData contains any slot with tint black color set, and disables it otherwise. * *CanvasGroup Compatible.* Enable when SkeletonGraphic is used below a `CanvasGroup` GameObject. The material also needs `CanvasGroup Compatible` enabled, so assign the suitable material after changing this setting via `Detect Material` or manually. When using a `SkeletonGraphic Tint Black*` shader and both `Tint Black` and `PMA Vertex Color` are enabled, the alpha value will be stored at `uv2.g` instead of at the primary vertex color `color.a`, and `color.a` stores constant `1.0` to capture `CanvasGroup` modifying `color.a`. > A `Detect` button is provided which enables this parameter if the SkeletonGraphic component is located below a `CanvasGroup` component in the hierarchy, and disables it otherwise. * *[4.1 and older] Canvas Group Tint Black.* Only enable when using a `SkeletonGraphic Tint Black*` shader. Has no effect when `Tint Black` is disabled or `PMA Vertex Color` is disabled. Enable when using `Additive` blend mode at a slot of `SkeletonGraphic` under a `CanvasGroup`. When enabled, the alpha value is stored at `uv2.g` instead of primary vertex color `color.a`, and `color.a` stores constant `1.0` to capture `CanvasGroup` modifying `color.a`. * *PMA Vertex Colors* *(additional rules for [CanvasGroup alpha](#CanvasGroup-alpha) apply)*. Multiply vertex color RGB with vertex color alpha. This parameter is enabled by default, which is the correct setting unless you are using thirdparty shaders or require `CanvasGroup Compatible` enabled on a shader which is not `"SkeletonGraphic TintBlack*"`. > A `Detect` button is provided, which requires `Tint Black` and `CanvasGroup Compatible` above to be setup correctly. `Detect` disables this parameter if a thirdparty (non-Spine) shader is used, or if `CanvasGroup Compatible` is enabled and `Tint Black` disabled. It enables the parameter otherwise. The following detailed rules for *PMA Vertex Color* apply *(only needed when `Detect` fails)*: > *When using spine-unity 4.2 or newer:* > Enable this parameter *(the default)*: > * if `CanvasGroup Compatible` is disabled at the used `"Spine/SkeletonGraphic*"` shader (even with `Straight Alpha Texture` enabled), or > * if using a `"Spine/SkeletonGraphic TintBlack*"` shader (even with `Straight Alpha Texture` enabled), or > * if using a thirdparty (non-Spine) shader which requires vertex color as PMA (likely if the shader uses PMA additive output blend mode `Blend One OneMinusSrcAlpha`). > > Disable this parameter: > * if not using a `"Spine/SkeletonGraphic TintBlack*"` shader but a normal `"Spine/SkeletonGraphic*"` shader which has `CanvasGroup Compatible` enabled, or > * if using a thirdparty (non-Spine) shader which requires regular vertex color (likely if the shader uses regular output blend mode `Blend SrcAlpha OneMinusSrcAlpha`). > *When using spine-unity 4.1 or older:* > Enable this parameter *(the default)*: > * if `CanvasGroup Compatible` is disabled at the used `"Spine/SkeletonGraphic*"` shader (even with `Straight Alpha Texture` enabled), or > * if using a thirdparty (non-Spine) shader which requires vertex color as PMA (likely if the shader uses PMA additive output blend mode `Blend One OneMinusSrcAlpha`). > > Disable this parameter: > * if you're using a `"Spine/SkeletonGraphic*"` shader which has `CanvasGroup Compatible` enabled, or > * if using a thirdparty (non-Spine) shader which requires regular vertex color (likely if the shader uses regular output blend mode `Blend SrcAlpha OneMinusSrcAlpha`). When enabled, additive slots can be rendered in a single draw call together with normal slots. When disabled, additive slots require [`SkeletonData`](#Skeleton-Data) *Blend Mode Materials - Apply Additive Material* enabled, leading to a separate draw call, which may adversely affect performance. * *Detect Settings.* Applies detection of `Tint Black`, `CanvasGroup Compatible` and `PMA Vertex Colors` parameters at once. * *Detect Material.* Assigns the suitable `SkeletonGraphic` material based on the above `Tint Black` and `CanvasGroup Compatible` parameters and the atlas texture's import settings (PMA vs straight alpha settings). If you receive incorrect results, likely your texture settings are incorrect (see the documentation [here](#Advanced---Premultiplied-vs-Straight-Alpha-Import)). * *Multiple CanvasRenderers.* When set to `true`, `SkeletonGraphic` no longer uses a single `CanvasRenderer` but automatically creates the required number of child `CanvasRenderer` GameObjects for each required draw call (submesh). This can be used to raise the [single texture limitation](#Advanced---Single-Texture-Atlas-Export-and-SkeletonGraphic), but comes at an additional performance overhead. * *Blend Mode Materials.* Allows using different `SkeletonGraphic` materials for each Slot blend mode. Use only `"Spine/SkeletonGraphic *"` or other `CanvasRenderer` compatible materials here. * Select `Assign Default` to assign the default blend mode materials `SkeletonGraphicAdditive`, `SkeletonGraphicMultiply` and `SkeletonGraphicScreen`. > **Note:** Be sure to have a proper setup of `Blend Mode Materials` at the [`SkeletonDataAsset`](#Skeleton-Data), as the `SkeletonGraphic` blend mode material assignment relies on the [`SkeletonDataAsset's`](#Skeleton-Data) materials. `Additive Material` is ignored when `PMA Vertex Colors` is enabled. * *Animation Update*. Whether to update the animation in normal `Update` *(the default)*, physics step `FixedUpdate`, or manually via a user call. When using a [SkeletonRootMotion](#SkeletonRootMotion) component with a `Rigidbody` or `Rigidbody2D` assigned, it is recommended to set the update mode to `In FixedUpdate`. Otherwise `In Update` is recommended. * *Update When Invisible*. Update mode used when the MeshRenderer becomes invisible. Update mode is automatically reset to `UpdateMode.FullUpdate` when the mesh becomes visible again. * *Separator Slot Names.* Slots that determine where the render is split when *Enable Separation* is set to `true`. For general information on render separation, see section [SkeletonRenderSeparator](#SkeletonRenderSeparator), but note that no additional components are required with `SkeletonGraphic`. * *Enable Separation.* Render separation can be enabled directly in this Inspector section, it does not require any additional components (like `SkeletonRenderSeparator` or `SkeletonPartsRenderer` for `SkeletonRenderer` components). When enabled, additional separation part GameObjects will be created automatically, and `CanvasRenderer` GameObjects re-parented to them accordingly. The separation part GameObjects can be moved around and re-parented in the hierarchy according to your requirements to achieve the desired draw order within your `Canvas`. * *Update Part Location.* When enabled, separator part GameObject location will be updated to match the position of the `SkeletonGraphic`. This can be helpful when re-parenting parts to a different GameObject. * *Physics Inheritance.* Controls how Transform movement is applied to PhysicsConstraints of the skeleton. * *Position*. When set to non-zero, Transform position movement in X and Y direction is applied to skeleton PhysicsConstraints, multiplied by these X and Y scale factors. Typical (X,Y) values are: (1,1) to apply XY movement normally, (2,2) to apply movement with double intensity, (1,0) to apply only horizontal movement, or (0,0) to not apply any Transform position movement at all. * *Rotation*. When set to non-zero, Transform rotation movement is applied to skeleton PhysicsConstraints, multiplied by this scale factor. Typical values are: 1 to apply movement normally, 2 to apply movement with double intensity, or 0 to not apply any Transform rotation movement at all. * *Movement relative to*. To apply Transform movement relative to e.g. a parent Transform, set this to the reference Transform relative to which movement shall be calculated. Set this to *None* to use the absolute world location *(the default)*. #### Example Scene You can examine the example scene [Spine Examples/Getting Started/6 Skeleton Graphic](#6-SkeletonGraphic) for basic usage. An advanced example scene showing how to set up separator slots and modify draw order can be found at `Spine Examples/Other Examples/SkeletonRenderSeparator`. ### SkeletonRenderer Component The `SkeletonRenderer` component is responsible for drawing the current state of a skeleton. It is the base class for [SkeletonAnimation](#SkeletonAnimation-Component) and [SkeletonMecanim](#SkeletonMecanim-Component). > **Note:** most of the time you will want to use [SkeletonAnimation](#SkeletonAnimation-Component), [SkeletonMecanim](#SkeletonMecanim-Component) or [SkeletonGraphic (UI)](#SkeletonGraphic-Component) instead. These components provide sophisticated means to control animation. Only when applying animations manually without transitions, as could be useful at a UI gauge element, this component may be useful as-is. Rendering is performed via a procedural mesh which is updated at a `MeshRenderer` component. The component uses the texture atlas asset referenced by the [SkeletonDataAsset](#Skeleton-Data-Asset) to find the textures and materials needed to draw the attachments of the skeleton. Please consult the documentation section of [SkeletonAnimation](#SkeletonAnimation-Component) for additional information. You can examine the example scene `Spine Examples/Other Examples/SpineGauge` on how to use a `SkeletonRenderer` component directly. ## Utility Components ### SkeletonRootMotion spine-unity supports root motion on all three Spine skeleton components. The `SkeletonRootMotion` component can be attached to [SkeletonAnimation](#SkeletonAnimation-Component) and [SkeletonGraphic (UI)](#SkeletonGraphic-Component) GameObjects, while a separate [SkeletonMecanimRootMotion](#SkeletonMecanimRootMotion) component is provided for [SkeletonMecanim](#SkeletonMecanim-Component). Attaching this root motion component is similar to enabling the `Apply Root Motion` parameter at the Unity Mecanim [`Animator`](https://docs.unity3d.com/Manual/class-Animator.html) component. When enabled, the character's position is driven by the animation according to the movement of the selected `Root Motion Bone`. > **Note:** There is a [SkeletonMecanimRootMotion](#SkeletonMecanimRootMotion) component provided for [SkeletonMecanim](#SkeletonMecanim-Component) objects. `SkeletonRootMotion` will fail when used on `SkeletonAnimation` or `SkeletonGraphic (UI)` components. ![](/img/spine-runtimes-guide/spine-unity/skeleton-rootmotion-component.png) **Parameters** - *Root Motion Bone.* The target bone whose movement is used as root motion. - *X.* When enabled, movement along the local X axis is applied as root motion. - *Y.* When enabled, movement along the local Y axis is applied as root motion. - *Root Motion Scale (X).* Scale applied to the horizontal root motion delta. Can be used for delta compensation to e.g. stretch a jump to the desired distance. - *Root Motion Scale (Y)* Scale applied to the vertical root motion delta. Can be used for delta compensation to e.g. stretch a jump to the desired height. - *Animation Tracks.* Allows you to specify which [animation tracks](/spine-applying-animations#Tracks) shall be included in root motion calculations. **Optional Parameters** - *Rigidbody2D.* When a `Rigidbody2D` is assigned, movement is applied via physics to the given `Rigidbody2D` instead of the `Transform` component. It is then recommended to set the skeleton animation component's [`Advanced` - `Animation Update`](#Setting-Advanced-Parameters) Inspector parameter to `In FixedUpdate`. - *Rigidbody.* When a `Rigidbody` is assigned, movement is applied via physics to the given `Rigidbody` instead of the `Transform` component. It is then recommended to set the skeleton animation component's [`Advanced` - `Animation Update`](#Setting-Advanced-Parameters) Inspector parameter to `In FixedUpdate`. > **Note:** The `SkeletonRootMotion` class provides `AdjustRootMotionToDistance()` and other methods to allow for easy delta compensation. Delta compensation can be used to e.g. stretch a jump to a given distance. Root motion can be adjusted at the start of an animation or every frame via `skeletonRootMotion.AdjustRootMotionToDistance(targetPosition - transform.position, trackIndex);`. ### SkeletonMecanimRootMotion This component is a variant of the [SkeletonRootMotion](#SkeletonRootMotion) component to be used with [SkeletonMecanim](#SkeletonMecanim-Component) components. The `SkeletonMecanimRootMotion` component is automatically added to your skeleton GameObject when the `Apply Root Motion` parameter at the Unity Mecanim [`Animator`](https://docs.unity3d.com/Manual/class-Animator.html) is enabled. To remove the `SkeletonMecanimRootMotion` component you have to ensure to disable the Animator's `Apply Root Motion` parameter first. ![](/img/spine-runtimes-guide/spine-unity/skeleton-mecanim-rootmotion-component.png) **Parameters** - *Root Motion Bone.* The target bone whose movement is used as root motion. - *X.* When enabled, movement along the local X axis is applied as root motion. - *Y.* When enabled, movement along the local Y axis is applied as root motion. - *Root Motion Scale (X).* Scale applied to the horizontal root motion delta. Can be used for delta compensation to e.g. stretch a jump to the desired distance. - *Root Motion Scale (Y)* Scale applied to the vertical root motion delta. Can be used for delta compensation to e.g. stretch a jump to the desired height. - *Mecanim Layers.* Allows you to specify which [Mecanim layers](https://docs.unity3d.com/Manual/AnimationLayers.html) shall be included in root motion calculations. **Optional Parameters** - *Rigidbody2D.* When a `Rigidbody2D` is assigned, movement is applied via physics to the given `Rigidbody2D` instead of the `Transform` component. - *Rigidbody.* When a `Rigidbody` is assigned, movement is applied via physics to the given `Rigidbody` instead of the `Transform` component. > **Note:** The `SkeletonMecanimRootMotion` class provides `AdjustRootMotionToDistance()` and other methods to allow for easy delta compensation. Delta compensation can be used to e.g. stretch a jump to a given distance. Root motion can be adjusted at the start of an animation or every frame via `skeletonRootMotion.AdjustRootMotionToDistance(targetPosition - transform.position, trackIndex);`. ### BoneFollower This component references a bone of a [SkeletonAnimation](#SkeletonAnimation-Component) component and sets its own transform to that of the bone on every `Update`. ![](/img/spine-runtimes-guide/spine-unity/bone-follower-component.png) > **Note:** There is a [BoneFollowerGraphic](#BoneFollowerGraphic) component provided for [SkeletonGraphic](#SkeletonGraphic-Component) objects. In contrast to the [SkeletonUtilityBone](#SkeletonUtilityBone) component a `BoneFollower` can be used as a single isolated GameObject without any parent bone objects. Use this to let objects like particle systems follow a specific bone on the skeleton. You can examine the example scene [Spine Examples/Getting Started/4 Object Oriented Sample](#4-Object-Oriented-Sample) on how to set up a `BoneFollower` component. ### BoneFollowerGraphic This component is a variant of the [Bone Follower](#BoneFollower) component to be used with [SkeletonGraphic](#SkeletonGraphic-Component) components. ![](/img/spine-runtimes-guide/spine-unity/bone-follower-graphic-component.png) In contrast to the [SkeletonUtilityBone](#SkeletonUtilityBone) component a `BoneFollowerGraphic` can be used as a single isolated GameObject without any parent bone objects. Use this to let objects like particle systems follow a specific bone on the skeleton. You can examine the example scene [Spine Examples/Getting Started/6 Skeleton Graphic](#6-SkeletonGraphic) on how to set up a `BoneFollowerGraphic` component. ### PointFollower This component is similar to the [Bone Follower](#BoneFollower) component but follows a [PointAttachment](/spine-points) instead of a bone. ![](/img/spine-runtimes-guide/spine-unity/point-follower-component.png) In contrast to the [SkeletonUtilityBone](#SkeletonUtilityBone) component a `PointFollower` can be used as a single isolated GameObject without any parent bone objects. ### BoundingBoxFollower This component is used to match a [Bounding Box](/spine-bounding-boxes) at a skeleton's slot. It extracts the shape and assigns it at a `PolygonCollider2D` and enables or disables it every frame to match the current animation. ![](/img/spine-runtimes-guide/spine-unity/boundingbox-follower-component.png) > Note: The bone's position is not automatically followed, which is why it is typically used together with a `BoneFollower` component. You can use the `Add Bone Follower` button in the `BoundingBoxFollower` inspector to create and setup a `BoneFollower` component. > Note: Vertex deformation animation (moving vertices of a Bounding Box over time in an animation) is not followed along, it only covers the initial shape. See [Bone Follower](#BoneFollower) for further information. ### SkeletonUtilityBone Sometimes you may want to modify bone positions programmatically at runtime to react to physics or user input. ![](/img/spine-runtimes-guide/spine-unity/skeleton-utilitybone-modes.png) The [SkeletonUtilityBone](#SkeletonUtilityBone) component provides a convenient interface to let GameObjects follow a bone position, override a bone position manually or via 2D and 3D physics. It can be configured to either *follow* the local bone position or *override* it on every `Update`. When set to `Override`, the component will set the bone position before the [SkeletonAnimation](#SkeletonAnimation-Component) component updates the world transforms. > **Important Note:** A `SkeletonUtilityBone` uses local transform values. It relies on a hierarchy of `SkeletonUtilityBone` GameObjects that mirrors the skeleton's bone hierarchy. The recommended way to quickly create a `SkeletonUtilityBone` hierarchy is via the [`SkeletonUtility`](#SkeletonUtility) component described [below](#SkeletonUtility). The `SkeletonUtilityBone` Inspector also provides an interface to create additional child bones (selectively or recursively) or create a [2D and 3D hinge chain](#Create-2D-and-3D-Hinge-Chains-for-Physics). ![](/img/spine-runtimes-guide/spine-unity/skeleton-utilitybone-component-add.png) Once your hierarchy of `SkeletonUtilityBones` is created, the Hierarchy panel shows different icons next to a `SkeletonUtilityBone` GameObject depending on whether it is set to * `Follow`: ![Follow](/img/spine-runtimes-guide/spine-unity/icon-bone.png) * or `Override`: ![Override](/img/spine-runtimes-guide/spine-unity/icon-poseBones.png) ![](/img/spine-runtimes-guide/spine-unity/skeleton-utility-hierarchy.png) #### Example Use Case Use a `SkeletonUtilityBone` in `Override` mode for use cases such as letting the user drag a bone of the skeleton around. In case you need a GameObject to follow only a single bone position, you can use the [BoneFollower](#BoneFollower) component instead to save resources. #### Example Scene You can find an example scene that demonstrates usage of `SkeletonUtilityBone` at `Spine Examples/Other Examples/SkeletonUtility Animated Physics`. It shows how some `SkeletonUtilityBones` nodes are configured to `Follow` bone positions to be the necessary hierarchial parents for the `Override` nodes. #### Create 2D and 3D Hinge Chains for Physics ![Hinge Chain Demo](/img/spine-runtimes-guide/spine-unity/hingechains/hinge-chains-wide.gif) You may want to add physics to the cape of your character, have it drag heavy objects around or swing a morning-star. The spine-unity runtime allows you to generate a physics rig of [HingeJoint](https://docs.unity3d.com/Manual/class-HingeJoint.html) or [HingeJoint2D](https://docs.unity3d.com/Manual/class-HingeJoint2D.html) elements from an existing [SkeletonUtilityBone](/spine-unity#SkeletonUtilityBone) hierarchy (see [Creating a Hierarchy of SkeletonUtilityBones](#Creating-a-Hierarchy-of-SkeletonUtilityBones)). ![Hinge Chain Setup](/img/spine-runtimes-guide/spine-unity/hingechains/setup-hinge-chain.gif) Select the first `SkeletonUtilityBone` chain element and in the Inspector choose `Create 3D Hinge Chain` or `Create 2D Hinge Chain` to generate the physics rig. The selected element and all its `SkeletonUtilityBone` children are turned into a hinge chain. You can then adjust the Rigidbody's drag and mass parameters to tweak the result. Raising the drag value will make the Rigidbody move slower and create the effect of being heavy or interact with air. > Note that the chain root node is no longer parented to bones of the skeleton, but placed at the top hierarchy level of the scene. This is a requirement in Unity to have momentum applied properly. Do not reparent the chain root to bones of your skeleton, or chain elements will no longer be affected by skeleton movement! ##### **3D hinge chains** 1. Create a [SkeletonUtilityBone hierarchy](/spine-unity#Creating-a-Hierarchy-of-SkeletonUtilityBones) as usual. 2. Select the first chain element in the Scene panel and in the Inspector choose `Create 3D Hinge Chain` to create the 3D hinge chain rig. ![Create Hinge Chain 3D](/img/spine-runtimes-guide/spine-unity/hingechains/create-hinge-chain-3d.png) 3. This will remove the chain GameObjects from the previous parent (`cape-root` in the example) and place a new `HingeChain Parent` GameObject at the top level of the scene. As mentioned above, do not reparent this GameObject to the skeleton! ![Hinge Chain 3D Hierarchy](/img/spine-runtimes-guide/spine-unity/hingechains/hinge-chain-3d.png) 4. Adjust chain elements Rigidbody drag and mass parameters to tweak the result. When the skeleton is flipped, the `HingeChain Parent` GameObject will automatically be rotated by 180 degrees to adjust the hinge chain to the flipped bone locations. ##### **2D hinge chains** 1. Create a [SkeletonUtilityBone hierarchy](/spine-unity#Creating-a-Hierarchy-of-SkeletonUtilityBones) as usual. 2. Select the first chain element in the Scene panel and in the Inspector choose `Create 2D Hinge Chain` to create the 2D hinge chain rig. ![Create Hinge Chain 2D](/img/spine-runtimes-guide/spine-unity/hingechains/create-hinge-chain-2d.png) 3. This will remove the chain GameObjects from the previous parent (`cape-root` in the example) and place a new `HingeChain Parent` GameObject at the top level of the scene. As mentioned above, do not reparent this GameObject to the skeleton! ![Hinge Chain 2D Hierarchy](/img/spine-runtimes-guide/spine-unity/hingechains/hinge-chain-2d.png) 4. Adjust chain elements Rigidbody2D drag and mass parameters to tweak the result. Note that this GameObject contains two child objects, named `Hinge Chain` and `Hinge Chain FlippedX`. When the skeleton is flipped, these GameObjects will automatically be activated and deactivated to enable the respective hinge chain. ### SkeletonUtility #### Creating a Hierarchy of SkeletonUtilityBones The `SkeletonUtility` component offers a quick way to create a hierarchy of `SkeletonUtilityBone` GameObjects mirroring the bone hierarchy of the skeleton. ![](/img/spine-runtimes-guide/spine-unity/add-skeleton-utility.png) To create a `SkeletonUtility` component, select your [SkeletonAnimation](#SkeletonAnimation-Component) component and in the Inspector unfold the `Advanced` section and hit `Add Skeleton Utility`. Once created, the `Add Skeleton Utility` button will disappear and `SkeletonUtility` component is added to your GameObject. ![](/img/spine-runtimes-guide/spine-unity/skeleton-utility-component.png) The `SkeletonUtility` component provides a `Spawn Hierarchy` button with the following options presented on click: 1. `Follow all bones` Creates `SkeletonUtilityBone` GameObjects for all bones in the hierarchy, set to mode `Follow` 2. `Follow (Root Only)` Creates only the root `SkeletonUtilityBone` GameObject, set to mode `Follow` 3. `Override all bones` Creates `SkeletonUtilityBone` GameObjects for all bones in the hierarchy, set to mode `Override` 4. `Override (Root Only)` Creates only the root `SkeletonUtilityBone` GameObject, set to mode `Override` Each`SkeletonUtilityBone` can then be configured to override bone positions of a skeleton where necessary. ![](/img/spine-runtimes-guide/spine-unity/skeleton-utility-hierarchy.png) > **Note:** You can add additional `SkeletonUtilityBone` GameObjects via the inspector of a `SkeletonUtilityBone` later, the `Spawn Hierarchy` functionality serves as a rough starting point. You can also delete unneeded `SkeletonUtilityBone` GameObjects to save resources. Just remember you need to keep their parents intact, so do not delete GameObjects in the middle of a hierarchy-chain or change their parents. ### SkeletonUtilityConstraint ![](/img/spine-runtimes-guide/spine-unity/utility-constraint-baseclass.png) #### C# # Base class to derive skeleton utility constraint subclasses from. It automatically registers itself at the parent `SkeletonUtility` and will be updated accordingly. See example constraint classes `SkeletonUtilityGroundConstraint` and `SkeletonUtilityEyeConstraint` for how to write your own constraint classes. #### Example Scene The spine-unity runtime comes with example scenes that demonstrate the above constraints. You can find them in `Spine Examples/Other Examples/SkeletonUtility GroundConstraint` and `Spine Examples/Other Examples/SkeletonUtility Eyes`. ### SkeletonRendererCustomMaterials ![](/img/spine-runtimes-guide/spine-unity/skeleton-renderer-custom-materials-boy.png) You may want to override materials for a specific Skeleton instance or even only at certain slots. This component provides an inspector interface to assign custom material overrides for [SkeletonRenderer](#SkeletonRenderer-Component), including subclasses [SkeletonAnimation](#SkeletonAnimation-Component) and [SkeletonMecanim](#SkeletonMecanim-Component). ![](/img/spine-runtimes-guide/spine-unity/skeleton-renderer-custom-materials.png) You can right-click on a [SkeletonRenderer](#SkeletonRenderer-Component) (or subclasses [SkeletonAnimation](#SkeletonAnimation-Component) and [SkeletonMecanim](#SkeletonMecanim-Component)) and select `Add Basic Serialized Custom Materials` to add this component to the renderer. Add entries to the `Custom Slot Materials` array to override materials at certain slots or to the `Custom Material Overrides` array to replace one material with another for the whole skeleton. Be sure to uncheck `Override Disabled` to enable the respective material overrides. > **Note:** This component is not intended to be interfaced through code. To dynamically set materials for your SkeletonRenderer through code, you can directly access `SkeletonRenderer.CustomMaterialOverride` for material array overrides and `SkeletonRenderer.CustomSlotMaterials` for slot material overrides. ### SkeletonGraphicCustomMaterials A variant of [SkeletonRendererCustomMaterials](#SkeletonRendererCustomMaterials) for [SkeletonGraphic](#SkeletonGraphic-Component). This component provides an inspector interface to assign custom material and texture overrides for [SkeletonGraphic](#SkeletonGraphic-Component). ![](/img/spine-runtimes-guide/spine-unity/skeleton-graphic-custom-materials.png) You can right-click on a [SkeletonGraphic](#SkeletonGraphic-Component) and select `Add Basic Serialized Custom Materials` to add this component to the GameObject. Add entries to the `Custom Texture Overrides` array to replace one texture with another for the whole skeleton. Add entries to the `Custom Material Overrides` array to replace the used material at an original texture (before replacement) with another material. Be sure to check `Override Enabled` to enable the respective texture or material overrides. > **Note:** This component is not intended to be interfaced through code. To dynamically set materials for your SkeletonGraphic through code, you can directly access `SkeletonGraphic.CustomMaterialOverride` for material array overrides and `SkeletonGraphic.CustomTextureOverride` for texture overrides. ### SkeletonRenderSeparator ![](/img/spine-runtimes-guide/spine-unity/skeleton-render-separator-spineboy.png) You may want to display other GameObjects between parts of your character, e.g. to let your character run into a tree and display one leg in front and one behind the trunk. The `SkeletonRenderSeparator` component allows you to split your [SkeletonRenderer](#SkeletonRenderer-Component) (or subclass [SkeletonAnimation](#SkeletonAnimation-Component) and [SkeletonMecanim](#SkeletonMecanim-Component)) into two or more `SkeletonPartsRenderers` with customizable layer order. > **Note:** The [SkeletonGraphic](#SkeletonGraphic-Component) component provides render separation functionality directly at the `SkeletonGraphic` Inspector in the `Advanced` section, it does not require any additional components. ![](/img/spine-runtimes-guide/spine-unity/skeleton-render-separator-component.png) > **Note:** Normally, Spine renderer components will use a single renderer to display the whole mesh of a skeleton. This unfortunately prevents you from inserting other `UnityEngine.Renderers` (`SpriteRenderer`, `MeshRenderer`, `ParticleSystem`, etc.) between its parts. #### Setup 1. **Make sure you know your Skeleton's draw order.** Find out which slot you want to use to separate your Skeleton's render into parts. For convenience, label this slot clearly before exporting your Skeleton. 2. **Add the SkeletonRenderSeparator component** Select your Spine GameObject. Right-click on your [SkeletonAnimation](#SkeletonAnimation-Component) or [SkeletonRenderer](#SkeletonRenderer-Component) in the inspector. Choose `Add Skeleton Render Separator`. This will add the `SkeletonRenderSeparator` component to the GameObject. !["Steps 2 to 4"](/img/spine-runtimes-guide/spine-unity/skeleton-render-separator-steps.gif) 3. **Assign Separator Slots** The inspector now shows a warning that the list of separators is empty. Setup separator slots by choosing the desired slot(s) under `Separator Slot Names`. You can add additional separator slots using the `+` button. > **Note:** This field is serialized at the [SkeletonRenderer](#SkeletonRenderer-Component) (or [SkeletonAnimation](#SkeletonAnimation-Component) and [SkeletonMecanim](#SkeletonMecanim-Component) subclass) component, `SkeletonRenderSeparator` just provides the interface for it. 4. **Add Parts Renderers** The inspector now shows a warning that you don't have enough parts renderers. Click on the `Add the missing renderers (n)` button to create the required GameObjects with `SkeletonPartsRenderer` components. These GameObjects will be automatically assigned at the `Parts Renderers` list above. > Note: The `SkeletonRenderSeparator` detects the currently required number of parts renderers,depending on the current draw order. If draw order is modified at runtime, it may happen that the renderer requires more parts renderers. In this case you may need to add one or two additional parts renderers manually by clicking the `Add Parts Renderer` button. 5. **Setup `Sorting Layer` and `Order in Layer`** Each of the `SkeletonPartsRenderers` provides a [`Sorting Layer`](https://docs.unity3d.com/Manual/2DSorting.html#sortlayer) and [`Order in Layer`](https://docs.unity3d.com/ScriptReference/Renderer-sortingOrder.html) property in the inspector. You can now setup the sorting properties at each `SkeletonPartsRenderer`. Higher values will move the renderer to the front. ![](/img/spine-runtimes-guide/spine-unity/skeleton-parts-renderer-component.png) > **Note:** The `SkeletonPartsRenderer` GameObjects don't have to be children of your Spine GameObject. The `SkeletonRenderSeparator` keeps references, so you can organize them however you need to. #### Example Scene You can find an example scene that demonstrates usage of `SkeletonPartsRenderer` and `SkeletonRenderSeparator` at `Spine Examples/Other Examples/SkeletonRenderSeparator`. #### C# # ##### Enabling and Disabling By default, `SkeletonRenderSeparator` will disable the [SkeletonRenderer](#SkeletonRenderer-Component) and take over his mesh rendering task. Likewise, if you disable `SkeletonRenderSeparator`, [SkeletonRenderer](#SkeletonRenderer-Component) will take over rendering again. You can enable and disable a `SkeletonRenderSeparator` as any component: ```csharp skeletonRenderSeparator.enabled = true; // separation is enabled. skeletonRenderSeparator.enabled = false; // separation is disabled. ``` ##### Changing the separation point The point of separation is not stored in `SkeletonRenderSeparator`. It is defined by the separator slots in [SkeletonRenderer](#SkeletonRenderer-Component) (or subclasses [SkeletonAnimation](#SkeletonAnimation-Component) and [SkeletonMecanim](#SkeletonMecanim-Component)). If you want to manipulate separator slots at runtime, you can access the list `SkeletonRenderer.separatorSlots` and manipulate it as usual by calling `Add`, `Remove` or `Clear`. ```csharp Spine.Slot mySlot = skeletonAnimation.Skeleton.FindSlot("MY SPECIAL SLOT"); skeletonAnimation.separatorSlots.Clear(); skeletonAnimation.separatorSlots.Add(mySlot); ``` ##### Adding a SkeletonRenderSeparator at runtime You can use the static method `SkeletonRenderSeparator.AddToSkeletonRenderer` to add and initialize a new `SkeletonRenderSeparator` component. ```csharp SkeletonAnimation skeletonAnimation = GetComponent(); skeletonAnimation.SeparatorSlots.Add(mySlot); // see above // Add the SkeletonRenderSeparator. SkeletonRenderSeparator skeletonRenderSeparator = SkeletonRenderSeparator.AddToSkeletonRenderer(skeletonAnimation); ``` By default, it will add the currently necessary `SkeletonPartsRenderers`. It provides a number of optional arguments for advanced use cases, please see the [code documentation](https://github.com/EsotericSoftware/spine-runtimes/blob/4.2/spine-unity/Assets/Spine/Runtime/spine-unity/Components/SkeletonRenderSeparator/SkeletonRenderSeparator.cs#L86-L94). ## Rendering ### Shaders ![](/img/spine-runtimes-guide/spine-unity/stretchyman-only-small.png) The spine-unity runtime includes several different shaders. By default, the `Spine/Skeleton` shader will be assigned at a newly imported skeleton Material. You can change the shader via the Material's Shader parameter as usual. Below you will find a list of included Spine shaders. > **Important Note:** Use only special `CanvasRenderer` compatible shaders with **`SkeletonGraphic`** components. See [SkeletonGraphic - Important Material Requirements](#Important-Material-Requirements) for details. > **Important Note:** The spine-unity runtime package provides only [**Built-In Render Pipeline**](https://docs.unity3d.com/Manual/built-in-render-pipeline.html) shaders, which are not compatible with [**Universal Render Pipeline**](https://unity.com/srp/universal-render-pipeline) projects. If you're using Universal Render Pipeline, please use the provided URP shaders of the [Spine URP Shaders extension UPM package](#URP-Shaders---Extension-UPM-Package) instead. > **Note:** [*Deferred Shading rendering path*](https://docs.unity3d.com/Manual/RenderTech-DeferredShading.html) is not yet supported by Spine shaders. 1. **Spine/Skeleton** *(Default Shader)* Unlit transparent shader. Does not write to the z-buffer. 1. **Spine/Skeleton Graphic** *(Default shader for SkeletonGraphic)* Unlit transparent shader used by [SkeletonGraphic](#SkeletonGraphic-Component). Does not write to the z-buffer. Does not support `Additive` blend mode when used with a `CanvasGroup`, when required use `Spine/Skeleton Graphic Tint Black` instead. Limited to a single texture because of CanvasRenderer limitations. 1. **Spine/Skeleton Lit** Simple lit transparent shader, no normal map support. Does not write to the z-buffer. 1. **Spine/Skeleton Lit ZWrite** Simple lit transparent shader, no normal map support. Writes to the z-buffer. 1. **Spine/Skeleton Fill** Unlit transparent shader with customizable color overlay. Does not write to the z-buffer. `FillColor` determines the overlay color, `FillPhase` the color overlay intensity. 1. **Spine/Skeleton Tint** Unlit transparent shader with customizable two-color tint, tinting dark colors separately from light colors, called [tint black](/spine-slots#Tint-black). Does not write to the z-buffer. The texture's lighter colors are tinted with `Tint Color`, the texture's darker colors with `Black Point` color. This allows a tinted texture to be brighter than its original color, compared to ordinary multiply color blending. When setting both `Tint Color` and `Black Point` to the same color it will result in a solid color overlay. When setting `Tint Color` to black and `Black Point` to white, the texture color will be inverted. 1. **Spine/Skeleton Tint Black** ![](/img/spine-runtimes-guide/spine-unity/tint-black-demo.gif) Unlit transparent shader with Spine-animated per-slot [tint black](/spine-slots#Tint-black) feature. Does not write to the z-buffer. Spine provides a [Tint Black](/spine-slots#Tint-black) feature for slots, allowing animated black tint. Required additional setup step (for tint color vertex data): - Enable `Tint Black` in the [SkeletonAnimation](#SkeletonAnimation-Component)'s inspector in the `Advanced` section: ![](/img/spine-runtimes-guide/spine-unity/skeletonanimation-inspector-tintblack.png) 1. **Spine/Skeleton Tint Black Additive** Unlit transparent shader with Spine-animated per-slot [tint black](/spine-slots#Tint-black) feature. Uses additive blend mode. Does not write to the z-buffer. 1. **Spine/SkeletonGraphic Tint Black** Variant of `Spine/Skeleton Tint Black` shader for [SkeletonGraphic](#SkeletonGraphic-Component). Supports `Additive` blend mode when used with a `CanvasGroup`. Required additional setup steps (for tint color vertex data): 1. Enable `Tint Black` in the [SkeletonAnimation](#SkeletonAnimation-Component)'s inspector in the `Advanced` section. 2. Set the Material of the [SkeletonGraphic](#SkeletonGraphic-Component) to the `SkeletonGraphicTintBlack` material located in the respective subfolder of `Spine/Runtime/spine-unity/Materials` which suits your PMA or Straight alpha texture workflow, with or without CanvasGroup support. ![](/img/spine-runtimes-guide/spine-unity/skeletongraphictintblack-material.png) 3. Select the parent Canvas and under `Additional Shader Channels` enable `TexCoord1` and `TexCoord2`. ![](/img/spine-runtimes-guide/spine-unity/unity-canvas-texcoord1-texcoord2.png) Required additional setup steps for `Additive` blend mode at a `CanvasGroup`: 1. a) spine-unity 4.2 and newer: Enable `CanvasGroup Compatible` at the [SkeletonGraphic](#SkeletonGraphic-Component) inspector in the `Advanced` section. b) on older versions: Enable `Canvas Group Tint Black` at the [SkeletonGraphic](#SkeletonGraphic-Component) inspector in the `Advanced` section. 2. Enable `CanvasGroup Compatible` at the shader. 1. **Spine/Sprite** Sophisticated configurable shaders, allowing for more advanced lighting than the `Spine/Skeleton Lit` shader. You can find a demonstration of the `Spine/Sprite/Vertex Lit` shader in the example scene `Spine Examples/Other Examples/Sprite Shaders`. 1. **Spine/Sprite/Unlit** Unlit shader with configurable blend mode, overlay color, hue, saturation and brightness adjustments. Configurable to write to z-buffer. Fog support. 1. **Spine/Sprite/Vertex Lit** Sophisticated vertex-lit shader with configurable blend mode. Supports normal maps, secondary albedo, metallic and emission maps. Configurable color ramp for cel-shaded look and rim lighting based on normals. Configurable overlay color, hue, saturation and brightness adjustments. Configurable to write to z-buffer. Fog support. 1. **Spine/Sprite/Pixel Lit** Pixel-lit variant of `Spine/Sprite/Vertex Lit` shader. The only shader that receives per-pixel realtime shadows. This shader always writes to the z-buffer (`ZWrite` is enabled as it uses a `ForwardAdd` pass). 1. **Spine/Special** 1. **Spine/Special/Skeleton Grayscale** Unlit transparent shader for grayscale rendering with customizable intensity. Does not write to the z-buffer. 1. **Spine/Special/Skeleton Ghost** Special shader used by [SkeletonGhost](#SkeletonGhost) component for trail rendering. 1. **Spine/Blend Modes** Intended for slots that have blend modes `Additive`, `Multiply` and `Screen` assigned in the Spine editor. It is recommended to automatically assign blend mode materials on import via the provided [BlendModeMaterials SkeletonData Modifier asset](#Included-SkeletonData-Modifiers---BlendModeMaterialsAsset). 1. **Spine/Blend Modes/Skeleton PMA Additive** Unlit transparent shader. Uses additive blend mode. Does not write to the z-buffer. 1. **Spine/Blend Modes/Skeleton PMA Multiply** Unlit transparent shader. Uses multiply blend mode. Does not write to the z-buffer. 1. **Spine/Blend Modes/Skeleton PMA Screen** Unlit transparent shader. Uses screen blend mode. Does not write to the z-buffer. 1. **Spine/Outline** All shaders above provide an `Outline` parameter which can be enabled to switch to the respective `Spine/Outline` shader variant, drawing an additional colored outline around the skeleton. You can find a demonstration of the `Spine/Outline` shaders in the example scene `Spine Examples/Other Examples/Outline Shaders`. 1. **Spine/Outline/OutlineOnly-ZWrite** A special single-pass shader rendering only the outline. Writes to the z-buffer for proper outline occlusion at overlapping attachments. Can also be used when your skeleton requires multiple materials, where normal outline shaders will incorrectly outline each submesh instead of the whole skeleton. You can use e.g. the [`RenderCombinedMesh`](#RenderCombinedMesh) component to re-render your combined skeleton mesh with this outline-only shader to add the outline behind your skeleton. #### Post Processing Effects Some post processing effects like Depth of Field (DoF) require the shader to write to the z-buffer (to be more precice, to a depth pre-pass depth buffer). Some of the Spine shaders provide a `Depth Write` (also called `ZWrite`) parameter which can be enabled at the material, others write to the z-buffer by default. See the documentation above about which of the provided Spine shaders write to the z-buffer. Depending on the project's Graphics settings (or Render Pipeline Asset Settings respectively), it might not be sufficient that the shader writes to the z-buffer, e.g. when using `URP-HighFidelity` as Render Pipeline Asset. In this case you also need to change the `Render Queue` of the Material from `Transparent` to `AlphaTest`. If you feel limited by the provided shaders, you can also create your own modified copy of a Spine shader and change any lines reading `ZWrite Off` to `ZWrite On` (occurring in each Pass section) and change tags `"Queue"="Transparent"` to `"Queue"="AlphaTest"`. Don't forget to change the name of the shader in the first line of the file to avoid name clashes. #### URP Shaders - Extension UPM Package Universal Render Pipeline (URP) shaders are provided as a separate UPM (Unity Package Manager) package. See section [Optional Extension UPM Packages](#Optional--Extension-UPM-Packages) on how to download and install this package and section [Updating an Extension UPM Package](#Updating-an-Extension-UPM-Package) on how to update it. The URP Shaders UPM package provides shaders specifically built for Unity's Universal render pipeline, including 2D Renderer functionality. > **Note:** Do not use URP Shaders with `SkeletonGraphic` components. See [SkeletonGraphic - Important Material Requirements](#Important-Material-Requirements) for details. > **Note:** [*Deferred Rendering Path*](https://docs.unity3d.com/Packages/com.unity.render-pipelines.universal@12.0/manual/rendering/deferred-rendering-path.html), which has recently been added to the Universal Render Pipeline, is not yet supported by Spine URP shaders. **Shaders for URP with 2D Renderer** *(do not use with URP (3D) Forward Renderer)* 1. **Universal Render Pipeline/2D/Spine/Skeleton** Universal 2D renderer variant of the `Spine/Skeleton` shader. 1. **Universal Render Pipeline/2D/Spine/Skeleton Lit** Universal 2D renderer variant of the `Spine/Skeleton Lit` shader. 1. **Universal Render Pipeline/2D/Spine/Sprite** Universal 2D renderer variant of the `Spine/Sprite/Vertex Lit` and `Pixel Lit` shaders. **Shaders for URP with 3D Forward Renderer** *(do not use with URP 2D Renderer)* 1. **Universal Render Pipeline/Spine/Skeleton** Universal variant of the `Spine/Skeleton` shader. 1. **Universal Render Pipeline/Spine/Skeleton Lit** Universal variant of the `Spine/Skeleton Lit` shader. Can be configured to receive per-pixel realtime shadows. 1. **Universal Render Pipeline/Spine/Sprite** Universal variant of the `Spine/Sprite/Vertex Lit` and `Pixel Lit` shaders. Receives per-pixel realtime shadows. 1. **Universal Render Pipeline/Spine/Outline/Skeleton-OutlineOnly** Universal variant of the `Spine/Outline` shaders. URP does not allow multiple passes per shader, so it requires a separate material. You might want to consider the [`RenderExistingMesh`](#RenderExistingMesh) component, as demonstrated in the `com.esotericsoftware.spine.URP-shaders/Examples/Outline Shaders URP` example scene included in this package. If your skeleton requires multiple materials, you can use the [`RenderCombinedMesh`](#RenderCombinedMesh) component instead of the `RenderExistingMesh` component. The shaders can be assigned to materials as usual and will respect your settings of the assigned `UniversalRenderPipelineAsset` under `Project Settings - Graphics`. You can find a demonstration of the URP shaders in the example scenes within the directory `com.esotericsoftware.spine.URP-shaders/Examples` inside the UPM package: `3D/URP 3D Shaders.unity`, `2D/URP 2D Shaders.unity` and `Outline Shaders URP.unity`. #### LWRP Shaders - Extension UPM Package Lightweight Render Pipeline (LWRP) shaders are provided as a separate UPM (Unity Package Manager) package. See section [Optional Extension UPM Packages](#Optional--Extension-UPM-Packages) on how to download and install this package and section [Updating an Extension UPM Package](#Updating-an-Extension-UPM-Package) on how to update it. The LWRP Shaders UPM package provides shaders specifically built for Unity's lightweight render pipeline. > **Note:** Do not use LWRP Shaders with `SkeletonGraphic` components. See [SkeletonGraphic - Important Material Requirements](#Important-Material-Requirements) for details. 1. **Lightweight Render Pipeline/Spine/Skeleton** Lightweight variant of the `Spine/Skeleton` shader. 1. **Lightweight Render Pipeline/Spine/Skeleton Lit** Lightweight variant of the `Spine/Skeleton Lit` shader. 1. **Lightweight Render Pipeline/Spine/Sprite** Lightweight variant of the `Spine/Sprite/Vertex Lit` and `Pixel Lit` shaders. The shaders can be assigned to materials as usual and will respect your settings of the assigned `LightweightRenderPipelineAsset` under `Project Settings - Graphics`. You can find a demonstration of the LWRP shaders in the example scene `com.esotericsoftware.spine.lwrp-shaders-4.2/Examples/LWRP Shaders.unity` in the extracted package. #### Shader Graph Currently there are no official Shader Graph Spine shaders or shader nodes available. Note that when exporting your textures from Spine using [Straight alpha](#Advanced---Premultiplied-vs-Straight-Alpha-Export) settings, you should be able to use any non-Spine shader available. In case you want to replicate a feature that only the Spine shaders have to offer, please have a look at the [forum](/forum/search.php?keywords=shader+graph) for postings like these [[1](/forum/Shader-Graph-with-Normal-Map-and-Diffuse-Ramp-15755)], [[2](/forum/Adding-normals-to-a-Shader-Graph-15077)]. If you have any questions, you can always start a new forum thread in the Unity subforum. #### Amplify Shader Editor While there is no officially provided shader template for the Amplify Shader Editor, user `Hana` has kindly shared template code on the forum [here](/forum/Spine-Shader-Template-for-Amplify-16267?p=71176#p71176). #### Writing your own shaders Please first familiarize with how to write custom shaders for Unity [in general](https://docs.unity3d.com/2020.1/Documentation/Manual/ShadersOverview.html). Especially [Tutorial: vertex and fragment programs](https://docs.unity3d.com/2020.1/Documentation/Manual/SL-ShaderPrograms.html) provides a good overview, allowing you to more easily understand what the individual parts of spine-unity shaders are doing. ##### **Starting from an existing spine-unity shader** It is highly recommended to start with a copy of an existing spine-unity shader. You can then gradually modify an already working shader to adjust it to achieve the desired effect. You can for example add additional color processing before returning the final color. The following code shows a short example on how to create a modified version of the `SkeletonGraphic` shader extended by grayscale functionality: ``` Properties { _GrayIntensity("Intensity", Range(0, 1)) = 1 // this line was added to provide a Material property [..] } ``` ``` sampler2D _MainTex; float _GrayIntensity; // this parameter was added .. fixed4 frag (VertexOutput IN) : SV_Target { .. color.rgb = lerp(color.rgb, dot(color.rgb, float3(0.3, 0.59, 0.11)), _GrayIntensity); // this line was added return color; } ``` ##### **Caveats when using non-Spine shaders or visual shader editors** Be sure to consider the following differences between typical spine-unity shaders and other non-Spine shaders: 1. **Backface culling must be disabled** by setting `Cull Off` when rendering any Spine skeletons. 2. Spine shaders typically don't need normals, therefore `Advanced - Add Normals` may need to be enabled at your component when using lit shaders. 3. Spine shaders typically don't need tangents, therefore `Advanced - Solve Tangents` may need to be enabled at your component when using normal maps. 4. Spine shaders use Premultiply Alpha textures by default. Either a) export atlas textures as [Straight alpha](#Advanced---Premultiplied-vs-Straight-Alpha-Export), or b) change the blend mode of the shader to PMA blend mode `Blend One OneMinusSrcAlpha`. 5. Spine vertex colors are typically PMA vertex colors. When using transparent or `Additive` Slots, you may either a) change the blend mode of the shader to PMA blend mode `Blend One OneMinusSrcAlpha` and use PMA atlas textures, or b) disable `Advanced - PMA Vertex Colors` at your component (not rendering `Additive` Slots then). As always, general rules for UI and non-UI shaders apply: 1. Do not use UI shaders on `SkeletonAnimation` or `SkeletonMecanim`. 2. Do not use non-UI shaders on `SkeletonGraphic`. ##### **Analysis of the `Spine/Skeleton` shader** The following section provides an analysis of the [`Spine/Skeleton` shader](https://github.com/EsotericSoftware/spine-runtimes/blob/4.2/spine-unity/Assets/Spine/Runtime/spine-unity/Shaders/Spine-Skeleton.shader). This shader is applied by default when a Material is generated upon importing your Spine texture atlas. The `Spine/Skeleton` shader is fairly short and typical, and has the following characteristics: - Premultiply Alpha (PMA) blending - No depth buffer writing - No lighting - No backface culling - No fog - Uses vertex colors to tint the texture via multiply - Optionally uses straight alpha instead of PMA textures - Has a `"ShadowCaster"` pass so it can cast realtime shadows - Material Properties: - _MainTex "Main Texture" - _StraightAlphaInput "Straight Alpha Texture" - _Cutoff "Shadow alpha cutoff" - Advanced parameters: - _StencilRef "Stencil Reference" - _StencilComp "Stencil Comparison" - Outline parameters (_OutlineWidth "Outline Width", etc.) ##### **In detail:** - **Premultiply Alpha (PMA) blending** ```hlsl Blend One OneMinusSrcAlpha ``` [(Spine-Skeleton.shader:25)](https://github.com/EsotericSoftware/spine-runtimes/blob/4.2/spine-unity/Assets/Spine/Runtime/spine-unity/Shaders/Spine-Skeleton.shader#L25) Blending is defined as `result_rgba = frag_output_rgba * src_factor + framebuffer_rgba * dst_factor`. The non-standard `Blend One OneMinusSrcAlpha` PMA blend mode allows Slots that are set to `Additive` blend mode to be drawn in a single render pass with `Normal` blend mode Slots. This is achieved by using `One` at `SrcFactor` in the above line (instead of `SrcAlpha`). This adds the unmodified `frag_output_rgba` value to the `OneMinusSrcAlpha` weighted `framebuffer_rgba`: a) For `Normal` blending the fragment shader multiplies `RGB` by `A` and leaves `A` as-is. b) For `Additive` blending `RGB` is not multiplied by alpha, and `A` is set to `0`, receiving `result_rgba = frag_output_rgba + (1-0) * framebuffer_rgba`. The `Normal` and `Additive` Slot blend modes are implicitly passed to the shader as vertex color when the [Advanced - `PMA Vertex Colors`](/spine-unity#Setting-Advanced-Parameters) is enabled at your `SkeletonRenderer` or `SkeletonGraphic` Component: ```hlsl struct VertexInput { float4 vertexColor : COLOR } ``` [(Spine-Skeleton.shader:48)](https://github.com/EsotericSoftware/spine-runtimes/blob/4.2/spine-unity/Assets/Spine/Runtime/spine-unity/Shaders/Spine-Skeleton.shader#L48) When multiplying the PMA vertex colors with the sampled PMA texture colors, Slot blend modes `Normal` or `Additive` are automatically applied: ```hlsl return (texColor * i.vertexColor); ``` [(Spine-Skeleton.shader:72)](https://github.com/EsotericSoftware/spine-runtimes/blob/4.2/spine-unity/Assets/Spine/Runtime/spine-unity/Shaders/Spine-Skeleton.shader#L72) So to support proper `Normal` and `Additive` PMA blend modes in your shader: 1. Define the blend function as `Blend One OneMinusSrcAlpha` 2. Multiply the texture color by the vertex color 3. Enable [Advanced - `PMA Vertex Colors`](/spine-unity#Setting-Advanced-Parameters) at the Component. > If you want to use a shader using standard blend mode `Blend SrcAlpha OneMinusSrcAlpha` and don't need `Additive` Slots, you need to make sure to export your used atlas textures from Spine as [Straight alpha](#Advanced---Premultiplied-vs-Straight-Alpha-Export). - **No depth buffer writing** ```hlsl ZWrite Off ``` [(Spine-Skeleton.shader:24)](https://github.com/EsotericSoftware/spine-runtimes/blob/4.2/spine-unity/Assets/Spine/Runtime/spine-unity/Shaders/Spine-Skeleton.shader#L24) Not writing to the depth buffer is typical of an alpha-blended 2D sprite shader. Transparent objects will be drawn in back-to-front order according to your [`Camera.transparencySortMode`](https://docs.unity3d.com/ScriptReference/Camera-transparencySortMode.html) instead of relying on the depth buffer for depth sorting. `Spine/Skeleton` shares this characteristic with Unity's own `Sprites/Default` shader. > If you want to use a shader that has depth write enabled, be sure to set `Advanced - Z-Spacing` to a value other than `0` at your `SkeletonRenderer` or `SkeletonGraphic` Component to prevent Z-Fighting, especially if you have lighting applied. Note that using the depth buffer may cause unwanted results around semitransparent areas, including aliasing effects on edges. - **No lighting** The `Spine/Skeleton` shader is not affected by any Lights that are placed in the scene and will always be rendered in full `texColor * i.vertexColor` intensity. In order to apply lighting in a shader it is recommended to start from a working lit shader and modify your own copy accordingly. Simply changing the line `Lighting Off` to `Lighting On` will not lead to the desired effect, you need to evaluate lights in your vertex shader (for per-vertex lighting) or fragment shader functions (for per-pixel lighting) to multiply the color intensity accordingly. Also note that URP, URP-2D and standard-pipeline shaders all use a different lighting evaluation setup, so be sure to choose your reference shader accordingly. - **No backface culling** ```hlsl Cull Off ``` [(Spine-Skeleton.shader:23)](https://github.com/EsotericSoftware/spine-runtimes/blob/4.2/spine-unity/Assets/Spine/Runtime/spine-unity/Shaders/Spine-Skeleton.shader#L23) The only strict requirement for rendering Spine skeletons is to **disabling backface culling**, which is typical for 2D shaders. > Most 3D shaders will have backface culling enabled. With Spine meshes, this will cause some triangles to become invisible when parts are scaled negatively or if you flip your skeleton direction. - **No fog** The `Spine/Skeleton` shader is not affected by fog. Enabling fog at your shader will require some additional vertex parameters and function calls added to your shader code. From `UnityCG.cginc`: ```hlsl multi_compile_fog Will compile fog variants. UNITY_FOG_COORDS(texcoordindex) Declares the fog data interpolator. UNITY_TRANSFER_FOG(outputStruct,clipspacePos) Outputs fog data from the vertex shader. UNITY_APPLY_FOG(fogData,col) Applies fog to color "col". Automatically applies black fog when in forward-additive pass. Can also use UNITY_APPLY_FOG_COLOR to supply your own fog color. ``` You can have a look at the `Spine/Sprite/Unlit` shader on how to apply fog in your shader: ```hlsl #pragma multi_compile_fog ``` [(SpritesUnlit.shader:70)](https://github.com/EsotericSoftware/spine-runtimes/blob/4.2/spine-unity/Assets/Spine/Runtime/spine-unity/Shaders/Sprite/ SpritesUnlit.shader#L70) ```hlsl UNITY_FOG_COORDS(1) // to declare it at the free attribute TEXCOORD1 ``` [(SpriteUnlit.cginc:L24)](https://github.com/EsotericSoftware/spine-runtimes/blob/4.2/spine-unity/Assets/Spine/Runtime/spine-unity/Shaders/Sprite/CGIncludes/SpriteUnlit.cginc#L24) ```hlsl UNITY_TRANSFER_FOG(output,output.pos); ``` [(SpriteUnlit.cginc:46)](https://github.com/EsotericSoftware/spine-runtimes/blob/4.2/spine-unity/Assets/Spine/Runtime/spine-unity/Shaders/Sprite/CGIncludes/SpriteUnlit.cginc#L46) - **Uses vertex colors to tint the texture via multiply** See *Premultiply Alpha (PMA) blending* above. - **Optionally uses straight-alpha instead of PMA textures** Since the `Spine/Skeleton` shader's blend mode is constantly set to PMA blending, an input texture without premultiplied alpha colors needs to be converted to a PMA color after sampling. The following lines implement this feature: ``` // bool Material parameter, enables the _STRAIGHT_ALPHA_INPUT shader keyword when enabled [Toggle(_STRAIGHT_ALPHA_INPUT)] _StraightAlphaInput("Straight Alpha Texture", Int) = 0 .. // compiles the shader in two variants so that shader keywords can switch between both variants #pragma shader_feature _ _STRAIGHT_ALPHA_INPUT .. // when enabled, multiply texture rgb values by the texture alpha value. #if defined(_STRAIGHT_ALPHA_INPUT) texColor.rgb *= texColor.a; #endif ``` - **Has a `"ShadowCaster"` pass so it can cast realtime shadows** The second pass with [`Tags { "LightMode"="ShadowCaster" }`](https://github.com/EsotericSoftware/spine-runtimes/blob/4.2/spine-unity/Assets/Spine/Runtime/spine-unity/Shaders/Spine-Skeleton.shader#L77-L116) is automatically identified as shadow caster pass by the `LightMode`. A `ShadowCaster` pass does not write any RGB colors but instead writes depth information to a shadow buffer. Therefore it must use [`ZWrite On`](https://github.com/EsotericSoftware/spine-runtimes/blob/4.2/spine-unity/Assets/Spine/Runtime/spine-unity/Shaders/Spine-Skeleton.shader#L81). Since you cannot write semi-transparent depth, the fragment can either be written to the depth buffer, or discarded to not cast a shadow. This is done with the thresholding function call: ```hlsl clip(texcol.a * i.uvAndAlpha.a - _Cutoff); ``` [(Spine-Skeleton.shader:112)](https://github.com/EsotericSoftware/spine-runtimes/blob/4.2/spine-unity/Assets/Spine/Runtime/spine-unity/Shaders/Spine-Skeleton.shader#L112) Here the `_Cutoff` Material parameter defines the alpha threshold, a fragment is discarded by `clip(x)` if x < 0. - **Material Properties:** - _MainTex "Main Texture" The main texture. - _StraightAlphaInput "Straight Alpha Texture" See *"Optionally uses straight-alpha instead of PMA textures"* above. - _Cutoff "Shadow alpha cutoff" See *"Has a `"ShadowCaster"` pass so it can cast realtime shadows"* above. - Advanced parameters: - _StencilRef "Stencil Reference" Used for mask interaction. - _StencilComp "Stencil Comparison" Used for mask interaction, will be set by `SkeletonRenderer` or `SkeletonGraphic` Component according to `Mask Interaction` property. - Outline parameters (_OutlineWidth "Outline Width", etc.) Used when switching to outline shader variant `Spine/Outline/Skeleton`. Not used in the normal non-outline shader variant `Spine/Skeleton`. ### Materials ![](/img/spine-runtimes-guide/spine-unity/raptor-atlas-page.png) Each atlas page Texture requires its own Material, which is automatically created upon skeleton import. When using Slot blend modes other than `Normal`, additional Materials are created for each blend mode as well (except for `Additive` when using PMA, which can be rendered with the normal material). The Materials array of a MeshRenderer is managed by the [SkeletonRenderer](#SkeletonRenderer-Component) every frame, depending on the currently assigned attachments and the AtlasAssets these are contained in, and the used blend mode at the Slot. > **Note:** Direct modifications to the Materials array have no effect as they will be overwritten in the following `LateUpdate()` call. Use a [SkeletonRendererCustomMaterials](#SkeletonRendererCustomMaterials) or [SkeletonGraphicCustomMaterials](#SkeletonGraphicCustomMaterials) component to override materials. You can also assign different Materials at the *_Atlas* asset to change Materials for all instances. After any *_Atlas* asset modification you may need to hit `Reload` at the `SkeletonData Asset` parameter of your `SkeletonRenderer` component to reload the skeleton using the new atlas materials. > **Note:** Only use Materials with a `Spine/SkeletonGraphic*` shader with `SkeletonGraphic` components. Do not use URP, LWRP or normal shaders like `Spine/Skeleton` with a `SkeletonGraphic` component. See [SkeletonGraphic - Important Material Requirements](#Important-Material-Requirements) for details. #### Material Switching and Draw Calls If assigned attachments are distributed across multiple atlas pages or have different blend modes, e.g. material `A` and material `B`, the Materials array is set according to the draw order in which the materials are needed. If the order is: > 1. Attachment from A > 2. Attachment from A > 3. Attachment from B > 4. Attachment from A The resulting material array will be: > 1. Material A (for attachments 1 and 2) > 2. Material B (for attachment 3) > 3. Material A (for attachment 4) Every material in the Materials array corresponds to a [draw call](http://docs.unity3d.com/Manual/DrawCallBatching.html). Therefore a high amount of material switching adversely affects performance. The Dragon example shows an unfortunate use case with many draw calls: ![](/img/spine-runtimes-guide/spine-unity/render_spineunity_alternatingmaterials.png) It is therefore recommended to pack attachments to as few atlas pages as possible, and to group attachments to atlas pages according to draw order to prevent unnecessary material switching. Please see [Spine Texture Packer: Folder Structure](/spine-texture-packer#Folder-structure) on how to arrange atlas regions in your Spine atlases. #### Changing Materials Per Instance > **Note:** Direct modifications to the [SkeletonRenderer](#SkeletonRenderer-Component)'s Materials array have no effect as they will be overwritten in the following `LateUpdate()` call. If none of the methods below are suitable, you can manually override `MeshRenderer.Materials` every frame by using the [`SkeletonAnimation.OnMeshAndMaterialsUpdated`](#Life-cycle) callback delegate. This callback is called at the end of `LateUpdate()` after atlas materials have been assigned. ##### **CustomMaterialOverride and CustomSlotMaterials** [SkeletonRenderer](#SkeletonRenderer-Component) allows you to override Materials on specific slots or override the resulting materials. To replace an original material with your new material at runtime for an instance of [SkeletonRenderer](#SkeletonRenderer-Component), you can use `SkeletonRenderer.CustomMaterialOverride`: ```csharp // Use the following code to programmatically query the original material, see note below. // MeshRenderer.material will not work, MeshRenderer.sharedMaterial might fail in some cases. if (originalMaterial == null) originalMaterial = skeletonAnimation.SkeletonDataAsset.atlasAssets[0].PrimaryMaterial; skeletonAnimation.CustomMaterialOverride[originalMaterial] = newMaterial; // to enable the replacement. skeletonAnimation.CustomMaterialOverride.Remove(originalMaterial); // to disable that replacement. ``` > **Note:** Don't use `originalMaterial = skeletonAnimation.GetComponent!lt!MeshRenderer!gt!().material` as `.material` returns an instance copy of your primary Material, not the Material itself. It is also not recommended to use `originalMaterial = skeletonAnimation.GetComponent!lt!MeshRenderer!gt!().sharedMaterial`, as it might return null when the primary Material is not assigned yet, e.g. when the active frame has no active attachments or when called too early. To use a replacement Material on just a specific slot, you can use `SkeletonRenderer.CustomSlotMaterials`: ```csharp skeletonAnimation.CustomSlotMaterials[slot] = newMaterial; // to enable the replacement. skeletonAnimation.CustomSlotMaterials.Remove(slot); // to disable that replacement. ``` ##### **Tinting Skeletons while retaining batching** Using different `Materials` or `MaterialPropertyBlocks` on skeleton instances breaks batching. If you only need to tint individual skeleton instances differently and require no other material property modifications, you can use the `Skeleton.R .G .B .A` color properties. For tinting to be applied, [`Advanced - PMA Vertex Colors`](#Setting-Advanced-Parameters) must be enabled at the SkeletonRenderer Inspector. ```csharp public Color color = Color.white; ... skeleton = GetComponent().Skeleton; ... skeleton.R = color.r; skeleton.G = color.g; skeleton.B = color.b; skeleton.A = color.a; ``` These skeleton color values will set vertex colors and don't affect your Material properties. Same applies for tinting individual attachments: ```csharp slot = skeleton.FindSlot(slotname); ... slot.R = slotColor.r; slot.G = slotColor.g; slot.B = slotColor.b; slot.A = slotColor.a; ``` > **Note:** When your animations modify attachment color values, be sure to set any Slot color values after the animations have been applied by using e.g. the [SkeletonAnimation.UpdateComplete](#Life-cycle) callback. ##### **MaterialPropertyBlocks** ![](/img/spine-runtimes-guide/spine-unity/materialpropertyblock-demo.gif) You can use [Renderer.SetPropertyBlock](http://docs.unity3d.com/ScriptReference/Renderer.SetPropertyBlock.html) to override material property values for a single `MeshRenderer`. ```csharp MaterialPropertyBlock mpb = new MaterialPropertyBlock(); mpb.SetColor("_FillColor", Color.red); // "_FillColor" is a named property on the used shader. mpb.SetFloat("_FillPhase", 1.0f); // "_FillPhase" is another named property on the used shader. GetComponent().SetPropertyBlock(mpb); // to deactivate the override again: MaterialPropertyBlock mpb = this.cachedMaterialPropertyBlock; // assuming you had cached the MaterialPropertyBlock mpb.Clear(); GetComponent().SetPropertyBlock(mpb); ``` > **Note:** Parameter names used at a `MaterialPropertyBlock`, such as `_FillColor` or `_FillPhase`, have to match the name of the respective shader variable. Note that the shader variable name is not the name displayed in the Inspector, such as `Fill Color` and `Fill Phase`. To view the shader parameter names, you can open the `.shader` file (via the Material's gear icon menu, select `Edit Shader`) and have a look at the top-most secion called `Properties { .. }`. There you will find a listing of all parameters. In a parameter line like the following, it is the **leftmost** name `_FillColor`: ``` _FillColor ("Fill Color", Color) = (1,1,1,1) ^^^^^^^^^^ ``` Shader variable names typically start with an `_` character, and they never contain any spaces. The strings next to it like `"Fill Color"` is what is displayed in the Inspector. You can find a demonstration of per-instance material properties in the example scene `Spine Examples/Other Examples/Per Instance Material Properties`. > **Notes on optimization** > - Using Renderer.SetPropertyBlock with different Material values will break batching between renderers. Batching will take place between renderers when MaterialPropertyBlock parameters are equal, e.g. all setting tint color to the same green color. > - You need to call `SetPropertyBlock` whenever you change or add a property value to your MaterialPropertyBlock. But you can keep that MaterialPropertyBlock as part of your class so you don't have to keep instantiating a new one whenever you want to change a property. > - When you need to set a property frequently, you can use the static method: `Shader.PropertyToID(string)` to cache the int ID of that property instead of using the string overload of MaterialPropertyBlock's setters. ### Transparency and Draw Order All spine-unity shaders use alpha blending to cleanly draw semi-transparent transitions at borders of attachments. Without alpha blending (using a hard transparency threshold) hard jagged outlines would be the result, similar to aliasing artifacts. Unfortunately, alpha blending presents classical problems as the z-buffer cannot be used for automatic depth sorting. Instead, triangles need to be rendered in back-to-front order, painting parts over each other. Each [SkeletonRenderer](#SkeletonRenderer-Component) generates it's mesh accordingly, with triangles following the [Slot draw order](/spine-basic-concepts#Slots) defined in Spine. Within a single mesh, even a single draw call will paint correctly ordered skeleton parts. Between meshes, spine-unity utilizes many of Unity’s render order systems to determine what mesh should be on top of which. Using the standard spine-unity setup, whole skeleton meshes are rendered in an order determined by multiple factors: 1. **[Camera depth](http://docs.unity3d.com/ScriptReference/Camera-depth.html).** *Relevent in multi-camera setups.* 1. **Material.renderQueue.** *When set, it overrides the shader's `Queue` tag.* 1. **Shader's `Queue` tag.** *Defaults to `"Transparent"` queue in `Spine` shaders as other sprites.* 1. **[Sorting Group](https://docs.unity3d.com/ScriptReference/Rendering.SortingGroup.html) components.** *When placed on the MeshRenderer's GameObject or on any of the parents GameObjects.* 1. **Renderer's [SortingLayer](https://docs.unity3d.com/ScriptReference/SortingLayer.html) and [SortingOrder within a layer](https://docs.unity3d.com/ScriptReference/Renderer-sortingOrder.html).** 1. **Distance from the camera.** *Cameras can be configured whether [planar or perspective distance is used](http://docs.unity3d.com/ScriptReference/Camera-transparencySortMode.html).* If a scene's renderers are in the same sorting layer and order and the shader `Queue` tags are equal, you can control sorting of your Spine GameObjects via distance to the camera. Note that cameras provide a [transparencySortMode](http://docs.unity3d.com/ScriptReference/Camera-transparencySortMode.html) property. #### Sorting Layer and Order in Layer The inspector of a [SkeletonRenderer](#SkeletonRenderer-Component) (or subclasses [SkeletonAnimation](#SkeletonAnimation-Component) and [SkeletonMecanim](#SkeletonMecanim-Component)) provides `Sorting Layer` and `Order in Layer` properties which actually modify the `MeshRenderer`'s [sortingLayerID](http://docs.unity3d.com/ScriptReference/Renderer-sortingLayerID.html) and [sortingOrder](http://docs.unity3d.com/ScriptReference/Renderer-sortingOrder.html) properties. These properties are stored as part of `MeshRenderer` and are not part of `SkeletonRenderer`. You can access these properties via code: ```csharp GetComponent().sortingOrder = 1; // Change the Order in Layer to 1. ``` #### Preventing Incorrect Sorting ![](/img/spine-runtimes-guide/spine-unity/incorrect-sorting.png) Especially when using an orthographic camera, it may occur that skeletons using multiple atlas pages are sorted incorrectly. You can counter this by adding a [Sorting Group](https://docs.unity3d.com/ScriptReference/Rendering.SortingGroup.html) component to the skeleton GameObject. Another workaround is to rotate the camera by a tiny amount, e.g. set the camera's transform rotation Y value to 0.001. #### Rendering Objects between Parts of a Skeleton ![](/img/spine-runtimes-guide/spine-unity/skeleton-render-separator-spineboy.png) You may want to display other GameObjects between parts of your character, e.g. to let your character run into a tree and display one leg in front and one behind the trunk. spine-unity provides a [SkeletonRenderSeparator](#SkeletonRenderSeparator) component for the purpose of splitting a skeleton into multiple parts. #### Fading a Skeleton In or Out Unfortunately, alpha blending will cause back parts of your skeleton show through when lowering the alpha value of your skeleton to make it semi-transparent. This is a common problem due to transparency being applied when each triangle is drawn. ![](/img/spine-runtimes-guide/spine-unity/CommonError-AlphaFadeOut-Comparison.png) One solution to this problem is to use a temporary [RenderTexture](https://docs.unity3d.com/Manual/class-RenderTexture.html). You can render the whole character to the RenderTexture at normal opacity and then draw the content of this RenderTexture to your scene at the desired fade opacity. You can use the provided [SkeletonRenderTexture](#SkeletonRenderTexture) and [SkeletonRenderTextureFadeout](#SkeletonRenderTextureFadeout) example components for this purpose. You can find a demonstration of these components in the example scene `Spine Examples/Other Examples/RenderTexture FadeOut Transparency`. Note that this is only one of many ways to achive a fade-out effect. There may be other easier solutions such as gradually tinting the skeleton with a solid color, decreasing scale, etc. Existing 2D games may serve as valuable inspiration, as RenderTextures are a costly solution that has rarely been used in the past. ## Example Components spine-unity comes with additional example components that demonstrate solutions for some advanced use cases. The most important example components are listed below. ### SkeletonRagdoll You may want to turn an animated skeleton into a puppet-like ragdoll, e.g. to simulate falling down via physics in case of death. This can be achieved with the `SkeletonRagdoll` and `SkeletonRagdoll2D` example components, which provide a comfortable interface to create ragdoll physics components at a [SkeletonRenderer](#SkeletonRenderer-Component) (or subclasses [SkeletonAnimation](#SkeletonAnimation-Component) and [SkeletonMecanim](#SkeletonMecanim-Component)). You can find a demonstration of the `SkeletonRagdoll2D` component in the example scene `Spine Examples/Other Examples/SkeletonUtility Ragdoll`. ### SkeletonRenderTexture There are situations where you may need to render your skeleton to a [RenderTexture](https://docs.unity3d.com/Manual/class-RenderTexture.html) instead of directly to the screen, e.g. when you want to [fade out a skeleton via transparency](#Fading-a-Skeleton-In-or-Out). This component takes care of rendering the skeleton to a `RenderTexture` at the appropriate size and resolution and displays it at a matched quad, so that you can seamlessly switch to a one-to-one replacement. The [SkeletonRenderTextureFadeout](#SkeletonRenderTextureFadeout) component described below requires a `SkeletonRenderTexture` or a [SkeletonGraphicRenderTexture](#SkeletonGraphicRenderTexture) component. After adding the `SkeletonRenderTexture` component to your GameObject, you can add a `SkeletonRenderTextureFadeout` component to take care of a fade-out effect. > **Important Note:** Using an intermediate RenderTexture for rendering is an expensive operation compared to directly drawing a skeleton to the frame buffer. Use this component only where necessary. Keep it disabled until you actually want to enable the desired effect. E.g. only enable the `SkeletonRenderTexture` component during fade-out, but keep it disabled before and after that. ### SkeletonGraphicRenderTexture A variant of the [SkeletonRenderTexture](#SkeletonRenderTexture) component to be used with [SkeletonGraphic](#SkeletonGraphic-Component). ### SkeletonRenderTextureFadeout ![](/img/spine-runtimes-guide/spine-unity/CommonError-AlphaFadeOut-Comparison.png) You may want to fade-out a skeleton via transparency, but want to avoid the overlapping attachments issue [described here](#Fading-a-Skeleton-In-or-Out). This components can be used either with a [SkeletonRenderTexture](#SkeletonRenderTexture) or [SkeletonGraphicRenderTexture](#SkeletonGraphicRenderTexture) component (which needs to be added first) to render a skeleton at full opacity to a temporary [RenderTexture](https://docs.unity3d.com/Manual/class-RenderTexture.html) and then draw the content of this `RenderTexture` to your scene at the desired fade opacity. ### SkeletonGhost You may want to render a motion-trail or motion-blur effect at at character to simulate speed or power. The `SkeletonGhost` example component can be attached at a [SkeletonRenderer](#SkeletonRenderer-Component) (or subclasses [SkeletonAnimation](#SkeletonAnimation-Component) and [SkeletonMecanim](#SkeletonMecanim-Component)) to draw the skeleton multiple times, using a customizable material. ### SkeletonUtilityKinematicShadow You may want to have some bones to receive some inertia or to react to movement of other bones. This may be useful to have a cape follow the movement of a character in a more convincing way. This can be achieved with the `SkeletonUtilityKinematicShadow` component. It allows hinge chains to inherit a velocity interpreted from changes in parent transform position or from unrelated rigidbodies. You can find a demonstration of the `SkeletonUtilityKinematicShadow` component in the example scene `Spine Examples/Other Examples/SkeletonUtility Animated Physics`. ### RenderExistingMesh You may want to save performance by rendering identical copies of animated Skeletons multiple times at different locations, e.g. when a large group of skeletons allows for some repetition. Or you want to render a mesh again behind itself using e.g. the URP shader `Universal Render Pipeline/Spine/Outline/Skeleton-OutlineOnly` when selected. This component can be used to render an already animated and updated skeleton mesh again, saving the overhead of animation and calculating the mesh. ### RenderCombinedMesh When your skeleton requires multiple materials, the included outline shaders will incorrectly outline each submesh instead of the whole skeleton. This component can be used to combine the submeshes and render them as a single mesh, leading to correct outlines. ## Example Scenes The spine-unity runtime includes example scenes to demonstrate the most important components and usage of the C# API for common use cases. You can find them in the `Spine Examples` top level directory. Each scene includes a description text that will help you to quickly discover and understand the relevant parts. This video provides an overview of the example scenes included in the spine-unity runtime. !! If you are using the spine-unity runtime for the first time, it is highly recommended to check out at least the example scenes in the `Spine Examples/Getting Started`. ### Spine Examples / Getting Started The example scenes in the `Spine Examples/Getting Started` demonstrate the fundamental components and basic use cases. #### 1 The Spine GameObject This scene demonstrates the [SkeletonAnimation component](#SkeletonAnimation-Component) and the referenced SkeletonDataAsset which provides the necessary data. #### 2 Controlling Animation This scene demonstrates basic animation code using the C# API - starting animations and reacting to animation events. When pressing play, Spineboy will sequentially play animations walk, run, idle, and turn. Footstep events will trigger a sound accordingly. You can inspect the example script `SpineBeginnerTwo` component which is attached at the `spineboy` GameObject. It demonstrates usage of `SkeletonAnimation.AnimationState.SetAnimation()` and `SkeletonAnimation.AnimationState.AddAnimation()`. The script `HandleEventWithAudioExample` attached at the `sound` GameObject shows how you can hook up your own event method callback by registering it at `SkeletonAnimation.AnimationState.Event`. #### 3 Controlling Animation Continued This scene demonstrates how you can play animations simultaneously by using multiple animation tracks. It also shows how to use `AnimationReferenceAssets` as an alternative to using animation name strings. When pressing play, the `walk` animation will start to play in a loop. At the same time, and in its own timeframe, the `gungrab` and `gunkeep` animations are playing as a secondary animation. You can inspect the example script `Raptor` attached at the `raptor Skeleton` GameObject. It shows [how to expose AnimationReferenceAsset](https://github.com/EsotericSoftware/spine-runtimes/blob/4.2/spine-unity/Assets/Spine%20Examples/Scripts/Getting%20Started%20Scripts/Raptor.cs#L38-L40) properties at a component and assign it as animation [by calling the `SkeletonAnimation.AnimationState.SetAnimation()`](https://github.com/EsotericSoftware/spine-runtimes/blob/4.2/spine-unity/Assets/Spine%20Examples/Scripts/Getting%20Started%20Scripts/Raptor.cs#L57) method, on tracks 0 and 1. #### 4 Object Oriented Sample This scene demonstrates how you can setup a platformer character following the [Model-View-Controller](https://en.wikipedia.org/wiki/Model%E2%80%93view%E2%80%93controller) object oriented software design pattern. Please note that while this setup might not be the most suitable for your projects, it shall serve as inspiration on how input, game logic and visualization may be separated into components. When pressing play, you can control the Spineboy character with WASD (move), Spacebar (jump) and mouse input (aim and fire). Alternatively you can control it via an XBOX Controller. You can inspect the example script `SpineboyBeginnerInput` attached at the `PLAYER INPUT` GameObject, acting as `controller`. It modifies the state of the `model` represented by the `SpineboyBeginnerModel` component attached at the `PLAYER Spineboy` GameObject. Visualization of this state is performed by the `SpineboyBeginnerView` component, attached at the `VIEW Spineboy` GameObject, acting as `view`. It starts the respective animations at the [SkeletonAnimation](#SkeletonAnimation-Component) component which is attached at the same GameObject. #### 5 Basic Platformer This scene demonstrates the use case of a platformer with typical animations such as jump, run, fall, land, complete with particles and sound effects. It also shows how Spine meshes can be used to cast shadows in Unity. > **Note:** If you do not see any cast shadows, please enable shadows via `Edit - Preferences - Quality - Shadows` (`Unity - Preferences` on Mac). When pressing play, you can control the Hero character with WASD (move) and Spacebar (jump). Alternatively you can control it via an XBOX Controller. You can inspect the example script `BasicPlatformerController` attached at the `Player` GameObject. It shows how you can use Unity input to change between a character's states which are tracked in a newly created [`CharacterState`](https://github.com/EsotericSoftware/spine-runtimes/blob/4.2/spine-unity/Assets/Spine%20Examples/Scripts/Getting%20Started%20Scripts/BasicPlatformerController.cs#L39-L48) attribute. When states change, the `SkeletonAnimationHandleExample` example script is used to transition to the new animation, while the `HeroEffectsHandlerExample` example script is used to play a sound and spawn particle systems. #### 6 SkeletonGraphic This scene demonstrates the [SkeletonGraphic component](#SkeletonGraphic-Component) and how it can be integrated into an existing Unity UI. It also shows how `BoneFollowerGraphic` components can be used to attach text labels to follow bone positions. They can be found at the `Detached BoneFollowerGraphic` and `Child BoneFollowerGraphic` GameObjects. When pressing play, you will see a Canvas-based user interface where Doi and Spineboy are integrated into a scrollable panel. Both play looping animations just as a [SkeletonAnimation](#SkeletonAnimation-Component) component while being part of the UI. ## Timeline Extension UPM Package ![](/img/spine-runtimes-guide/spine-unity/timeline/timeline.png) Timeline support is provided as a separate UPM (Unity Package Manager) package. See section [Optional Extension UPM Packages](#Optional-Extension-UPM-Packages) on how to download and install this package and section [Updating an Extension UPM Package](#Updating-an-Extension-UPM-Package) on how to update it. This video will help you with installing and using the Timeline extension package. !! ### Spine-Unity Timeline Playables ![](/img/spine-runtimes-guide/spine-unity/timeline/add-menu.png) Spine Timeline currently provides three types of Timeline Playables: - `SkeletonAnimation Track` *(animates `SkeletonAnimation`)*, - `SkeletonGraphic Track` *(animates `SkeletonGraphic`)*, - `Skeleton Flip Track` *(flips `SkeletonAnimation` or `SkeletonGraphic`)*. > Note: Timeline tracks have been renamed in recent versions to improve readability. `SkeletonAnimation Track` was called `Spine AnimationState Track`, `SkeletonGraphic Track` was called `Spine AnimationState Graphic Track`, `Skeleton Flip Track` was called `Spine Skeleton Flip Track`. **Limitations:** currently only [SkeletonAnimation](#SkeletonAnimation-Component) and [SkeletonGraphic](#SkeletonGraphic-Component) are supported. There is currently no Timeline support for [SkeletonMecanim](#SkeletonMecanim-Component). #### SkeletonAnimation Track and SkeletonGraphic Track ![](/img/spine-runtimes-guide/spine-unity/timeline/animationstate-track.png) These track types can be used to set animations at the AnimationState of the target `SkeletonAnimation` or `SkeletonGraphic`. Track type `SkeletonAnimation Track` is used for `SkeletonAnimation`, `SkeletonGraphic Track` for `SkeletonGraphic`. ![](/img/spine-runtimes-guide/spine-unity/timeline/animationstate-track-inspector.png) **Parameters** - *Track Index.* The target AnimationState track index to set animations at. Do not forget to set this value accordingly when using multiple timeline tracks. > **Important Note:** Currently it is required to order the timeline tracks with base track at the top and overlay tracks below, otherwise the Editor Preview will display incorrect results. - *Unscaled Time.* Whenever starting a new animation clip of this track, `SkeletonAnimation.UnscaledTime` (or `SkeletonGraphic.UnscaledTime` respectively) will be set to this value. This allows you to play back Timeline clips either in normal game time or unscaled game time. Note that `PlayableDirector.UpdateMethod` is ignored and replaced by this property, which allows more fine-granular control per Timeline track. ##### Spine Animation State Clip You can add a `Spine Animation State Clip` to a `SkeletonAnimation Track` (or `SkeletonGraphic Track`) by dragging an `AnimationReferenceAsset` onto a Timeline track. See the [SkeletonData - Preview](#Preview) section on how to generate `AnimationReferenceAssets` for a `SkeletonDataAsset`. ![](/img/spine-runtimes-guide/spine-unity/timeline/animationstate-clip-inspector.png) **Parameters** *Clip Timing* - *Clip In.* An initial local start time offset applied when playing this animation. Can also be adjusted by dragging the left edge of the clip. - *Blend In Duration.* Blend transition duration used when `Use Blend Duration` is enabled and `Default Mix Duration` is disabled. Can be adjusted by moving the clip into the previous clip, resulting in a cross-fade triangle at the transition. - *Speed Multiplier.* Playback speed multiplier. When set to 2.0 it will play the animation twice as fast, when set to 0.5 half as fast. *Spine Animation State Clip* - *Don't Pause with Director.* If set to true, the animation will continue playing when the Director is paused. - *Don't End with Clip.* Normally when empty space follows the clip on the timeline, the empty animation is set on the track. Set this parameter to true to continue playing the clip's animation instead. - *Clip End Mix Out Duration.* When `Don't End with Clip` is false, and the clip is followed by blank space or stopped, the empty animation is set with this `MixDuration`. When set to a value less than 0, the clip is paused instead. *Mixing Setting* - *Default Mix Duration.* When disabled, the value under `Mix Duration` below is used for transitions from the previous animation to this animation. When enabled, it will use the setup `Mix Duration` value at the SkeletonData asset for the animation pair. - *Use Blend Duration.* When enabled, the value under `Mix Duration` will be synced with the timeline clip transition duration 'Ease In Duration'. Enable this value to adjust transition durations by moving the clip into the previous clip, resulting in a cross-fade triangle at the transition. - *Mix Duration.* When *Default Mix Duration* is disabled, this mix duration is used for transitions from the previous animation to this animation. - *Event Threshold.* See [TrackEntry.EventThreshold](/spine-api-reference#TrackEntry-eventThreshold). - *Attachment Threshold.* See [TrackEntry.AttachmentThreshold](/spine-api-reference#TrackEntry-attachmentThreshold). - *Draw Order Threshold.* See [TrackEntry.DrawOrderThreshold](/spine-api-reference#TrackEntry-drawOrderThreshold). - *Alpha.* See [TrackEntry.Alpha](/spine-api-reference#TrackEntry-alpha). *Ignored Parameters* - *Ease Out Duration, Blend Curves*. These parameters are ignored and have no effect. > Note: *Default Mix Duration* was previously called *Custom Duration* and inverted. This has been changed to improve readability. **Usage** 1. Add `SkeletonAnimationPlayableHandle` component to your SkeletonAnimation GameObject, or the `SkeletonGraphicPlayableHandle` in case of `SkeletonGraphic`. 2. With an existing Unity Playable Director, and in the Unity Timeline window, right-click on an empty space on the left and choose `Spine` - `SkeletonAnimation Track`. 3. Drag the SkeletonAnimation or SkeletonGraphic GameObject onto the empty reference property of the new Spine AnimationState Track. 4. To add an animation at a track, drag the respective [`AnimationReferenceAsset`](#Preview) into the clips view (the right part of the Timeline panel) as you would with normal animation clips. See spine-unity Runtime Documentation, [section Preview](#Preview) on how to create an `AnimationReferenceAsset` for each of your animations. > **Note:** You can use the Duplicate function (`CTRL`/`CMD` + `D`) to duplicate selected clips in the clips view. **Track Behavior** - `AnimationState.SetAnimation()` will be called at the beginning of every clip based on the `AnimationReferenceAsset`. - Clip durations matter since Timeline version 4.0. > Note: Behavior of version 3.8 was that clip durations don't matter. Animations were not cleared when reaching empty space after a clip on the timeline. - Empty animation: If a clip has no `AnimationReferenceAsset` assigned, it will call `SetEmptyAnimation` instead. - Error handling: If the animation with the provided `AnimationReferenceAsset` is not found, it will do nothing (the previous animation will continue playing normally). - Animations playing before the timeline starts playing will not be interrupted until the first clip starts playing. - What happens at the end of clips and at the end of the timeline depends on clip settings. When `Don't End with Clip` is true, nothing happens at the clip's end. This means the effect of the last clip's `SetAnimation` call will persist until you issue other calls at the AnimationState. If `Don't End with Clip` is false, it will be mix out to the empty animation with duration `Clip End Mix Out Duration`, or paused when `Clip End Mix Out Duration` is less than 0. - Edit mode preview mixing may look different from Play Mode mixing. Please check in actual Play Mode to see the actual results. Please see the remark in the [SkeletonAnimation Track](#SkeletonAnimation-Track-and-SkeletonGraphic-Track) section on correct track ordering when previewing multiple overlaid tracks. #### Skeleton Flip Track ![](/img/spine-runtimes-guide/spine-unity/timeline/skeleton-flip-track.png) This track type can be used to flip the skeleton of the target `SkeletonAnimation` or `SkeletonGraphic`. ##### Spine Skeleton Flip Clip ![](/img/spine-runtimes-guide/spine-unity/timeline/skeleton-flip-clip-inspector.png) **Parameters** - *Flip X.* Flips the skeleton along the X axis during the extents of the clip. - *Flip Y.* Flips the skeleton along the Y axis during the extents of the clip. **Usage** 1. Add `SkeletonAnimationPlayableHandle` component to your SkeletonAnimation GameObject, or the `SkeletonGraphicPlayableHandle` in case of `SkeletonGraphic`. 2. With an existing Unity Playable Director, and in the Unity Timeline window, right-click on an empty space on the left and choose `Spine` - `Skeleton Flip Track`. 3. Drag the SkeletonAnimation or SkeletonGraphic GameObject onto the empty reference property of the new Spine Skeleton Flip Track. 4. Right-click on the row in an empty space in the Timeline dopesheet and choose `Add Spine Skeleton Flip Clip`. 5. Adjust the start and end times of the new clip, name it appropriately at the top of the Inspector, and choose the desired FlipX and FlipY values. **Track Behavior** - The specified skeleton flip values will be applied for every frame within the duration of each track. - At the end of the timeline, the track will revert the skeleton flip to the flip values it captures when it starts playing that timeline. #### Known Issues - The Console potentially logs an incorrect and harmless error `DrivenPropertyManager has failed to register property "m_Script" of object "Spine GameObject (spineboy-pro)" with driver "" because the property doesn't exist.`. This is a known issue on Unity's end. See more here: https://forum.unity.com/threads/default-playables-text-switcher-track-error.502903/ # FAQ ## Import When something goes wrong importing your skeleton into Unity there are a number of possible causes, from incorrect Spine export settings to incorrect settings in Unity. This video will help you better understand the correct settings for many common problems during import. !! > **Why does import fail with a window saying "Could not automatically set the AtlasAsset for .."?** ![](/img/spine-runtimes-guide/spine-unity/CommonError-AtlasAsset.png) Please make sure that your have named the atlas file extension `.atlas.txt` and not `.atlas`. See [Spine Unity Export for Beginners](#Spine-Unity-Export-for-Beginners) for details. > **Why do I get the error "Opening scene in read-only package!" when opening a scene from a git UPM package?** ![Opening scene in readonly package](/img/spine-runtimes-guide/spine-unity/opening-scene-readonly-package.png) Unfortunately a bug in Unity causes the error `"Opening scene in read-only package!"` when trying to directly open a scene within a package downloaded via git URL. To open the example scenes contained in the package, please copy the scene files from the package directory to your `Assets` directory using your system's file manager (*Explorer* or *Finder* respectively). ## Visual > **Why do I get dark borders around transparent areas of my attachment images?** ![](/img/spine-runtimes-guide/spine-unity/CommonError-PMA-as-Straight.png) Most likely you have exported your textures as `Premultiply alpha` (PMA) but your import Material or Texture settings in Unity don't match this. See [Premultiplied vs Straight Alpha Import](#Advanced---Premultiplied-vs-Straight-Alpha-Import) for details. If you are using `Linear` color space, note that PMA textures are not supported. Another potential cause is when straight alpha workflow is used together with `Generate Mip Maps` enabled in Texture import settings, but color bleed has not been applied to all transparent pixels. This may happen even when exporting from Spine with option `Bleed` enabled if you modify the exported texture in an image editor. Some do not properly re-apply color bleed in transparent areas where alpha is 0, leaving the RGB portion of the pixel black or white instead. Whenever the unmodified exported texture is displayed correctly but the modified is not, missing color bleed is likely the cause. > **Why do I get colorful stripes in transparent areas of my attachment images?** ![](/img/spine-runtimes-guide/spine-unity/CommonError-Straight-as-PMA.png) Most likely you have exported your textures as straight alpha (`Bleed`) but your import Material or Texture settings in Unity don't match this. See [Premultiplied vs Straight Alpha Import](#Advanced---Premultiplied-vs-Straight-Alpha-Import) for details. > **Why do I get white borders around my attachment images when enabling Generate Mip Maps?** ![](/img/spine-runtimes-guide/spine-unity/CommonError-PMA-sRGB-Mipmaps.png) Most likely you have exported your textures as `Premultiply alpha` (PMA) but your import Texture settings in Unity have incorrectly enabled `sRGB (Color Texture)`. See [Premultiplied vs Straight Alpha Import](#Advanced---Premultiplied-vs-Straight-Alpha-Import) for details. > **I tried assigning materials at the MeshRenderer, but it is not possible. Why?** The Materials are controlled by the `SkeletonRenderer` every frame, see section [Materials](#Materials) for details. If you want to replace materials per instance or per Slot, see [Changing Materials Per Instance](#Changing-Materials-Per-Instance). > **Some of the included Spine shaders display incorrectly in my URP project. Why?** The spine-unity runtime package provides only [Built-In Render Pipeline](https://docs.unity3d.com/Manual/built-in-render-pipeline.html) shaders, which are not compatible with [Universal Render Pipeline](https://unity.com/srp/universal-render-pipeline) projects. Please use the provided URP shaders of the [Spine URP Shaders extension UPM package](#URP-Shaders---Extension-UPM-Package) instead. > **The Outline shader displays only outlines in my URP project. Why?** ![](/img/spine-runtimes-guide/spine-unity/CommonError-Outline-URP.png) There are two potential causes: 1. You're using a Built-In Render Pipeline shader such as `Spine/Skeleton` or `Spine/Outline/Skeleton` in your Universal Render Pipeline project. Built-In Render Pipeline shaders are not compatible with URP projects. Please use URP shaders of the [Spine URP Shaders extension UPM package](#URP-Shaders---Extension-UPM-Package) instead. 2. If you're using the correct URP shader `Universal Render Pipeline/Spine/Outline/Skeleton-OutlineOnly`, it renders only the outline because it's a single pass shader. You need to use e.g. the [`RenderExistingMesh`](#RenderExistingMesh) component to re-render your skeleton mesh with this outline-only shader to add the outline behind your skeleton. See the `com.esotericsoftware.spine.URP-shaders/Examples/Outline Shaders URP` example scene included in the [Spine URP Shaders UPM package](#URP-Shaders---Extension-UPM-Package) for a working example setup. > **The Outline shader displays inner outlines around skeleton parts. Why?** ![](/img/spine-runtimes-guide/spine-unity/CommonError-Outline-Inner.png) When your skeleton requires multiple materials, the included outline shaders will incorrectly outline each submesh instead of the whole skeleton. The best solution is to ensure that only a single material is used. This can be achieved by either packing your atlas accordingly, or by [runtime repacking](#Combining-Skins). If this is not possible, you can use e.g. the [`RenderCombinedMesh`](#RenderCombinedMesh) component to re-render your combined skeleton mesh with an outline-only shader to add the outline behind your skeleton. Available outline-only shaders are `Spine/Outline/OutlineOnly-ZWrite` for Built-In Render Pipeline and `Universal Render Pipeline/Spine/Outline/Skeleton-OutlineOnly` for URP. > **How can I replace Materials per Slot?** See [Changing Materials Per Instance](#Changing-Materials-Per-Instance). > **I tried using a normalmap on a skeleton, but it looks wrong. Why?** Please make sure that you have enabled `Advanced - Solve Tangents` at the `SkeletonRenderer` (or `SkeletonAnimation`) component. > **Why does SkeletonGraphic turn bright during fadeout of a UI panel via CanvasGroup alpha?** ![](/img/spine-runtimes-guide/spine-unity/CommonError-CanvasGroupBright.png) See section [SkeletonGraphic Component - CanvasGroup alpha](#CanvasGroup-alpha). > **Why do individual parts of my skeleton show through during alpha fadeout?** ![](/img/spine-runtimes-guide/spine-unity/CommonError-AlphaFadeOut.png) This is a common rendering problem of transparency being applied when overlapping triangles are drawn. See section [Fading a Skeleton In or Out](#Fading-a-Skeleton-In-or-Out) for more details. > **Why does my repacked skin display in the Editor but shows white polygons in the built executable?** ![](/img/spine-runtimes-guide/spine-unity/CommonError-RepackSkin.png) See section [runtime repacking](#Combining-Skins) where you will find an info box that lists the most common causes for this issue. ## Inconsistent behavior > **I'm using UPM packages via git URLs, why does the project behave differently on two machines?** If you are using a git URL that ends with e.g. `#4.2`, this leads to the Unity Package Manager downloading the latest version from the branch `4.2`. When the project is installing required packages for the first time, it downloads the latest required packages once. So a machine that downloads a required package earlier will have an older state of the package than another. You can select the package in the Package Manager and hit the `Update` button to update to the latest version by re-downloading the package. You can avoid this problem by replacing `#4.2` in your git URL with a specific git commit hash like `#5e8e4c21f11603ba1b72c220369d367582783744` to ensure everyone on your project has the same consistent state of the package. See below how to get a commit hash. Unfortunately the short commit hash like `#5e8e4c21` does not seem to work with Unity Package Manager. > **How can I get a git commit hash to use for the Package Manager git URL?** You can get the commit hash by visiting the [github commits page](https://github.com/EsotericSoftware/spine-runtimes/commits/4.2), selecting the desired branch and clicking the copy button (with tooltip "Copy the full SHA") at the right side of the commit to copy the commit hash to the clipboard. ![](/img/spine-runtimes-guide/spine-unity/copy-git-commit-hash.png) ## Performance > **Instantiating a skeleton causes an fps drop or GC memory allocation. How can I improve loading?** 1. If you are exporting your skeleton as `.json`, please consider switching to binary export as `.skel.bytes`. See [Binary Export for Unity](#Binary-Export-for-Unity) for details. 1. If you are instantiating skeleton prefabs during gameplay, consider loading the skeleton at level-load time, and also using a pool of objects instead of instantiating and destroying prefabs. Pre-warm the pool by loading e.g. 10 instances at a non-critical level-load timepoint. Enable and re-position objects instead of instanting new ones, and disable (and `ClearTracks` on `AnimationState`) instead of destroying them. > **I see many draw calls / batches / materials at a single skeleton. Why?** You are likely using multiple atlas pages or Slot blend modes in alternating draw order. See sections [Materials](#Materials) and [Material Switching and Draw Calls](#Material-Switching-and-Draw-Calls) for details. When combining skins or attachments from multiple atlas textures, consider [runtime repacking](#Combining-Skins) to repack attachments to a single atlas texture (at the cost of a single repack operation). > **How can I improve the performance of a skeleton?** 1. Avoid using clipping polygons if possible, consider using Unity's masking features instead. If you need to use clipping attachments, use as few vertices at the clipping polygon as possible. The area of the polygon does not matter, only the vertex count does, so e.g. consider creating a large triangle instead of a two triangles to cover a rectangular area. 1. Use as few mesh deformation keys as possible. 1. Use as few vertices as possible. 1. Remove unnecessary keys, don't key everything. 1. Optimize any other metric displayed in the [Metrics view](/spine-metrics#Metrics-view) in the Spine Editor. 1. Use as few atlas page textures as possible. 1. When requiring multiple materials per skeleton, try optimizing your draw order in Spine to minimize the number of Material switches, or try optimizing atlas texture export so that attachments next to each other in the draw order list are grouped to the same atlas page texture. See sections [Materials](#Materials) and [Material Switching and Draw Calls](#Material-Switching-and-Draw-Calls) for details. 1. Try sharing a single larger atlas texture between multiple skeletons where possible. You can assign a single AtlasAsset at the [SkeletonDataAsset atlas assets array](#Skeleton-Data-Asset) of different skeletons. See [Packing](/spine-texture-packer#Packing) for details. You may consider [packing by folder structure](/spine-texture-packer#Folder-structure) or using the [Command Line Interface](/spine-command-line-interface).