public void OptimizeSkin()
        {
            // Create a repacked skin.
            var previousSkin = skeletonAnimation.Skeleton.Skin;

            // Note: materials and textures returned by GetRepackedSkin() behave like 'new Texture2D()' and need to be destroyed
            if (runtimeMaterial)
            {
                Destroy(runtimeMaterial);
            }
            if (runtimeAtlas)
            {
                Destroy(runtimeAtlas);
            }
            Skin repackedSkin = previousSkin.GetRepackedSkin("Repacked skin", skeletonAnimation.SkeletonDataAsset.atlasAssets[0].PrimaryMaterial, out runtimeMaterial, out runtimeAtlas);

            previousSkin.Clear();

            // Use the repacked skin.
            skeletonAnimation.Skeleton.Skin = repackedSkin;
            skeletonAnimation.Skeleton.SetSlotsToSetupPose();
            skeletonAnimation.AnimationState.Apply(skeletonAnimation.Skeleton);

            // You can optionally clear the cache after multiple repack operations.
            AtlasUtilities.ClearCache();
        }
        public void OptimizeSkin()
        {
            // Create a repacked skin.
            var previousSkin = skeletonAnimation.Skeleton.Skin;

            // Note: materials and textures returned by GetRepackedSkin() behave like 'new Texture2D()' and need to be destroyed
            if (runtimeMaterial)
            {
                Destroy(runtimeMaterial);
            }
            if (runtimeAtlas)
            {
                Destroy(runtimeAtlas);
            }
            Skin repackedSkin = previousSkin.GetRepackedSkin("Repacked skin", skeletonAnimation.SkeletonDataAsset.atlasAssets[0].PrimaryMaterial, out runtimeMaterial, out runtimeAtlas);

            previousSkin.Clear();

            // Use the repacked skin.
            skeletonAnimation.Skeleton.Skin = repackedSkin;
            skeletonAnimation.Skeleton.SetSlotsToSetupPose();
            skeletonAnimation.AnimationState.Apply(skeletonAnimation.Skeleton);

            // `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();
        }
Esempio n. 3
0
        void Apply()
        {
            var skeletonAnimation = GetComponent <SkeletonAnimation>();
            var skeleton          = skeletonAnimation.Skeleton;

            // STEP 0: PREPARE SKINS
            // Let's prepare a new skin to be our custom skin with equips/customizations. We get a clone so our original skins are unaffected.
            customSkin = customSkin ?? new Skin("custom skin");             // This requires that all customizations are done with skin placeholders defined in Spine.
            var templateSkin = skeleton.Data.FindSkin(templateAttachmentsSkin);

            // STEP 1: "EQUIP" ITEMS USING SPRITES
            // STEP 1.1 Find the original/template attachment.
            // Step 1.2 Get a clone of the original/template attachment.
            // Step 1.3 Apply the Sprite image to the clone.
            // Step 1.4 Add the remapped clone to the new custom skin.

            // Let's do this for the visor.
            int        visorSlotIndex     = skeleton.Data.FindSlot(visorSlot).Index;              // You can access GetAttachment and SetAttachment via string, but caching the slotIndex is faster.
            Attachment templateAttachment = templateSkin.GetAttachment(visorSlotIndex, visorKey); // STEP 1.1

            // 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.
            Attachment newAttachment = templateAttachment.GetRemappedClone(visorSprite, sourceMaterial, pivotShiftsMeshUVCoords: false); // STEP 1.2 - 1.3

            customSkin.SetAttachment(visorSlotIndex, visorKey, newAttachment);                                                           // STEP 1.4

            // And now for the gun.
            int        gunSlotIndex = skeleton.Data.FindSlot(gunSlot).Index;
            Attachment templateGun  = templateSkin.GetAttachment(gunSlotIndex, gunKey);                                        // STEP 1.1
            Attachment newGun       = templateGun.GetRemappedClone(gunSprite, sourceMaterial, pivotShiftsMeshUVCoords: false); // STEP 1.2 - 1.3

            if (newGun != null)
            {
                customSkin.SetAttachment(gunSlotIndex, gunKey, newGun);                             // STEP 1.4
            }
            // customSkin.RemoveAttachment(gunSlotIndex, gunKey); // To remove an item.
            // customSkin.Clear()
            // Use skin.Clear() To remove all customizations.
            // Customizations will fall back to the value in the default skin if it was defined there.
            // To prevent fallback from happening, make sure the key is not defined in the default skin.

            // STEP 3: APPLY AND CLEAN UP.
            // Recommended, preferably at level-load-time: REPACK THE CUSTOM SKIN TO MINIMIZE DRAW CALLS
            //              IMPORTANT NOTE: the GetRepackedSkin() operation is expensive - if multiple characters
            //              need to call it every few seconds the overhead will outweigh the draw call benefits.
            //
            //              Repacking requires that you set all source textures/sprites/atlases to be Read/Write enabled in the inspector.
            //              Combine all the attachment sources into one skin. Usually this means the default skin and the custom skin.
            //              call Skin.GetRepackedSkin to get a cloned skin with cloned attachments that all use one texture.
            if (repack)
            {
                var repackedSkin = new Skin("repacked skin");
                repackedSkin.AddSkin(skeleton.Data.DefaultSkin);  // Include the "default" skin. (everything outside of skin placeholders)
                repackedSkin.AddSkin(customSkin);                 // Include your new custom skin.

                // Note: materials and textures returned by GetRepackedSkin() behave like 'new Texture2D()' and need to be destroyed
                if (runtimeMaterial)
                {
                    Destroy(runtimeMaterial);
                }
                if (runtimeAtlas)
                {
                    Destroy(runtimeAtlas);
                }
                repackedSkin = repackedSkin.GetRepackedSkin("repacked skin", sourceMaterial, out runtimeMaterial, out runtimeAtlas); // Pack all the items in the skin.
                skeleton.SetSkin(repackedSkin);                                                                                      // Assign the repacked skin to your Skeleton.
                if (bbFollower != null)
                {
                    bbFollower.Initialize(true);
                }
            }
            else
            {
                skeleton.SetSkin(customSkin);                 // Just use the custom skin directly.
            }

            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();
        }
Esempio n. 4
0
        void Apply()
        {
            var skeletonGraphic = GetComponent <SkeletonGraphic>();
            var skeleton        = skeletonGraphic.Skeleton;

            // STEP 0: PREPARE SKINS
            // Let's prepare a new skin to be our custom skin with equips/customizations. We get a clone so our original skins are unaffected.
            customSkin = customSkin ?? new Skin("custom skin");             // This requires that all customizations are done with skin placeholders defined in Spine.
            //customSkin = customSkin ?? skeleton.UnshareSkin(true, false, skeletonAnimation.AnimationState); // use this if you are not customizing on the default skin and don't plan to remove
            // Next let's get the skin that contains our source attachments. These are the attachments that
            var baseSkin = skeleton.Data.FindSkin(baseSkinName);

            // STEP 1: "EQUIP" ITEMS USING SPRITES
            // STEP 1.1 Find the original attachment.
            // Step 1.2 Get a clone of the original attachment.
            // Step 1.3 Apply the Sprite image to it.
            // Step 1.4 Add the remapped clone to the new custom skin.

            // Let's do this for the visor.
            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.
            int        gunSlotIndex = skeleton.FindSlotIndex(gunSlot);
            Attachment baseGun      = baseSkin.GetAttachment(gunSlotIndex, gunKey);        // STEP 1.1
            Attachment newGun       = baseGun.GetRemappedClone(gunSprite, sourceMaterial); // STEP 1.2 - 1.3

            if (newGun != null)
            {
                customSkin.SetAttachment(gunSlotIndex, gunKey, newGun);                             // STEP 1.4
            }
            // customSkin.RemoveAttachment(gunSlotIndex, gunKey); // To remove an item.
            // customSkin.Clear()
            // Use skin.Clear() To remove all customizations.
            // Customizations will fall back to the value in the default skin if it was defined there.
            // To prevent fallback from happening, make sure the key is not defined in the default skin.

            // STEP 3: APPLY AND CLEAN UP.
            // Recommended: REPACK THE CUSTOM SKIN TO MINIMIZE DRAW CALLS
            //              Repacking requires that you set all source textures/sprites/atlases to be Read/Write enabled in the inspector.
            //              Combine all the attachment sources into one skin. Usually this means the default skin and the custom skin.
            //              call Skin.GetRepackedSkin to get a cloned skin with cloned attachments that all use one texture.
            if (repack)
            {
                var repackedSkin = new Skin("repacked skin");
                repackedSkin.AddAttachments(skeleton.Data.DefaultSkin);
                repackedSkin.AddAttachments(customSkin);
                // Note: materials and textures returned by GetRepackedSkin() behave like 'new Texture2D()' and need to be destroyed
                if (runtimeMaterial)
                {
                    Destroy(runtimeMaterial);
                }
                if (runtimeAtlas)
                {
                    Destroy(runtimeAtlas);
                }
                repackedSkin = repackedSkin.GetRepackedSkin("repacked skin", sourceMaterial, out runtimeMaterial, out runtimeAtlas);
                skeleton.SetSkin(repackedSkin);
            }
            else
            {
                skeleton.SetSkin(customSkin);
            }

            //skeleton.SetSlotsToSetupPose();
            skeleton.SetToSetupPose();
            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();
        }
        public static void GetSpineRepackedSkin(CombineTextureData combineTextureData, Skin skin, string newName, Shader shader, int maxAtlasSize, TextureFormat textureFormat, bool mipMaps, Material materialPropertySource, bool clearCache)
        {
            if (skin == null)
            {
                throw new System.NullReferenceException("Skin was null");
            }
            var skinAttachments = skin.Attachments;
            var newSkin         = new Skin(newName);

            var existingRegions     = new Dictionary <AtlasRegion, int> ();
            var regionIndexes       = new List <int> ();
            var repackedAttachments = new List <Attachment> ();
            var texturesToPack      = new List <Texture2D> ();
            var originalRegions     = new List <AtlasRegion> ();
            int newRegionIndex      = 0;

            foreach (var kvp in skinAttachments)
            {
                var newAttachment = kvp.Value.GetClone(true);
                if (IsRenderable(newAttachment))
                {
                    var region = newAttachment.GetAtlasRegion();
                    int existingIndex;
                    if (existingRegions.TryGetValue(region, out existingIndex))
                    {
                        regionIndexes.Add(existingIndex);  // Store the region index for the eventual new attachment.
                    }
                    else
                    {
                        originalRegions.Add(region);
                        //texturesToPack.Add (region.ToTexture ()); // Add the texture to the PackTextures argument
                        existingRegions.Add(region, newRegionIndex); // Add the region to the dictionary of known regions
                        regionIndexes.Add(newRegionIndex);           // Store the region index for the eventual new attachment.
                        newRegionIndex++;
                    }
                    repackedAttachments.Add(newAttachment);
                }
                var key = kvp.Key;
                newSkin.AddAttachment(key.slotIndex, key.name, newAttachment);
            }
            //合并图集
            if (null != combineTextureData.combineCoroutineSmall)
            {
                //region.ToTexture ()???
                GameManager.Instance.StopCoroutine(combineTextureData.combineCoroutineSmall);
            }
            combineTextureData.combineCoroutineSmall = GameManager.Instance.StartCoroutine(CombineTexturesTool.Instance.GetRenderTextureByTexturesOptimize(combineTextureData, originalRegions, maxAtlasSize, (PackagedTextureResult result) => {
                RenderTexture renderTexture        = result.renderTexture;
                TextureClass[] outTextureClassList = result.textureInfo;
                var newMaterial = new Material(shader);
                if (materialPropertySource != null)
                {
                    newMaterial.CopyPropertiesFromMaterial(materialPropertySource);
                    newMaterial.shaderKeywords = materialPropertySource.shaderKeywords;
                }

                newMaterial.name        = newName;
                newMaterial.mainTexture = renderTexture;
                var page  = newMaterial.ToSpineAtlasPage();
                page.name = newName;

                var repackedRegions = new List <AtlasRegion> ();
                for (int i = 0, n = originalRegions.Count; i < n; i++)
                {
                    var oldRegion = originalRegions[i];
                    var newRegion = UVRectToAtlasRegion(GetTargetRectByIndex(outTextureClassList, i), oldRegion.name, page, oldRegion.offsetX, oldRegion.offsetY, oldRegion.rotate);
                    repackedRegions.Add(newRegion);
                }

                for (int i = 0, n = repackedAttachments.Count; i < n; i++)
                {
                    var a = repackedAttachments[i];
                    a.SetRegion(repackedRegions[regionIndexes[i]]);
                }

                if (clearCache)
                {
                    AtlasUtilities.ClearCache();
                }
                if (null != combineTextureData.resultData)
                {
                    combineTextureData.resultData.skin     = null;
                    combineTextureData.resultData.material = null;
                    if (null != combineTextureData.resultData.currentRenderTex)
                    {
                        combineTextureData.resultData.lastRenderTex = combineTextureData.resultData.currentRenderTex;
                    }
                }
                combineTextureData.resultData.skin             = newSkin;
                combineTextureData.resultData.material         = newMaterial;
                combineTextureData.resultData.currentRenderTex = renderTexture;
                combineTextureData.isFinished = true;
            }));
        }