diff --git a/spine-unity/Assets/Spine Examples/Scripts/Mix and Match Character Customize/EquipSystemExample.cs b/spine-unity/Assets/Spine Examples/Scripts/Mix and Match Character Customize/EquipSystemExample.cs
index fc0521e45..381ed541b 100644
--- a/spine-unity/Assets/Spine Examples/Scripts/Mix and Match Character Customize/EquipSystemExample.cs
+++ b/spine-unity/Assets/Spine Examples/Scripts/Mix and Match Character Customize/EquipSystemExample.cs
@@ -82,6 +82,8 @@ namespace Spine.Unity.Examples {
var templateSkin = skeletonData.FindSkin(templateSkinName);
Attachment templateAttachment = templateSkin.GetAttachment(slotIndex, templateAttachmentName);
attachment = templateAttachment.GetRemappedClone(asset.sprite, sourceMaterial, premultiplyAlpha: this.applyPMA);
+ // Note: Each call to `GetRemappedClone()` with parameter `premultiplyAlpha` set to `true` creates
+ // a cached Texture copy which can be cleared by calling AtlasUtilities.ClearCache() as shown in the method below.
cachedAttachments.Add(asset, attachment); // Cache this value for next time this asset is used.
}
@@ -91,6 +93,14 @@ namespace Spine.Unity.Examples {
public void Done () {
target.OptimizeSkin();
+ // `GetRepackedSkin()` and each call to `GetRemappedClone()` with parameter `premultiplyAlpha` set to `true`
+ // creates cached Texture copies which can be cleared by calling AtlasUtilities.ClearCache().
+ // You can optionally clear the textures cache after multiple repack operations.
+ // Just be aware that while this cleanup frees up memory, it is also a costly operation
+ // and will likely cause a spike in the framerate.
+
+ //AtlasUtilities.ClearCache();
+ //Resources.UnloadUnusedAssets();
}
}
diff --git a/spine-unity/Assets/Spine Examples/Scripts/Mix and Match Character Customize/EquipsVisualsComponentExample.cs b/spine-unity/Assets/Spine Examples/Scripts/Mix and Match Character Customize/EquipsVisualsComponentExample.cs
index a548a3408..8caf2ca9b 100644
--- a/spine-unity/Assets/Spine Examples/Scripts/Mix and Match Character Customize/EquipsVisualsComponentExample.cs
+++ b/spine-unity/Assets/Spine Examples/Scripts/Mix and Match Character Customize/EquipsVisualsComponentExample.cs
@@ -78,9 +78,14 @@ namespace Spine.Unity.Examples {
Destroy(runtimeMaterial);
if (runtimeAtlas)
Destroy(runtimeAtlas);
- var repackedSkin = collectedSkin.GetRepackedSkin("Repacked skin", skeletonAnimation.SkeletonDataAsset.atlasAssets[0].PrimaryMaterial, out runtimeMaterial, out runtimeAtlas);
+ var repackedSkin = collectedSkin.GetRepackedSkin("Repacked skin", skeletonAnimation.SkeletonDataAsset.atlasAssets[0].PrimaryMaterial,
+ out runtimeMaterial, out runtimeAtlas, maxAtlasSize : 1024, clearCache: false);
collectedSkin.Clear();
+ // You can optionally clear the textures cache after each ore multiple repack operations are done.
+ //AtlasUtilities.ClearCache();
+ //Resources.UnloadUnusedAssets();
+
// 3. Use the repacked skin.
skeletonAnimation.Skeleton.Skin = repackedSkin;
RefreshSkeletonAttachments();
diff --git a/spine-unity/Assets/Spine Examples/Scripts/Mix and Match Character Customize/MixAndMatchSkinsExample.cs b/spine-unity/Assets/Spine Examples/Scripts/Mix and Match Character Customize/MixAndMatchSkinsExample.cs
index 13951f94d..a0c4a6c70 100644
--- a/spine-unity/Assets/Spine Examples/Scripts/Mix and Match Character Customize/MixAndMatchSkinsExample.cs
+++ b/spine-unity/Assets/Spine Examples/Scripts/Mix and Match Character Customize/MixAndMatchSkinsExample.cs
@@ -149,8 +149,13 @@ namespace Spine.Unity.Examples {
skeletonAnimation.Skeleton.SetSlotsToSetupPose();
skeletonAnimation.AnimationState.Apply(skeletonAnimation.Skeleton);
- // You can optionally clear the cache after multiple repack operations.
+ // `GetRepackedSkin()` and each call to `GetRemappedClone()` with parameter `premultiplyAlpha` set to `true`
+ // cache necessarily created Texture copies which can be cleared by calling AtlasUtilities.ClearCache().
+ // You can optionally clear the textures cache after multiple repack operations.
+ // Just be aware that while this cleanup frees up memory, it is also a costly operation
+ // and will likely cause a spike in the framerate.
AtlasUtilities.ClearCache();
+ Resources.UnloadUnusedAssets();
}
void UpdateCharacterSkin () {
diff --git a/spine-unity/Assets/Spine Examples/Scripts/MixAndMatch.cs b/spine-unity/Assets/Spine Examples/Scripts/MixAndMatch.cs
index b5dba28e6..64200eb91 100644
--- a/spine-unity/Assets/Spine Examples/Scripts/MixAndMatch.cs
+++ b/spine-unity/Assets/Spine Examples/Scripts/MixAndMatch.cs
@@ -95,6 +95,8 @@ namespace Spine.Unity.Examples {
int visorSlotIndex = skeleton.FindSlotIndex(visorSlot); // You can access GetAttachment and SetAttachment via string, but caching the slotIndex is faster.
Attachment templateAttachment = templateSkin.GetAttachment(visorSlotIndex, visorKey); // STEP 1.1
Attachment newAttachment = templateAttachment.GetRemappedClone(visorSprite, sourceMaterial, pivotShiftsMeshUVCoords : false); // STEP 1.2 - 1.3
+ // Note: Each call to `GetRemappedClone()` with parameter `premultiplyAlpha` set to `true` creates
+ // a cached Texture copy which can be cleared by calling AtlasUtilities.ClearCache() as done in the method below.
customSkin.SetAttachment(visorSlotIndex, visorKey, newAttachment); // STEP 1.4
// And now for the gun.
@@ -136,6 +138,12 @@ namespace Spine.Unity.Examples {
skeleton.SetSlotsToSetupPose(); // Use the pose from setup pose.
skeletonAnimation.Update(0); // Use the pose in the currently active animation.
+ // `GetRepackedSkin()` and each call to `GetRemappedClone()` with parameter `premultiplyAlpha` set to `true`
+ // cache necessarily created Texture copies which can be cleared by calling AtlasUtilities.ClearCache().
+ // You can optionally clear the textures cache after multiple repack operations.
+ // Just be aware that while this cleanup frees up memory, it is also a costly operation
+ // and will likely cause a spike in the framerate.
+ AtlasUtilities.ClearCache();
Resources.UnloadUnusedAssets();
}
}
diff --git a/spine-unity/Assets/Spine Examples/Scripts/MixAndMatchGraphic.cs b/spine-unity/Assets/Spine Examples/Scripts/MixAndMatchGraphic.cs
index 570abd4d0..eabe0a084 100644
--- a/spine-unity/Assets/Spine Examples/Scripts/MixAndMatchGraphic.cs
+++ b/spine-unity/Assets/Spine Examples/Scripts/MixAndMatchGraphic.cs
@@ -96,6 +96,8 @@ namespace Spine.Unity.Examples {
int visorSlotIndex = skeleton.FindSlotIndex(visorSlot); // You can access GetAttachment and SetAttachment via string, but caching the slotIndex is faster.
Attachment baseAttachment = baseSkin.GetAttachment(visorSlotIndex, visorKey); // STEP 1.1
Attachment newAttachment = baseAttachment.GetRemappedClone(visorSprite, sourceMaterial); // STEP 1.2 - 1.3
+ // Note: Each call to `GetRemappedClone()` with parameter `premultiplyAlpha` set to `true` creates
+ // a cached Texture copy which can be cleared by calling AtlasUtilities.ClearCache() as done below.
customSkin.SetAttachment(visorSlotIndex, visorKey, newAttachment); // STEP 1.4
// And now for the gun.
@@ -135,6 +137,12 @@ namespace Spine.Unity.Examples {
skeletonGraphic.Update(0);
skeletonGraphic.OverrideTexture = runtimeAtlas;
+ // `GetRepackedSkin()` and each call to `GetRemappedClone()` with parameter `premultiplyAlpha` set to `true`
+ // cache necessarily created Texture copies which can be cleared by calling AtlasUtilities.ClearCache().
+ // You can optionally clear the textures cache after multiple repack operations.
+ // Just be aware that while this cleanup frees up memory, it is also a costly operation
+ // and will likely cause a spike in the framerate.
+ AtlasUtilities.ClearCache();
Resources.UnloadUnusedAssets();
}
}
diff --git a/spine-unity/Assets/Spine/Runtime/spine-unity/Utility/AtlasUtilities.cs b/spine-unity/Assets/Spine/Runtime/spine-unity/Utility/AtlasUtilities.cs
index a8d156d2c..be9317076 100644
--- a/spine-unity/Assets/Spine/Runtime/spine-unity/Utility/AtlasUtilities.cs
+++ b/spine-unity/Assets/Spine/Runtime/spine-unity/Utility/AtlasUtilities.cs
@@ -242,11 +242,17 @@ namespace Spine.Unity.AttachmentTools {
/// Fills the outputAttachments list with new attachment objects based on the attachments in sourceAttachments,
/// but mapped to a new single texture using the same material.
/// Returned Material and Texture behave like new Texture2D(), thus you need to call Destroy()
- /// to free resources.
+ /// to free resources.
+ /// This method caches necessary Texture copies for later re-use, which might steadily increase the texture memory
+ /// footprint when used excessively. Set to true
+ /// or call to clear this texture cache.
+ /// You may want to call Resources.UnloadUnusedAssets() after that.
+ ///
/// The list of attachments to be repacked.
/// The List(Attachment) to populate with the newly created Attachment objects.
- ///
/// May be null. If no Material property source is provided, no special
+ /// When set to true, is called after
+ /// repacking to clear the texture cache. See remarks for additional info.
public static void GetRepackedAttachments (List sourceAttachments, List outputAttachments, Material materialPropertySource, out Material outputMaterial, out Texture2D outputTexture, int maxAtlasSize = 1024, int padding = 2, TextureFormat textureFormat = SpineTextureFormat, bool mipmaps = UseMipMaps, string newAssetName = "Repacked Attachments", bool clearCache = false, bool useOriginalNonrenderables = true) {
if (sourceAttachments == null) throw new System.ArgumentNullException("sourceAttachments");
if (outputAttachments == null) throw new System.ArgumentNullException("outputAttachments");
@@ -337,7 +343,14 @@ namespace Spine.Unity.AttachmentTools {
/// GetRepackedSkin is an expensive operation, preferably call it at level load time.
/// No Spine.Atlas object is created so there is no way to find AtlasRegions except through the Attachments using them.
/// Returned Material and Texture behave like new Texture2D(), thus you need to call Destroy()
- /// to free resources.
+ /// to free resources.
+ /// This method caches necessary Texture copies for later re-use, which might steadily increase the texture memory
+ /// footprint when used excessively. Set to true
+ /// or call to clear this texture cache.
+ /// You may want to call Resources.UnloadUnusedAssets() after that.
+ ///
+ /// When set to true, is called after
+ /// repacking to clear the texture cache. See remarks for additional info.
/// Optional additional textures (such as normal maps) to copy while repacking.
/// To copy e.g. the main texture and normal maps, pass 'new int[] { Shader.PropertyToID("_BumpMap") }' at this parameter.
/// When additionalTexturePropertyIDsToCopy is non-null,
@@ -368,10 +381,7 @@ namespace Spine.Unity.AttachmentTools {
///
/// Creates and populates a duplicate skin with cloned attachments that are backed by a new packed texture atlas
/// comprised of all the regions from the original skin.
- /// GetRepackedSkin is an expensive operation, preferably call it at level load time.
- /// No Spine.Atlas object is created so there is no way to find AtlasRegions except through the Attachments using them.
- /// Returned Material and Texture behave like new Texture2D(), thus you need to call Destroy()
- /// to free resources.
+ /// See documentation of for details.
public static Skin GetRepackedSkin (this Skin o, string newName, Shader shader, out Material outputMaterial, out Texture2D outputTexture,
int maxAtlasSize = 1024, int padding = 2, TextureFormat textureFormat = SpineTextureFormat, bool mipmaps = UseMipMaps,
Material materialPropertySource = null, bool clearCache = false, bool useOriginalNonrenderables = true,
@@ -525,6 +535,18 @@ namespace Spine.Unity.AttachmentTools {
static Dictionary CachedRegionTextures = new Dictionary();
static List CachedRegionTexturesList = new List();
+ ///
+ /// Frees up textures cached by repacking and remapping operations.
+ ///
+ /// Calling with parameter premultiplyAlpha=true,
+ /// or will cache textures for later re-use,
+ /// which might steadily increase the texture memory footprint when used excessively.
+ /// You can clear this Texture cache by calling .
+ /// You may also want to call Resources.UnloadUnusedAssets() after that. Be aware that while this cleanup
+ /// frees up memory, it is also a costly operation and will likely cause a spike in the framerate.
+ /// Thus it is recommended to perform costly repacking and cleanup operations after e.g. a character customization
+ /// screen has been exited, and if required additionally after a certain number of GetRemappedClone() calls.
+ ///
public static void ClearCache () {
foreach (var t in CachedRegionTexturesList) {
UnityEngine.Object.Destroy(t);
diff --git a/spine-unity/Assets/Spine/Runtime/spine-unity/Utility/AttachmentCloneExtensions.cs b/spine-unity/Assets/Spine/Runtime/spine-unity/Utility/AttachmentCloneExtensions.cs
index 2629c41f9..218156213 100644
--- a/spine-unity/Assets/Spine/Runtime/spine-unity/Utility/AttachmentCloneExtensions.cs
+++ b/spine-unity/Assets/Spine/Runtime/spine-unity/Utility/AttachmentCloneExtensions.cs
@@ -80,7 +80,8 @@ namespace Spine.Unity.AttachmentTools {
/// The original attachment.
/// The sprite whose texture to use.
/// The source material used to copy the shader and material properties from.
- /// If true, a premultiply alpha clone of the original texture will be created.
+ /// If true, a premultiply alpha clone of the original texture will be created.
+ /// See remarks below for additional info.
/// If true MeshAttachments will be cloned as linked meshes and will inherit animation from the original attachment.
/// If true the size of the original attachment will be followed, instead of using the Sprite size.
/// If true and the original Attachment is a MeshAttachment, then
@@ -89,6 +90,10 @@ namespace Spine.Unity.AttachmentTools {
/// If true and the original Attachment is a RegionAttachment, then
/// the original region's scale value is used instead of the Sprite's pixels per unit property. Since uniform scale is used,
/// x scale of the original attachment (width scale) is used, scale in y direction (height scale) is ignored.
+ /// When parameter premultiplyAlpha is set to true, a premultiply alpha clone of the
+ /// original texture will be created. Additionally, this PMA Texture clone is cached for later re-use,
+ /// which might steadily increase the Texture memory footprint when used excessively.
+ /// See on how to clear these cached textures.
public static Attachment GetRemappedClone (this Attachment o, Sprite sprite, Material sourceMaterial,
bool premultiplyAlpha = true, bool cloneMeshAsLinked = true, bool useOriginalRegionSize = false,
bool pivotShiftsMeshUVCoords = true, bool useOriginalRegionScale = false) {
diff --git a/spine-unity/Assets/Spine/Runtime/spine-unity/Utility/AttachmentRegionExtensions.cs b/spine-unity/Assets/Spine/Runtime/spine-unity/Utility/AttachmentRegionExtensions.cs
index 6e786019a..600538748 100644
--- a/spine-unity/Assets/Spine/Runtime/spine-unity/Utility/AttachmentRegionExtensions.cs
+++ b/spine-unity/Assets/Spine/Runtime/spine-unity/Utility/AttachmentRegionExtensions.cs
@@ -125,7 +125,10 @@ namespace Spine.Unity.AttachmentTools {
}
///
- /// Creates a Spine.AtlasRegion that uses a premultiplied alpha duplicate texture of the Sprite's texture data. Returns a RegionAttachment that uses it. Use this if you plan to use a premultiply alpha shader such as "Spine/Skeleton"
+ /// Creates a Spine.AtlasRegion that uses a premultiplied alpha duplicate texture of the Sprite's texture data.
+ /// Returns a RegionAttachment that uses it. Use this if you plan to use a premultiply alpha shader such as "Spine/Skeleton".
+ /// The duplicate texture is cached for later re-use. See documentation of
+ /// for additional details.
public static RegionAttachment ToRegionAttachmentPMAClone (this Sprite sprite, Shader shader, TextureFormat textureFormat = AtlasUtilities.SpineTextureFormat, bool mipmaps = AtlasUtilities.UseMipMaps, Material materialPropertySource = null, float rotation = 0f) {
if (sprite == null) throw new System.ArgumentNullException("sprite");
if (shader == null) throw new System.ArgumentNullException("shader");