[unity] Removed support for long abandoned thirdparty asset "2D Toolkit" (TK2D) by Unikron Software.

This commit is contained in:
Harald Csaszar 2026-03-11 21:16:03 +01:00
parent ff90da5848
commit 054f0139a8
12 changed files with 1 additions and 375 deletions

View File

@ -353,6 +353,7 @@
- Removed `attachment.GetRemappedClone()` extension methods. Replace `attachment.GetRemappedClone(parameters)` with `attachment.Copy(); attachment.SetRegion(parameters)`. Removed `AttachmentCloneExtensions` class, `SetRegion` methods are now in `AttachmentRegionExtensions`.
- Renamed `ToAtlasRegionPMAClone` to `ToAtlasRegionWithNewPMATexture`.
- Renamed `ToRegionAttachmentPMAClone` to `ToRegionAttachmentWithNewPMATexture`.
- Removed support for long abandoned thirdparty asset "2D Toolkit" (TK2D) by Unikron Software.
- **Changes of default values**
- Changed default atlas texture workflow from PMA to straight alpha textures. This move was done because straight alpha textures are compatible with both Gamma and Linear color space, with the latter being the default for quite some time now in Unity. Note that `PMA Vertex Color` is unaffected and shall be enabled as usual to allow for single-pass additive rendering.

View File

@ -56,9 +56,6 @@ namespace Spine.Unity.Editor {
SerializedProperty atlasAssets, skeletonJSON, scale, fromAnimation, toAnimation, duration, defaultMix;
SerializedProperty skeletonDataModifiers;
SerializedProperty blendModeMaterials;
#if SPINE_TK2D
SerializedProperty spriteCollection;
#endif
#if SPINE_SKELETON_MECANIM
static bool isMecanimExpanded = false;
@ -121,13 +118,8 @@ namespace Spine.Unity.Editor {
controller = serializedObject.FindProperty("controller");
#endif
#if SPINE_TK2D
if (newAtlasAssets) atlasAssets.isExpanded = false;
spriteCollection = serializedObject.FindProperty("spriteCollection");
#else
// Analysis disable once ConvertIfToOrExpression
if (newAtlasAssets) atlasAssets.isExpanded = true;
#endif
// This handles the case where the managed editor assembly is unloaded before recompilation when code changes.
AppDomain.CurrentDomain.DomainUnload -= OnDomainUnload;
@ -247,15 +239,11 @@ namespace Spine.Unity.Editor {
DrawUnityTools();
} else {
#if !SPINE_TK2D
// Draw Reimport Button
using (new EditorGUI.DisabledGroupScope(skeletonJSON.objectReferenceValue == null)) {
if (GUILayout.Button(SpineInspectorUtility.TempContent("Attempt Reimport", Icons.warning)))
DoReimport();
}
#else
EditorGUILayout.HelpBox("Couldn't load SkeletonData.", MessageType.Error);
#endif
DrawWarningList();
}
@ -350,15 +338,7 @@ namespace Spine.Unity.Editor {
// Texture source field.
using (new SpineInspectorUtility.BoxScope()) {
EditorGUILayout.LabelField("Atlas", EditorStyles.boldLabel);
#if !SPINE_TK2D
EditorGUILayout.PropertyField(atlasAssets, true);
#else
using (new EditorGUI.DisabledGroupScope(spriteCollection.objectReferenceValue != null)) {
EditorGUILayout.PropertyField(atlasAssets, true);
}
EditorGUILayout.LabelField("spine-tk2d", EditorStyles.boldLabel);
EditorGUILayout.PropertyField(spriteCollection, true);
#endif
}
// Mix settings.
@ -430,15 +410,7 @@ namespace Spine.Unity.Editor {
EditorGUILayout.LabelField("Atlas", EditorStyles.boldLabel);
using (var changeCheck = new EditorGUI.ChangeCheckScope()) {
#if !SPINE_TK2D
EditorGUILayout.PropertyField(atlasAssets, true);
#else
using (new EditorGUI.DisabledGroupScope(spriteCollection.objectReferenceValue != null)) {
EditorGUILayout.PropertyField(atlasAssets, true);
}
EditorGUILayout.LabelField("spine-tk2d", EditorStyles.boldLabel);
EditorGUILayout.PropertyField(spriteCollection, true);
#endif
if (atlasAssets.arraySize == 0)
EditorGUILayout.HelpBox("AtlasAssets array is empty. Skeleton's attachments will load without being mapped to images.", MessageType.Info);
@ -703,14 +675,8 @@ namespace Spine.Unity.Editor {
else
warnings.Add("Skeleton data file is not a valid Spine JSON or binary file.");
} else {
#if SPINE_TK2D
bool searchForSpineAtlasAssets = (compatibilityProblemInfo == null);
bool isSpriteCollectionNull = spriteCollection.objectReferenceValue == null;
if (!isSpriteCollectionNull) searchForSpineAtlasAssets = false;
#else
// Analysis disable once ConvertToConstant.Local
bool searchForSpineAtlasAssets = (compatibilityProblemInfo == null);
#endif
if (searchForSpineAtlasAssets) {
bool detectedNullAtlasEntry = false;
@ -744,10 +710,6 @@ namespace Spine.Unity.Editor {
}
}
#if SPINE_TK2D
if (missingPaths.Count > 0)
warnings.Add("Missing regions. SkeletonData asset requires tk2DSpriteCollectionData or Spine AtlasAssets.");
#endif
}
if (missingPaths != null) {

View File

@ -434,9 +434,6 @@ namespace Spine.Unity.Editor {
string dir = Path.GetDirectoryName(skeletonPath).Replace('\\', '/');
#if SPINE_TK2D
IngestSpineProject(loadedAsset, null);
#else
string skeletonName = Path.GetFileNameWithoutExtension(skeletonPath);
List<string> requiredPaths = GetRequiredAtlasRegions(skeletonPath);
@ -470,7 +467,6 @@ namespace Spine.Unity.Editor {
if (abortSkeletonImport)
break;
#endif
}
if (atlasPaths.Count > 0 || imagePaths.Count > 0 || skeletonPaths.Count > 0) {
@ -1123,32 +1119,6 @@ namespace Spine.Unity.Editor {
internal static SkeletonDataAsset IngestSpineProject (TextAsset spineJson, params AtlasAssetBase[] atlasAssets) {
string filePath = GetSkeletonDataAssetFilePath(spineJson);
#if SPINE_TK2D
if (spineJson != null) {
SkeletonDataAsset skeletonDataAsset = (SkeletonDataAsset)AssetDatabase.LoadAssetAtPath(filePath, typeof(SkeletonDataAsset));
if (skeletonDataAsset == null) {
skeletonDataAsset = SkeletonDataAsset.CreateInstance<SkeletonDataAsset>();
skeletonDataAsset.skeletonJSON = spineJson;
skeletonDataAsset.fromAnimation = new string[0];
skeletonDataAsset.toAnimation = new string[0];
skeletonDataAsset.duration = new float[0];
skeletonDataAsset.defaultMix = SpineEditorUtilities.Preferences.defaultMix;
skeletonDataAsset.scale = SpineEditorUtilities.Preferences.defaultScale;
AssetDatabase.CreateAsset(skeletonDataAsset, filePath);
AssetDatabase.SaveAssets();
} else {
SpineEditorUtilities.ClearSkeletonDataAsset(targetSkeletonDataAsset);
skeletonDataAsset.GetSkeletonData(true);
}
return skeletonDataAsset;
} else {
EditorUtility.DisplayDialog("Error!", "Tried to ingest null Spine data.", "OK");
return null;
}
#else
if (spineJson != null && atlasAssets != null) {
SkeletonDataAsset skeletonDataAsset = (SkeletonDataAsset)AssetDatabase.LoadAssetAtPath(filePath, typeof(SkeletonDataAsset));
if (skeletonDataAsset == null) {
@ -1175,7 +1145,6 @@ namespace Spine.Unity.Editor {
EditorUtility.DisplayDialog("Error!", "Must specify both Spine JSON and AtlasAsset array", "OK");
return null;
}
#endif
}
#endregion

View File

@ -57,34 +57,6 @@ using UnityEditor;
using UnityEngine;
namespace Spine.Unity.Editor {
public partial class SpineEditorUtilities {
public static class SpineTK2DEditorUtility {
const string SPINE_TK2D_DEFINE = "SPINE_TK2D";
internal static bool IsTK2DInstalled () {
return (Shader.Find("tk2d/SolidVertexColor") != null ||
Shader.Find("tk2d/AdditiveVertexColor") != null);
}
internal static bool IsTK2DAllowed {
get {
return false; // replace with "return true;" to allow TK2D support
}
}
internal static void EnableTK2D () {
if (!IsTK2DAllowed)
return;
SpineBuildEnvUtility.DisableSpineAsmdefFiles();
SpineBuildEnvUtility.EnableBuildDefine(SPINE_TK2D_DEFINE);
}
internal static void DisableTK2D () {
SpineBuildEnvUtility.EnableSpineAsmdefFiles();
SpineBuildEnvUtility.DisableBuildDefine(SPINE_TK2D_DEFINE);
}
}
}
public static class SpineBuildEnvUtility {
public const string SPINE_ALLOW_UNSAFE_CODE = "SPINE_ALLOW_UNSAFE";

View File

@ -442,30 +442,6 @@ namespace Spine.Unity.Editor {
}
}
#if SPINE_TK2D_DEFINE
bool isTK2DDefineSet = true;
#else
bool isTK2DDefineSet = false;
#endif
bool isTK2DAllowed = SpineTK2DEditorUtility.IsTK2DAllowed;
if (SpineTK2DEditorUtility.IsTK2DInstalled() || isTK2DDefineSet) {
GUILayout.Space(20);
EditorGUILayout.LabelField("3rd Party Settings", EditorStyles.boldLabel);
using (new GUILayout.HorizontalScope()) {
EditorGUILayout.PrefixLabel("Define TK2D");
if (isTK2DAllowed && GUILayout.Button("Enable", GUILayout.Width(64)))
SpineTK2DEditorUtility.EnableTK2D();
if (GUILayout.Button("Disable", GUILayout.Width(64)))
SpineTK2DEditorUtility.DisableTK2D();
}
#if !SPINE_TK2D_DEFINE
if (!isTK2DAllowed) {
EditorGUILayout.LabelField("To allow TK2D support, please modify line 67 in", EditorStyles.boldLabel);
EditorGUILayout.LabelField("Spine/Editor/spine-unity/Editor/Util./BuildSettings.cs", EditorStyles.boldLabel);
}
#endif
}
GUILayout.Space(20);
EditorGUILayout.LabelField("Automatic Component Upgrade", EditorStyles.boldLabel);
#if SPINE_AUTO_UPGRADE_COMPONENTS_OFF

View File

@ -84,11 +84,7 @@ namespace Spine.Unity.Editor {
public const string SPINE_SETTINGS_ASSET_PATH = "Assets/Editor/SpineSettings.asset";
#if SPINE_TK2D
internal const float DEFAULT_DEFAULT_SCALE = 1f;
#else
internal const float DEFAULT_DEFAULT_SCALE = 0.01f;
#endif
public float defaultScale = DEFAULT_DEFAULT_SCALE;
internal const float DEFAULT_DEFAULT_MIX = 0.2f;
@ -485,30 +481,6 @@ namespace Spine.Unity.Editor {
}
}
#if SPINE_TK2D_DEFINE
bool isTK2DDefineSet = true;
#else
bool isTK2DDefineSet = false;
#endif
bool isTK2DAllowed = SpineEditorUtilities.SpineTK2DEditorUtility.IsTK2DAllowed;
if (SpineEditorUtilities.SpineTK2DEditorUtility.IsTK2DInstalled() || isTK2DDefineSet) {
GUILayout.Space(20);
EditorGUILayout.LabelField("3rd Party Settings", EditorStyles.boldLabel);
using (new GUILayout.HorizontalScope()) {
EditorGUILayout.PrefixLabel("Define TK2D");
if (GUILayout.Button("Disable", GUILayout.Width(64)))
SpineEditorUtilities.SpineTK2DEditorUtility.DisableTK2D();
if (isTK2DAllowed && GUILayout.Button("Enable", GUILayout.Width(64)))
SpineEditorUtilities.SpineTK2DEditorUtility.EnableTK2D();
}
#if !SPINE_TK2D_DEFINE
if (!isTK2DAllowed) {
EditorGUILayout.LabelField("To allow TK2D support, please modify line 67 in", EditorStyles.boldLabel);
EditorGUILayout.LabelField("Spine/Editor/spine-unity/Editor/Util./BuildSettings.cs", EditorStyles.boldLabel);
}
#endif
}
GUILayout.Space(20);
EditorGUILayout.LabelField("Threading Defaults", EditorStyles.boldLabel);
{

View File

@ -66,12 +66,7 @@ namespace Spine.Unity {
#region Inspector
public AtlasAssetBase[] atlasAssets = new AtlasAssetBase[0];
#if SPINE_TK2D
public tk2dSpriteCollectionData spriteCollection;
public float scale = 1f;
#else
public float scale = 0.01f;
#endif
public TextAsset skeletonJSON;
public bool isUpgradingBlendModeMaterials = false;
@ -173,17 +168,10 @@ namespace Spine.Unity {
// Clear();
// return null;
// }
// #if !SPINE_TK2D
// if (atlasAssets.Length == 0) {
// Clear();
// return null;
// }
// #else
// if (atlasAssets.Length == 0 && spriteCollection == null) {
// Clear();
// return null;
// }
// #endif
if (skeletonData != null)
return skeletonData;
@ -192,23 +180,8 @@ namespace Spine.Unity {
float skeletonDataScale;
Atlas[] atlasArray = this.GetAtlasArray();
#if !SPINE_TK2D
attachmentLoader = (atlasArray.Length == 0) ? (AttachmentLoader)new RegionlessAttachmentLoader() : (AttachmentLoader)new AtlasAttachmentLoader(atlasArray);
skeletonDataScale = scale;
#else
if (spriteCollection != null) {
attachmentLoader = new Spine.Unity.TK2D.SpriteCollectionAttachmentLoader(spriteCollection);
skeletonDataScale = (1.0f / (spriteCollection.invOrthoSize * spriteCollection.halfTargetHeight) * scale);
} else {
if (atlasArray.Length == 0) {
Reset();
if (!quiet) Debug.LogError("Atlas not set for SkeletonData asset: " + name, this);
return null;
}
attachmentLoader = new AtlasAttachmentLoader(atlasArray);
skeletonDataScale = scale;
}
#endif
bool hasBinaryExtension = skeletonJSON.name.ToLower().Contains(".skel");
SkeletonData loadedSkeletonData = null;

View File

@ -282,13 +282,8 @@ namespace Spine.Unity {
totalRawVertexCount += attachmentVertexCount;
}
#if !SPINE_TK2D
if (material == null && rendererObject != null)
current.material = (Material)((AtlasRegion)rendererObject).page.rendererObject;
#else
if (material == null && rendererObject != null)
current.material = (rendererObject is Material) ? (Material)rendererObject : (Material)((AtlasRegion)rendererObject).page.rendererObject;
#endif
instructionOutput.hasActiveClipping = skeletonHasClipping;
instructionOutput.rawVertexCount = totalRawVertexCount;
@ -309,9 +304,6 @@ namespace Spine.Unity {
public static bool RequiresMultipleSubmeshesByDrawOrder (Skeleton skeleton) {
#if SPINE_TK2D
return false;
#endif
ExposedList<Slot> drawOrder = skeleton.DrawOrder;
int drawOrderCount = drawOrder.Count;
Slot[] drawOrderItems = drawOrder.Items;
@ -366,9 +358,7 @@ namespace Spine.Unity {
preActiveClippingSlotSource = -1
};
#if !SPINE_TK2D
bool isCustomSlotMaterialsPopulated = customSlotMaterials != null && customSlotMaterials.Count > 0;
#endif
int separatorCount = separatorSlots == null ? 0 : separatorSlots.Count;
bool hasSeparators = separatorCount > 0;
@ -467,7 +457,6 @@ namespace Spine.Unity {
#endif
}
} else {
#if !SPINE_TK2D
Material material;
if (isCustomSlotMaterialsPopulated) {
if (!customSlotMaterials.TryGetValue(slot, out material))
@ -475,10 +464,6 @@ namespace Spine.Unity {
} else {
material = (Material)((AtlasRegion)region).page.rendererObject;
}
#else
// An AtlasRegion in plain spine-unity, spine-TK2D hooks into TK2D's system. eventual source of Material object.
Material material = (region is Material) ? (Material)region : (Material)((AtlasRegion)region).page.rendererObject;
#endif
#if !SPINE_TRIANGLECHECK
if (current.forceSeparate || !System.Object.ReferenceEquals(current.material, material)) { // Material changed. Add the previous submesh.

View File

@ -1,9 +0,0 @@
fileFormatVersion: 2
guid: e70d3026a0242e5418232b2015be29f7
folderAsset: yes
timeCreated: 1456509301
licenseType: Free
DefaultImporter:
userData:
assetBundleName:
assetBundleVariant:

View File

@ -1,163 +0,0 @@
/******************************************************************************
* Spine Runtimes License Agreement
* Last updated April 5, 2025. Replaces all prior versions.
*
* Copyright (c) 2013-2026, Esoteric Software LLC
*
* Integration of the Spine Runtimes into software or otherwise creating
* derivative works of the Spine Runtimes is permitted under the terms and
* conditions of Section 2 of the Spine Editor License Agreement:
* http://esotericsoftware.com/spine-editor-license
*
* Otherwise, it is permitted to integrate the Spine Runtimes into software
* or otherwise create derivative works of the Spine Runtimes (collectively,
* "Products"), provided that each user of the Products must obtain their own
* Spine Editor license and redistribution of the Products in any form must
* include this license and copyright notice.
*
* THE SPINE RUNTIMES ARE PROVIDED BY ESOTERIC SOFTWARE LLC "AS IS" AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL ESOTERIC SOFTWARE LLC BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES,
* BUSINESS INTERRUPTION, OR LOSS OF USE, DATA, OR PROFITS) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THE SPINE RUNTIMES, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*****************************************************************************/
#if SPINE_TK2D
using Spine;
using System;
using UnityEngine;
// MITCH: handle TPackerCW flip mode (probably not swap uv horizontaly)
namespace Spine.Unity.TK2D {
public class SpriteCollectionAttachmentLoader : AttachmentLoader {
private tk2dSpriteCollectionData sprites;
private float u, v, u2, v2;
private bool regionRotated;
private float regionOriginalWidth, regionOriginalHeight;
private float regionWidth, regionHeight;
private float regionOffsetX, regionOffsetY;
private Material material;
public SpriteCollectionAttachmentLoader (tk2dSpriteCollectionData sprites) {
if (sprites == null)
throw new ArgumentNullException("sprites cannot be null.");
this.sprites = sprites;
}
private AtlasRegion ProcessSpriteDefinition (String name) {
// Strip folder names.
int index = name.LastIndexOfAny(new char[] { '/', '\\' });
if (index != -1)
name = name.Substring(index + 1);
tk2dSpriteDefinition def = sprites.inst.GetSpriteDefinition(name);
if (def == null) {
Debug.Log("Sprite not found in atlas: " + name, sprites);
throw new Exception("Sprite not found in atlas: " + name);
}
if (def.complexGeometry)
throw new NotImplementedException("Complex geometry is not supported: " + name);
if (def.flipped == tk2dSpriteDefinition.FlipMode.TPackerCW)
throw new NotImplementedException("Only 2D Toolkit atlases are supported: " + name);
Vector2 minTexCoords = Vector2.one, maxTexCoords = Vector2.zero;
for (int i = 0; i < def.uvs.Length; ++i) {
Vector2 uv = def.uvs[i];
minTexCoords = Vector2.Min(minTexCoords, uv);
maxTexCoords = Vector2.Max(maxTexCoords, uv);
}
regionRotated = def.flipped == tk2dSpriteDefinition.FlipMode.Tk2d;
if (regionRotated) {
float temp = minTexCoords.x;
minTexCoords.x = maxTexCoords.x;
maxTexCoords.x = temp;
}
u = minTexCoords.x;
v = maxTexCoords.y;
u2 = maxTexCoords.x;
v2 = minTexCoords.y;
regionOriginalWidth = (int)(def.untrimmedBoundsData[1].x / def.texelSize.x);
regionOriginalHeight = (int)(def.untrimmedBoundsData[1].y / def.texelSize.y);
regionWidth = (int)(def.boundsData[1].x / def.texelSize.x);
regionHeight = (int)(def.boundsData[1].y / def.texelSize.y);
if (regionRotated) {
float tempSwap = regionWidth;
regionWidth = regionHeight;
regionHeight = tempSwap;
}
float x0 = def.untrimmedBoundsData[0].x - def.untrimmedBoundsData[1].x / 2;
float x1 = def.boundsData[0].x - def.boundsData[1].x / 2;
regionOffsetX = (int)((x1 - x0) / def.texelSize.x);
float y0 = def.untrimmedBoundsData[0].y - def.untrimmedBoundsData[1].y / 2;
float y1 = def.boundsData[0].y - def.boundsData[1].y / 2;
regionOffsetY = (int)((y1 - y0) / def.texelSize.y);
material = def.materialInst;
AtlasRegion region = new AtlasRegion();
region.name = name;
AtlasPage page = new AtlasPage();
page.rendererObject = material;
region.page = page;
region.u = u;
region.v = v;
region.u2 = u2;
region.v2 = v2;
region.rotate = regionRotated;
region.degrees = regionRotated ? 90 : 0;
region.originalWidth = (int)regionOriginalWidth;
region.originalHeight = (int)regionOriginalHeight;
region.width = (int)regionWidth;
region.height = (int)regionHeight;
region.offsetX = regionOffsetX;
region.offsetY = regionOffsetY;
return region;
}
private void LoadSequence (string name, string basePath, Sequence sequence) {
TextureRegion[] regions = sequence.Regions;
for (int i = 0, n = regions.Length; i < n; i++) {
string path = sequence.GetPath(basePath, i);
regions[i] = ProcessSpriteDefinition(path);
if (regions[i] == null) throw new ArgumentException(string.Format("Region not found in atlas: {0} (region attachment: {1})", path, name));
}
}
public RegionAttachment NewRegionAttachment (Skin skin, String name, String path, Sequence sequence) {
LoadSequence(name, path, sequence);
return new RegionAttachment(name, sequence);
}
public MeshAttachment NewMeshAttachment (Skin skin, String name, String path, Sequence sequence) {
LoadSequence(name, path, sequence);
return new MeshAttachment(name, sequence);
}
public BoundingBoxAttachment NewBoundingBoxAttachment (Skin skin, String name) {
return new BoundingBoxAttachment(name);
}
public PathAttachment NewPathAttachment (Skin skin, string name) {
return new PathAttachment(name);
}
public PointAttachment NewPointAttachment (Skin skin, string name) {
return new PointAttachment(name);
}
public ClippingAttachment NewClippingAttachment (Skin skin, string name) {
return new ClippingAttachment(name);
}
}
}
#endif

View File

@ -1,8 +0,0 @@
fileFormatVersion: 2
guid: 03238e4a73953c045a6cb289162532f3
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:

View File

@ -237,11 +237,7 @@ namespace Spine.Unity {
if (rendererObject == null)
return null;
#if SPINE_TK2D
return (rendererObject.GetType() == typeof(Material)) ? (Material)rendererObject : (Material)((AtlasRegion)rendererObject).page.rendererObject;
#else
return (Material)((AtlasRegion)rendererObject).page.rendererObject;
#endif
}
/// <summary>Fills a Vector2 buffer with local vertices.</summary>