using System.Collections; using System.Collections.Generic; using UnityEngine; using Spine.Unity.AttachmentTools; namespace BFEditor { public class EditorBattleRoleAttackOperate : MonoBehaviour { Spine.Unity.SkeletonAnimation skeletonAnimation; Spine.Unity.SkeletonDataAsset skeletonDataAsset; List animationList = new List(){"attack01", "attack02", "attack03", "attack04", "attack05", "attack06"}; private int index = 0; private bool changedEquip = false; private Spine.Skin equipsSkin; private string skinName = "s1"; private string attachmentName = "MainWeapon"; private string attachmentName2 = "MainWeapon2"; public Sprite WeaponSprite; public Material SourceMaterial; Spine.Skin collectedSkin; Spine.Attachment CacheAttachment; public Material runtimeMaterial; public Texture2D runtimeAtlas; private float cd = 0.0f; void Start() { skeletonAnimation = GetComponentInChildren(); skeletonDataAsset = skeletonAnimation.SkeletonDataAsset; equipsSkin = new Spine.Skin("Equips"); Spine.Skin templateSkin = skeletonAnimation.Skeleton.Data.FindSkin(skinName); if (templateSkin != null) equipsSkin.AddSkin(templateSkin); skeletonAnimation.Skeleton.Skin = equipsSkin; RefreshSkeletonAttachments(); } // Update is called once per frame void Update() { cd -= Time.deltaTime; if(Input.GetKeyDown(KeyCode.Mouse0)) { if (cd <= 0.0f) { skeletonAnimation.AnimationState.SetAnimation(0, animationList[index], false); index++; if (index >= animationList.Count) { index = 0; cd = 1.0f; } } } else if(Input.GetKeyDown(KeyCode.Mouse1)) { ChangeEquip(); // 由骨架setAttachment方法来执行上述操作。 skeletonAnimation.Skeleton.SetAttachment("wx001", "w1001"); } } private void ChangeEquip() { if (changedEquip) { return; } changedEquip = true; Spine.SkeletonData skeletonData = skeletonDataAsset.GetSkeletonData(true); int slotIndex = skeletonData.FindSlot(attachmentName).Index; Spine.Attachment attachment = GenerateAttachmentFromEquipAsset(slotIndex, skinName, attachmentName); Equip(slotIndex, attachmentName, attachment); int slotIndex2 = skeletonData.FindSlot(attachmentName2).Index; Spine.Attachment attachment2 = GenerateAttachmentFromEquipAsset(slotIndex2, skinName, attachmentName2); Equip(slotIndex2, attachmentName2, attachment2); // OptimizeSkin(); // OptimizeSkin2(); } private Spine.Attachment GenerateAttachmentFromEquipAsset (int slotIndex, string templateSkinName, string templateAttachmentName) { if (CacheAttachment == null) { Spine.SkeletonData skeletonData = skeletonDataAsset.GetSkeletonData(true); Spine.Skin templateSkin = skeletonData.FindSkin(templateSkinName); Spine.Attachment templateAttachment = templateSkin.GetAttachment(slotIndex, templateAttachmentName); CacheAttachment = templateAttachment.GetRemappedClone(WeaponSprite, SourceMaterial, premultiplyAlpha: false); // 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. } return CacheAttachment; } private void Equip (int slotIndex, string attachmentName, Spine.Attachment attachment) { equipsSkin.SetAttachment(slotIndex, attachmentName, attachment); skeletonAnimation.Skeleton.SetSkin(equipsSkin); RefreshSkeletonAttachments(); } private void RefreshSkeletonAttachments () { skeletonAnimation.Skeleton.SetSlotsToSetupPose(); skeletonAnimation.AnimationState.Apply(skeletonAnimation.Skeleton); //skeletonAnimation.Update(0); } private void OptimizeSkin () { // 1. Collect all the attachments of all active skins. collectedSkin = collectedSkin ?? new Spine.Skin("Collected skin"); collectedSkin.Clear(); collectedSkin.AddSkin(skeletonAnimation.Skeleton.Data.DefaultSkin); collectedSkin.AddSkin(equipsSkin); // 2. Create a repacked 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); Spine.Skin repackedSkin = collectedSkin.GetRepackedSkin("Repacked skin", skeletonAnimation.SkeletonDataAsset.atlasAssets[0].PrimaryMaterial, out runtimeMaterial, out runtimeAtlas, maxAtlasSize: 2048, 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(); } public void OptimizeSkin2 () { // Create a repacked skin. Spine.Skin 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); Spine.Skin repackedSkin = previousSkin.GetRepackedSkin("Repacked skin", SourceMaterial, 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(); } } }