【Unity3D】Spine 3.8版本使用记录
版本:spine-unity-3.8-2021-11-10.unitypackage
1、控制指定范围帧[起始帧->结束帧]播放 + 倒放
float timeScale = -1;
SkeletonAnimation ani = ...;
var track = ani.AnimationState.SetAnimation(0, "xxxx", false);
float startTime = 起始帧 / 30f;
float endTime = 结束帧 / 30f;
track.AnimationStart = startTime;
track.AnimationEnd = endTime;
track.TimeScale = timeScale;
if (timeScale < 0)
{track.TrackTime = endTime;ani.Update(0);ani.LateUpdate();
}
当timeScale是负数时则表示倒放,数值代表播放速度,否则正放。
2、局部换皮肤
using System;
using Spine;
using Spine.Unity;
using Spine.Unity.AttachmentTools;
using UnityEngine;/// <summary>
/// 换皮测试
/// </summary>
public class SpineChangeSkin : MonoBehaviour
{private SkeletonAnimation skeletonAnimation;private SkeletonDataAsset skeletonDataAsset;private Material sourceMaterial;private SkeletonData skeletonData;private bool applyPma = true;[SpineSkin] private string templateSkinName;//模板皮肤名称(初始)private Skin equipsSkin;private Skin collectedSkin;#region 优化皮肤用private Material runtimeMaterial;private Texture2D runtimeAtlas;#endregion#region ChangeShin需要的 外部可显示 选择//[SpineSlot] public string slot1; //骨骼槽点//[SpineSkin] public string templateSkin;//[SpineAttachment(skinField: "templateSkin")]//public string templateAttachment;#endregionpublic void Init(){skeletonAnimation = GetComponent<SkeletonAnimation>();skeletonDataAsset = skeletonAnimation.SkeletonDataAsset;sourceMaterial = skeletonDataAsset.atlasAssets[0].PrimaryMaterial;skeletonData = skeletonAnimation.Skeleton.Data;ReSetSkin();}private void ReSetSkin(){var skeleton = skeletonAnimation.skeleton;var skin = skeleton.Skin;if (skin == null)templateSkinName = "default";elsetemplateSkinName = skin.Name;equipsSkin = new Skin("Equips");var tSkin = skeletonData.FindSkin(templateSkinName);if (tSkin != null)equipsSkin.AddAttachments(tSkin);skeletonAnimation.Skeleton.Skin = equipsSkin;RefreshSkeletonAttachments();}/// <summary>/// 局部换皮/// </summary>/// <param name="slot">骨骼槽点昵称</param>/// <param name="attachmentName">SpineAttachment 类型 一般和slot名称相同</param>/// <param name="sprite">要更改的贴图[需要开启读写功能]</param>public void ChangeShin(string slot, string attachmentName,Sprite sprite){int slotIndex = skeletonData.FindSlot(slot).Index;//根据骨骼槽点 找到槽点索引Attachment attachment = GenerateAttachment(slotIndex, templateSkinName, attachmentName, sprite);if (attachment == null)return;equipsSkin.SetAttachment(slotIndex, attachmentName, attachment);skeletonAnimation.Skeleton.SetSkin(equipsSkin);RefreshSkeletonAttachments();OptimizeSkin();}private Attachment GenerateAttachment(int slotIndex, string tSkinName, string attachmentName,Sprite sprite){var sData = skeletonDataAsset.GetSkeletonData(true);var tSkin = sData.FindSkin(tSkinName);Attachment tAttachment = tSkin.GetAttachment(slotIndex, attachmentName);if (tAttachment == null){Debug.LogError($"skin {tSkinName} slotIndex {slotIndex} attachmentName {attachmentName} ==》attachment=null");return null;}var attachment = tAttachment?.GetRemappedClone(sprite, sourceMaterial, premultiplyAlpha: this.applyPma);return attachment;}/// <summary>/// 刷新皮肤/// </summary>void RefreshSkeletonAttachments(){skeletonAnimation.Skeleton.SetSlotsToSetupPose();skeletonAnimation.AnimationState.Apply(skeletonAnimation.Skeleton); //skeletonAnimation.Update(0);}/// <summary>/// 优化皮肤 将换过皮肤的贴图 整合到一张贴图中 [人物贴图需要开启读写功能]/// </summary>public void OptimizeSkin(){try{// 1. 收集所有活动皮肤的所有附件。collectedSkin = collectedSkin ?? new Skin("Collected skin");collectedSkin.Clear();collectedSkin.AddAttachments(skeletonAnimation.Skeleton.Data.DefaultSkin);collectedSkin.AddAttachments(equipsSkin);// 2. 创造一个重新包装的皮肤。// 注意:GetRepackedSkin()返回的材质和纹理行为类似于'new Texture2D()',需要销毁if (runtimeMaterial != null){Destroy(runtimeMaterial);}if (runtimeAtlas != null){Destroy(runtimeAtlas);}var repackedSkin = collectedSkin.GetRepackedSkin("Repacked skin",sourceMaterial, out runtimeMaterial,out runtimeAtlas, clearCache:true);collectedSkin.Clear();// 3.使用重新包装的皮肤。skeletonAnimation.Skeleton.Skin = repackedSkin;RefreshSkeletonAttachments();}catch (Exception e){Debug.LogError($"OptimizeSkin 异常:{e.Message}");}}
}
默认启用PMA,贴图需要开启读写模式,如果贴图在SpriteAtlas图集,这个图集也要开启读写模式(PMA:将ChangeShin函数动态添加的Sprite打包成图集形式,图集可以一次DC渲染这个Spine,但是和其他Spine物体是分开图集的,所以当有N多个Spine物体时,依旧是很多DC的)
使用方法,需要知道插槽名,附件名,调用ChangeShin函数传入(插槽名,附件名,Sprite)
其他问题:
【Unity3D】Spine黑线(预乘问题)、贴图边缘裁剪问题-CSDN博客
【Unity】Spine重新播放动画时会闪烁上次动画的残影_spine跳帧抖动-CSDN博客
谨慎使用ani.Initialize(true); 传入的true代表完全覆盖重置所有你的设定,比如局部换肤,所有回调,一些动态添加的一切