|
@@ -43,6 +43,10 @@
|
|
#define NEW_PREFERENCES_SETTINGS_PROVIDER
|
|
#define NEW_PREFERENCES_SETTINGS_PROVIDER
|
|
#endif
|
|
#endif
|
|
|
|
|
|
|
|
+#if UNITY_2018_2_OR_NEWER
|
|
|
|
+#define EXPOSES_SPRITE_ATLAS_UTILITIES
|
|
|
|
+#endif
|
|
|
|
+
|
|
using UnityEngine;
|
|
using UnityEngine;
|
|
using UnityEditor;
|
|
using UnityEditor;
|
|
using System.Collections.Generic;
|
|
using System.Collections.Generic;
|
|
@@ -60,6 +64,7 @@ namespace Spine.Unity.Editor {
|
|
|
|
|
|
public const string SkeletonDataSuffix = "_SkeletonData";
|
|
public const string SkeletonDataSuffix = "_SkeletonData";
|
|
public const string AtlasSuffix = "_Atlas";
|
|
public const string AtlasSuffix = "_Atlas";
|
|
|
|
+ public const string SpriteAtlasSuffix = "_SpriteAtlas";
|
|
|
|
|
|
/// HACK: This list keeps the asset reference temporarily during importing.
|
|
/// HACK: This list keeps the asset reference temporarily during importing.
|
|
///
|
|
///
|
|
@@ -251,6 +256,7 @@ namespace Spine.Unity.Editor {
|
|
bool reimport = false) {
|
|
bool reimport = false) {
|
|
|
|
|
|
var atlasPaths = new List<string>();
|
|
var atlasPaths = new List<string>();
|
|
|
|
+ var spriteAtlasPaths = new List<string>();
|
|
var imagePaths = new List<string>();
|
|
var imagePaths = new List<string>();
|
|
var skeletonPaths = new List<PathAndProblemInfo>();
|
|
var skeletonPaths = new List<PathAndProblemInfo>();
|
|
CompatibilityProblemInfo compatibilityProblemInfo = null;
|
|
CompatibilityProblemInfo compatibilityProblemInfo = null;
|
|
@@ -267,6 +273,9 @@ namespace Spine.Unity.Editor {
|
|
if (str.EndsWith(".atlas.txt", System.StringComparison.Ordinal))
|
|
if (str.EndsWith(".atlas.txt", System.StringComparison.Ordinal))
|
|
atlasPaths.Add(str);
|
|
atlasPaths.Add(str);
|
|
break;
|
|
break;
|
|
|
|
+ case ".spriteatlas":
|
|
|
|
+ spriteAtlasPaths.Add(str);
|
|
|
|
+ break;
|
|
case ".png":
|
|
case ".png":
|
|
case ".jpg":
|
|
case ".jpg":
|
|
imagePaths.Add(str);
|
|
imagePaths.Add(str);
|
|
@@ -294,7 +303,6 @@ namespace Spine.Unity.Editor {
|
|
AtlasAssetBase atlas = IngestSpineAtlas(atlasText, texturesWithoutMetaFile);
|
|
AtlasAssetBase atlas = IngestSpineAtlas(atlasText, texturesWithoutMetaFile);
|
|
atlases.Add(atlas);
|
|
atlases.Add(atlas);
|
|
}
|
|
}
|
|
-
|
|
|
|
AddDependentSkeletonIfAtlasChanged(skeletonPaths, atlasPaths);
|
|
AddDependentSkeletonIfAtlasChanged(skeletonPaths, atlasPaths);
|
|
|
|
|
|
// Import skeletons and match them with atlases.
|
|
// Import skeletons and match them with atlases.
|
|
@@ -575,6 +583,164 @@ namespace Spine.Unity.Editor {
|
|
return (AtlasAssetBase)AssetDatabase.LoadAssetAtPath(atlasPath, typeof(AtlasAssetBase));
|
|
return (AtlasAssetBase)AssetDatabase.LoadAssetAtPath(atlasPath, typeof(AtlasAssetBase));
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+ public static bool SpriteAtlasSettingsNeedAdjustment (UnityEngine.U2D.SpriteAtlas spriteAtlas) {
|
|
|
|
+ #if EXPOSES_SPRITE_ATLAS_UTILITIES
|
|
|
|
+ UnityEditor.U2D.SpriteAtlasPackingSettings packingSettings = UnityEditor.U2D.SpriteAtlasExtensions.GetPackingSettings(spriteAtlas);
|
|
|
|
+ UnityEditor.U2D.SpriteAtlasTextureSettings textureSettings = UnityEditor.U2D.SpriteAtlasExtensions.GetTextureSettings(spriteAtlas);
|
|
|
|
+
|
|
|
|
+ bool areSettingsAsDesired =
|
|
|
|
+ packingSettings.enableRotation == true &&
|
|
|
|
+ packingSettings.enableTightPacking == false &&
|
|
|
|
+ textureSettings.readable == true &&
|
|
|
|
+ textureSettings.generateMipMaps == false;
|
|
|
|
+ // note: platformSettings.textureCompression is always providing "Compressed", so we have to skip it.
|
|
|
|
+ return !areSettingsAsDesired;
|
|
|
|
+ #else
|
|
|
|
+ return false;
|
|
|
|
+ #endif
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ public static bool AdjustSpriteAtlasSettings (UnityEngine.U2D.SpriteAtlas spriteAtlas) {
|
|
|
|
+ #if EXPOSES_SPRITE_ATLAS_UTILITIES
|
|
|
|
+ UnityEditor.U2D.SpriteAtlasPackingSettings packingSettings = UnityEditor.U2D.SpriteAtlasExtensions.GetPackingSettings(spriteAtlas);
|
|
|
|
+ UnityEditor.U2D.SpriteAtlasTextureSettings textureSettings = UnityEditor.U2D.SpriteAtlasExtensions.GetTextureSettings(spriteAtlas);
|
|
|
|
+
|
|
|
|
+ packingSettings.enableRotation = true;
|
|
|
|
+ packingSettings.enableTightPacking = false;
|
|
|
|
+ UnityEditor.U2D.SpriteAtlasExtensions.SetPackingSettings(spriteAtlas, packingSettings);
|
|
|
|
+
|
|
|
|
+ textureSettings.readable = true;
|
|
|
|
+ textureSettings.generateMipMaps = false;
|
|
|
|
+ UnityEditor.U2D.SpriteAtlasExtensions.SetTextureSettings(spriteAtlas, textureSettings);
|
|
|
|
+
|
|
|
|
+ TextureImporterPlatformSettings platformSettings = new TextureImporterPlatformSettings();
|
|
|
|
+ platformSettings.textureCompression = TextureImporterCompression.Uncompressed;
|
|
|
|
+ platformSettings.crunchedCompression = false;
|
|
|
|
+ UnityEditor.U2D.SpriteAtlasExtensions.SetPlatformSettings(spriteAtlas, platformSettings);
|
|
|
|
+
|
|
|
|
+ string atlasPath = AssetDatabase.GetAssetPath(spriteAtlas);
|
|
|
|
+ Debug.Log(string.Format("Adjusted unsuitable SpriteAtlas settings '{0}'", atlasPath), spriteAtlas);
|
|
|
|
+ return false;
|
|
|
|
+ #else
|
|
|
|
+ return true;
|
|
|
|
+ #endif
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ public static bool GeneratePngFromSpriteAtlas (UnityEngine.U2D.SpriteAtlas spriteAtlas, out string texturePath) {
|
|
|
|
+ texturePath = System.IO.Path.ChangeExtension(AssetDatabase.GetAssetPath(spriteAtlas), ".png");
|
|
|
|
+ if (spriteAtlas == null)
|
|
|
|
+ return false;
|
|
|
|
+
|
|
|
|
+ Texture2D tempTexture = SpineSpriteAtlasAsset.AccessPackedTextureEditor(spriteAtlas);
|
|
|
|
+ if (tempTexture == null)
|
|
|
|
+ return false;
|
|
|
|
+
|
|
|
|
+ byte[] bytes = null;
|
|
|
|
+ try {
|
|
|
|
+ bytes = tempTexture.EncodeToPNG();
|
|
|
|
+ }
|
|
|
|
+ catch (System.Exception) {
|
|
|
|
+ // handled below
|
|
|
|
+ }
|
|
|
|
+ if (bytes == null || bytes.Length == 0) {
|
|
|
|
+ Debug.LogError("Could not read Compressed SpriteAtlas. Please enable 'Read/Write Enabled' and ensure 'Compression' is set to 'None' in Inspector.", spriteAtlas);
|
|
|
|
+ return false;
|
|
|
|
+ }
|
|
|
|
+ System.IO.File.WriteAllBytes(texturePath, bytes);
|
|
|
|
+ AssetDatabase.SaveAssets();
|
|
|
|
+ AssetDatabase.Refresh();
|
|
|
|
+ return System.IO.File.Exists(texturePath);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ public static AtlasAssetBase IngestSpriteAtlas (UnityEngine.U2D.SpriteAtlas spriteAtlas, List<string> texturesWithoutMetaFile) {
|
|
|
|
+ if (spriteAtlas == null) {
|
|
|
|
+ Debug.LogWarning("SpriteAtlas source cannot be null!");
|
|
|
|
+ return null;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ if (SpriteAtlasSettingsNeedAdjustment(spriteAtlas)) {
|
|
|
|
+ // settings need to be adjusted via the 'Spine SpriteAtlas Import' window if you want to use it as a Spine atlas.
|
|
|
|
+ return null;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ Texture2D texture = null;
|
|
|
|
+ { // only one page file
|
|
|
|
+ string texturePath;
|
|
|
|
+ GeneratePngFromSpriteAtlas(spriteAtlas, out texturePath);
|
|
|
|
+ texture = AssetDatabase.LoadAssetAtPath<Texture2D>(texturePath);
|
|
|
|
+ if (texture == null && System.IO.File.Exists(texturePath)) {
|
|
|
|
+ EditorUtility.SetDirty(spriteAtlas);
|
|
|
|
+ return null; // next iteration will load the texture as well.
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ string primaryName = spriteAtlas.name;
|
|
|
|
+ string assetPath = Path.GetDirectoryName(AssetDatabase.GetAssetPath(spriteAtlas)).Replace('\\', '/');
|
|
|
|
+
|
|
|
|
+ string atlasPath = assetPath + "/" + primaryName + SpriteAtlasSuffix + ".asset";
|
|
|
|
+
|
|
|
|
+ SpineSpriteAtlasAsset atlasAsset = AssetDatabase.LoadAssetAtPath<SpineSpriteAtlasAsset>(atlasPath);
|
|
|
|
+
|
|
|
|
+ List<Material> vestigialMaterials = new List<Material>();
|
|
|
|
+
|
|
|
|
+ if (atlasAsset == null)
|
|
|
|
+ atlasAsset = SpineSpriteAtlasAsset.CreateInstance<SpineSpriteAtlasAsset>();
|
|
|
|
+ else {
|
|
|
|
+ foreach (Material m in atlasAsset.materials)
|
|
|
|
+ vestigialMaterials.Add(m);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ protectFromStackGarbageCollection.Add(atlasAsset);
|
|
|
|
+ atlasAsset.spriteAtlasFile = spriteAtlas;
|
|
|
|
+
|
|
|
|
+ int pagesCount = 1;
|
|
|
|
+ var populatingMaterials = new List<Material>(pagesCount);
|
|
|
|
+
|
|
|
|
+ {
|
|
|
|
+ string pageName = "SpriteAtlas";
|
|
|
|
+
|
|
|
|
+ string materialPath = assetPath + "/" + primaryName + "_" + pageName + ".mat";
|
|
|
|
+ Material mat = AssetDatabase.LoadAssetAtPath<Material>(materialPath);
|
|
|
|
+
|
|
|
|
+ if (mat == null) {
|
|
|
|
+ mat = new Material(Shader.Find(SpineEditorUtilities.Preferences.defaultShader));
|
|
|
|
+ ApplyPMAOrStraightAlphaSettings(mat, SpineEditorUtilities.Preferences.textureSettingsReference);
|
|
|
|
+ AssetDatabase.CreateAsset(mat, materialPath);
|
|
|
|
+ }
|
|
|
|
+ else {
|
|
|
|
+ vestigialMaterials.Remove(mat);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ if (texture != null)
|
|
|
|
+ mat.mainTexture = texture;
|
|
|
|
+
|
|
|
|
+ EditorUtility.SetDirty(mat);
|
|
|
|
+ // note: don't call AssetDatabase.SaveAssets() since this would trigger OnPostprocessAllAssets() every time unnecessarily.
|
|
|
|
+ populatingMaterials.Add(mat); //atlasAsset.materials[i] = mat;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ atlasAsset.materials = populatingMaterials.ToArray();
|
|
|
|
+
|
|
|
|
+ for (int i = 0; i < vestigialMaterials.Count; i++)
|
|
|
|
+ AssetDatabase.DeleteAsset(AssetDatabase.GetAssetPath(vestigialMaterials[i]));
|
|
|
|
+
|
|
|
|
+ if (AssetDatabase.GetAssetPath(atlasAsset) == "")
|
|
|
|
+ AssetDatabase.CreateAsset(atlasAsset, atlasPath);
|
|
|
|
+ else
|
|
|
|
+ atlasAsset.Clear();
|
|
|
|
+
|
|
|
|
+ atlasAsset.GetAtlas();
|
|
|
|
+ atlasAsset.updateRegionsInPlayMode = true;
|
|
|
|
+
|
|
|
|
+ EditorUtility.SetDirty(atlasAsset);
|
|
|
|
+ AssetDatabase.SaveAssets();
|
|
|
|
+
|
|
|
|
+ Debug.Log(string.Format("{0} :: Imported with {1} material", atlasAsset.name, atlasAsset.materials.Length), atlasAsset);
|
|
|
|
+
|
|
|
|
+ protectFromStackGarbageCollection.Remove(atlasAsset);
|
|
|
|
+ return (AtlasAssetBase)AssetDatabase.LoadAssetAtPath(atlasPath, typeof(AtlasAssetBase));
|
|
|
|
+ }
|
|
|
|
+
|
|
static bool SetDefaultTextureSettings (string texturePath, SpineAtlasAsset atlasAsset) {
|
|
static bool SetDefaultTextureSettings (string texturePath, SpineAtlasAsset atlasAsset) {
|
|
TextureImporter texImporter = (TextureImporter)TextureImporter.GetAtPath(texturePath);
|
|
TextureImporter texImporter = (TextureImporter)TextureImporter.GetAtPath(texturePath);
|
|
if (texImporter == null) {
|
|
if (texImporter == null) {
|
|
@@ -595,7 +761,7 @@ namespace Spine.Unity.Editor {
|
|
return true;
|
|
return true;
|
|
}
|
|
}
|
|
|
|
|
|
- #if NEW_PREFERENCES_SETTINGS_PROVIDER
|
|
|
|
|
|
+#if NEW_PREFERENCES_SETTINGS_PROVIDER
|
|
static bool SetReferenceTextureSettings (string texturePath, SpineAtlasAsset atlasAsset, string referenceAssetPath) {
|
|
static bool SetReferenceTextureSettings (string texturePath, SpineAtlasAsset atlasAsset, string referenceAssetPath) {
|
|
var texturePreset = AssetDatabase.LoadAssetAtPath<UnityEditor.Presets.Preset>(referenceAssetPath);
|
|
var texturePreset = AssetDatabase.LoadAssetAtPath<UnityEditor.Presets.Preset>(referenceAssetPath);
|
|
bool isTexturePreset = texturePreset != null && texturePreset.GetTargetTypeName() == "TextureImporter";
|
|
bool isTexturePreset = texturePreset != null && texturePreset.GetTargetTypeName() == "TextureImporter";
|
|
@@ -613,7 +779,7 @@ namespace Spine.Unity.Editor {
|
|
AssetDatabase.SaveAssets();
|
|
AssetDatabase.SaveAssets();
|
|
return true;
|
|
return true;
|
|
}
|
|
}
|
|
- #else
|
|
|
|
|
|
+#else
|
|
static bool SetReferenceTextureSettings (string texturePath, SpineAtlasAsset atlasAsset, string referenceAssetPath) {
|
|
static bool SetReferenceTextureSettings (string texturePath, SpineAtlasAsset atlasAsset, string referenceAssetPath) {
|
|
TextureImporter reference = TextureImporter.GetAtPath(referenceAssetPath) as TextureImporter;
|
|
TextureImporter reference = TextureImporter.GetAtPath(referenceAssetPath) as TextureImporter;
|
|
if (reference == null)
|
|
if (reference == null)
|
|
@@ -642,7 +808,7 @@ namespace Spine.Unity.Editor {
|
|
AssetDatabase.SaveAssets();
|
|
AssetDatabase.SaveAssets();
|
|
return true;
|
|
return true;
|
|
}
|
|
}
|
|
- #endif
|
|
|
|
|
|
+#endif
|
|
|
|
|
|
static void ApplyPMAOrStraightAlphaSettings (Material material, string referenceTextureSettings) {
|
|
static void ApplyPMAOrStraightAlphaSettings (Material material, string referenceTextureSettings) {
|
|
bool isUsingPMAWorkflow = string.IsNullOrEmpty(referenceTextureSettings) ||
|
|
bool isUsingPMAWorkflow = string.IsNullOrEmpty(referenceTextureSettings) ||
|
|
@@ -650,9 +816,9 @@ namespace Spine.Unity.Editor {
|
|
|
|
|
|
MaterialChecks.EnablePMAAtMaterial(material, isUsingPMAWorkflow);
|
|
MaterialChecks.EnablePMAAtMaterial(material, isUsingPMAWorkflow);
|
|
}
|
|
}
|
|
- #endregion
|
|
|
|
|
|
+#endregion
|
|
|
|
|
|
- #region Import SkeletonData (json or binary)
|
|
|
|
|
|
+#region Import SkeletonData (json or binary)
|
|
internal static string GetSkeletonDataAssetFilePath(TextAsset spineJson) {
|
|
internal static string GetSkeletonDataAssetFilePath(TextAsset spineJson) {
|
|
string primaryName = Path.GetFileNameWithoutExtension(spineJson.name);
|
|
string primaryName = Path.GetFileNameWithoutExtension(spineJson.name);
|
|
string assetPath = Path.GetDirectoryName(AssetDatabase.GetAssetPath(spineJson)).Replace('\\', '/');
|
|
string assetPath = Path.GetDirectoryName(AssetDatabase.GetAssetPath(spineJson)).Replace('\\', '/');
|
|
@@ -996,7 +1162,7 @@ namespace Spine.Unity.Editor {
|
|
return null;
|
|
return null;
|
|
}
|
|
}
|
|
|
|
|
|
- string spineGameObjectName = string.Format("Spine GameObject ({0})", skeletonDataAsset.name.Replace("_SkeletonData", ""));
|
|
|
|
|
|
+ string spineGameObjectName = string.Format("Spine GameObject ({0})", skeletonDataAsset.name.Replace(AssetUtility.SkeletonDataSuffix, ""));
|
|
GameObject go = EditorInstantiation.NewGameObject(spineGameObjectName, useObjectFactory,
|
|
GameObject go = EditorInstantiation.NewGameObject(spineGameObjectName, useObjectFactory,
|
|
typeof(MeshFilter), typeof(MeshRenderer), typeof(SkeletonAnimation));
|
|
typeof(MeshFilter), typeof(MeshRenderer), typeof(SkeletonAnimation));
|
|
SkeletonAnimation newSkeletonAnimation = go.GetComponent<SkeletonAnimation>();
|
|
SkeletonAnimation newSkeletonAnimation = go.GetComponent<SkeletonAnimation>();
|
|
@@ -1025,19 +1191,19 @@ namespace Spine.Unity.Editor {
|
|
|
|
|
|
/// <summary>Handles creating a new GameObject in the Unity Editor. This uses the new ObjectFactory API where applicable.</summary>
|
|
/// <summary>Handles creating a new GameObject in the Unity Editor. This uses the new ObjectFactory API where applicable.</summary>
|
|
public static GameObject NewGameObject (string name, bool useObjectFactory) {
|
|
public static GameObject NewGameObject (string name, bool useObjectFactory) {
|
|
- #if NEW_PREFAB_SYSTEM
|
|
|
|
|
|
+#if NEW_PREFAB_SYSTEM
|
|
if (useObjectFactory)
|
|
if (useObjectFactory)
|
|
return ObjectFactory.CreateGameObject(name);
|
|
return ObjectFactory.CreateGameObject(name);
|
|
- #endif
|
|
|
|
|
|
+#endif
|
|
return new GameObject(name);
|
|
return new GameObject(name);
|
|
}
|
|
}
|
|
|
|
|
|
/// <summary>Handles creating a new GameObject in the Unity Editor. This uses the new ObjectFactory API where applicable.</summary>
|
|
/// <summary>Handles creating a new GameObject in the Unity Editor. This uses the new ObjectFactory API where applicable.</summary>
|
|
public static GameObject NewGameObject (string name, bool useObjectFactory, params System.Type[] components) {
|
|
public static GameObject NewGameObject (string name, bool useObjectFactory, params System.Type[] components) {
|
|
- #if NEW_PREFAB_SYSTEM
|
|
|
|
|
|
+#if NEW_PREFAB_SYSTEM
|
|
if (useObjectFactory)
|
|
if (useObjectFactory)
|
|
return ObjectFactory.CreateGameObject(name, components);
|
|
return ObjectFactory.CreateGameObject(name, components);
|
|
- #endif
|
|
|
|
|
|
+#endif
|
|
return new GameObject(name, components);
|
|
return new GameObject(name, components);
|
|
}
|
|
}
|
|
|
|
|
|
@@ -1075,7 +1241,7 @@ namespace Spine.Unity.Editor {
|
|
return null;
|
|
return null;
|
|
}
|
|
}
|
|
|
|
|
|
- string spineGameObjectName = string.Format("Spine Mecanim GameObject ({0})", skeletonDataAsset.name.Replace("_SkeletonData", ""));
|
|
|
|
|
|
+ string spineGameObjectName = string.Format("Spine Mecanim GameObject ({0})", skeletonDataAsset.name.Replace(AssetUtility.SkeletonDataSuffix, ""));
|
|
GameObject go = EditorInstantiation.NewGameObject(spineGameObjectName, useObjectFactory,
|
|
GameObject go = EditorInstantiation.NewGameObject(spineGameObjectName, useObjectFactory,
|
|
typeof(MeshFilter), typeof(MeshRenderer), typeof(Animator), typeof(SkeletonMecanim));
|
|
typeof(MeshFilter), typeof(MeshRenderer), typeof(Animator), typeof(SkeletonMecanim));
|
|
|
|
|