[unity] Fixed error on Unity 2018.3 due to asmdef reference. Resolved by removed reference and using reflection instead.

This commit is contained in:
Harald Csaszar 2026-02-19 23:08:19 +01:00
parent 45f0e32262
commit 8f6018ad0b
2 changed files with 93 additions and 58 deletions

View File

@ -2,20 +2,12 @@
"name": "spine-unity-editor",
"references": [
"spine-csharp",
"spine-unity",
"Unity.2D.Sprite.Editor"
"spine-unity"
],
"optionalUnityReferences": [],
"includePlatforms": [
"Editor"
],
"excludePlatforms": [],
"allowUnsafeCode": false,
"versionDefines": [
{
"name": "com.unity.2d.sprite",
"expression": "1.0.0",
"define": "TEXTUREIMPORTER_SPRITESHEET_OBSOLETE"
}
]
"allowUnsafeCode": false
}

View File

@ -31,18 +31,13 @@
#define GET_ASSET_PATH_USES_ENTITY_ID
#endif
//#if UNITY_2022_2_OR_NEWER
// note: defined by spine-unity-editor.asmdef file when package is actually found
//#define TEXTUREIMPORTER_SPRITESHEET_OBSOLETE
//#endif
#if UNITY_2022_2_OR_NEWER
#define TEXTUREIMPORTER_SPRITESHEET_OBSOLETE
#endif
//#define BAKE_ALL_BUTTON
//#define REGION_BAKING_MESH
#if TEXTUREIMPORTER_SPRITESHEET_OBSOLETE
using UnityEditor.U2D.Sprites;
#endif
using Spine;
using System;
using System.Collections.Generic;
@ -52,11 +47,6 @@ using UnityEngine;
namespace Spine.Unity.Editor {
using Event = UnityEngine.Event;
#if TEXTUREIMPORTER_SPRITESHEET_OBSOLETE
using SpriteDataType = SpriteRect;
#else
using SpriteDataType = SpriteMetaData;
#endif
[CustomEditor(typeof(SpineAtlasAsset)), CanEditMultipleObjects]
public class SpineAtlasAssetInspector : UnityEditor.Editor {
@ -353,36 +343,99 @@ namespace Spine.Unity.Editor {
#endif
TextureImporter t = (TextureImporter)TextureImporter.GetAtPath(texturePath);
t.spriteImportMode = SpriteImportMode.Multiple;
#if TEXTUREIMPORTER_SPRITESHEET_OBSOLETE
SpriteDataProviderFactories factory = new SpriteDataProviderFactories();
factory.Init();
ISpriteEditorDataProvider dataProvider = factory.GetSpriteEditorDataProviderFromObject(t);
dataProvider.InitSpriteEditorDataProvider();
// Read existing sprite rects
SpriteRect[] spriteRects = dataProvider.GetSpriteRects();
List<SpriteRect> sprites = new List<SpriteRect>(spriteRects);
#else
SpriteMetaData[] spriteSheet = t.spritesheet;
List<SpriteMetaData> sprites = new List<SpriteMetaData>(spriteSheet);
#endif
List<AtlasRegion> regions = SpineAtlasAssetInspector.GetRegions(atlas);
int updatedCount = 0;
int addedCount = 0;
#if TEXTUREIMPORTER_SPRITESHEET_OBSOLETE
// Avoid assembly reference to Unity.2D.Sprite.Editor which causes an error on Unity 2018.3.
Type factoryType = null;
foreach (Assembly assembly in AppDomain.CurrentDomain.GetAssemblies()) {
factoryType = assembly.GetType("UnityEditor.U2D.Sprites.SpriteDataProviderFactories");
if (factoryType != null) break;
}
if (factoryType == null) {
Debug.LogWarning("SpriteDataProviderFactories type not found. Sprite slices could not be applied.");
return;
}
// The following reflection code is equivalent to this:
// SpriteDataProviderFactories factory = new SpriteDataProviderFactories();
// factory.Init();
// ISpriteEditorDataProvider dataProvider = factory.GetSpriteEditorDataProviderFromObject(t);
// dataProvider.InitSpriteEditorDataProvider();
//
// SpriteRect[] spriteRects = dataProvider.GetSpriteRects();
// List<SpriteRect> sprites = new List<SpriteRect>(spriteRects);
object factory = Activator.CreateInstance(factoryType);
factoryType.GetMethod("Init").Invoke(factory, null);
object dataProvider = factoryType.GetMethod("GetSpriteEditorDataProviderFromObject").Invoke(factory, new object[] { t });
Type providerInterface = dataProvider.GetType().GetInterface("ISpriteEditorDataProvider");
providerInterface.GetMethod("InitSpriteEditorDataProvider").Invoke(dataProvider, null);
Array spriteRectsArray = (Array)providerInterface.GetMethod("GetSpriteRects").Invoke(dataProvider, null);
Type spriteRectType = spriteRectsArray.GetType().GetElementType();
// Find a base type with a default constructor for creating new instances,
// since the array element type may be a derived type without one.
Type spriteRectBaseType = spriteRectType;
while (spriteRectBaseType != null && spriteRectBaseType != typeof(object)
&& spriteRectBaseType.GetConstructor(Type.EmptyTypes) == null)
spriteRectBaseType = spriteRectBaseType.BaseType;
PropertyInfo nameProperty = spriteRectBaseType.GetProperty("name");
PropertyInfo rectProperty = spriteRectBaseType.GetProperty("rect");
PropertyInfo pivotProperty = spriteRectBaseType.GetProperty("pivot");
List<object> sprites = new List<object>();
for (int i = 0; i < spriteRectsArray.Length; i++)
sprites.Add(spriteRectsArray.GetValue(i));
foreach (AtlasRegion r in regions) {
string pageName = System.IO.Path.GetFileNameWithoutExtension(r.page.name);
string textureName = texture.name;
bool pageMatch = string.Equals(pageName, textureName, StringComparison.Ordinal);
// if (pageMatch) {
// int pw = r.page.width;
// int ph = r.page.height;
// bool mismatchSize = pw != texture.width || pw > t.maxTextureSize || ph != texture.height || ph > t.maxTextureSize;
// if (mismatchSize)
// Debug.LogWarningFormat("Size mismatch found.\nExpected atlas size is {0}x{1}. Texture Import Max Size of texture '{2}'({4}x{5}) is currently set to {3}.", pw, ph, texture.name, t.maxTextureSize, texture.width, texture.height);
// }
int spriteIndex = pageMatch ? sprites.FindIndex(
(s) => string.Equals((string)nameProperty.GetValue(s), r.name, StringComparison.Ordinal)
) : -1;
bool spriteNameMatchExists = spriteIndex >= 0;
if (pageMatch) {
Rect spriteRect = new Rect();
spriteRect.width = r.width;
spriteRect.height = r.height;
spriteRect.x = r.x;
spriteRect.y = r.page.height - spriteRect.height - r.y;
if (spriteNameMatchExists) {
object s = sprites[spriteIndex];
rectProperty.SetValue(s, spriteRect);
updatedCount++;
} else {
object newSpriteRect = Activator.CreateInstance(spriteRectBaseType);
nameProperty.SetValue(newSpriteRect, r.name);
rectProperty.SetValue(newSpriteRect, spriteRect);
pivotProperty.SetValue(newSpriteRect, new Vector2(0.5f, 0.5f));
sprites.Add(newSpriteRect);
addedCount++;
}
}
}
Array resultArray = Array.CreateInstance(spriteRectBaseType, sprites.Count);
for (int i = 0; i < sprites.Count; i++)
resultArray.SetValue(sprites[i], i);
// The following reflection code is equivalent to this:
// dataProvider.SetSpriteRects(spriteRects);
// dataProvider.Apply();
providerInterface.GetMethod("SetSpriteRects").Invoke(dataProvider, new object[] { resultArray });
providerInterface.GetMethod("Apply").Invoke(dataProvider, null);
#else
SpriteMetaData[] spriteSheet = t.spritesheet;
List<SpriteMetaData> sprites = new List<SpriteMetaData>(spriteSheet);
foreach (AtlasRegion r in regions) {
string pageName = System.IO.Path.GetFileNameWithoutExtension(r.page.name);
string textureName = texture.name;
bool pageMatch = string.Equals(pageName, textureName, StringComparison.Ordinal);
int spriteIndex = pageMatch ? sprites.FindIndex(
(s) => string.Equals(s.name, r.name, StringComparison.Ordinal)
@ -391,24 +444,18 @@ namespace Spine.Unity.Editor {
if (pageMatch) {
Rect spriteRect = new Rect();
if (r.degrees == 90) {
spriteRect.width = r.height;
spriteRect.height = r.width;
} else {
spriteRect.width = r.width;
spriteRect.height = r.height;
}
spriteRect.width = r.width;
spriteRect.height = r.height;
spriteRect.x = r.x;
spriteRect.y = r.page.height - spriteRect.height - r.y;
if (spriteNameMatchExists) {
SpriteDataType s = sprites[spriteIndex];
SpriteMetaData s = sprites[spriteIndex];
s.rect = spriteRect;
sprites[spriteIndex] = s;
updatedCount++;
} else {
sprites.Add(new SpriteDataType {
sprites.Add(new SpriteMetaData {
name = r.name,
pivot = new Vector2(0.5f, 0.5f),
rect = spriteRect
@ -416,12 +463,8 @@ namespace Spine.Unity.Editor {
addedCount++;
}
}
}
#if TEXTUREIMPORTER_SPRITESHEET_OBSOLETE
dataProvider.SetSpriteRects(spriteRects);
dataProvider.Apply();
#else
t.spritesheet = sprites.ToArray();
#endif
EditorUtility.SetDirty(t);