我的项目使用了Spine来制作Player,现在正在制作装备系统,由于装备图片的资源量较多,用spine的skin管理起来不是特别方便,于是我想直接用unity中的sprite来替换进去。我已经完成了场景中Player(SkeletonAnimation)的装备外观替换,基本都是使用函数“ReplaceSlotWithSprite”来替换Skeleton中的Attachment(下面有详细的核心代码)。
需求:现在我想在装备界面中显示UI-Player(SkeletonGraphic),并且在每次换装时都能同步改变Player和UI-Player的装备外观,为此我需要在换装后将Player(SkeletonAnimation)的各种信息同步给UI-Player(SkeletonGraphic),我询问chatGPT获得代码方案后,执行的效果一直存在问题,甚至毫无效果,我已经调试了几天毫无进展,Spine官方是我最后的希望了 ,我想知道如何将SkeletonAnimation的所有东西复制到SkeletonGraphic上(它们使用了同一个SkeletonData)。
public bool ReplaceSlotWithSprite(EquipSlot slot, Sprite sprite, string preferTemplateAttachmentName = null) {
var skeleton = GetSkeleton();
if (skeleton == null || sprite == null) return false;
int slotIndex = FindSlotIndexByEnum(slot);
if (slotIndex < 0) return false;
// 若该槽有 CustomSlotMaterials 覆盖,先移除,让 remap 后的专用材质生效 RemoveCustomMaterialForSlot(slot);
var template = FindBestTemplateAttachment(slotIndex, preferTemplateAttachmentName);
if (template == null) { Debug.LogError($"缺少模板附件:{slot} / prefer={preferTemplateAttachmentName}");
return false;
}
var remapped = RemapFromTemplateAttachment(slot, template, sprite);
if (remapped == null) return false;
skeleton.Slots.Items[slotIndex].Attachment = remapped;
ApplyAndRefresh();
return true;
}
Attachment RemapFromTemplateAttachment(EquipSlot slot, Attachment template, Sprite sprite)
{
if (template == null || sprite == null) return null;
var skeleton = GetSkeleton();
if (skeleton == null) return null;
var tex = sprite.texture;
var mat = GetMaterialForSlotTexture(slot, tex);
if (mat == null) return null;
if (template is RegionAttachment ra) return ra.GetRemappedClone(sprite, mat, false, true);
if (template is MeshAttachment ma) return ma.GetRemappedClone(sprite, mat, false, true);
Debug.LogWarning($"不支持的模板类型:{template.GetType().Name}"); return null; }
Attachment FindBestTemplateAttachment(int slotIndex, string preferAttachmentName = null) {
var skeleton = GetSkeleton();
if (skeleton == null) return null;
var sData = skeleton.Data;
var defaultSkin = sData.FindSkin(defaultSkinName) ?? sData.DefaultSkin;
if (!string.IsNullOrEmpty(preferAttachmentName) && defaultSkin != null){
var at = defaultSkin.GetAttachment(slotIndex, preferAttachmentName);
if (at != null) { if (logVerbose) Debug.Log($"模板:指定名 {preferAttachmentName}");
return at; }
}
var slotName = skeleton.Slots.Items[slotIndex].Data.Name;
if (defaultSkin != null) { var at2 = defaultSkin.GetAttachment(slotIndex, slotName);
if (at2 != null) { if (logVerbose) Debug.Log($"模板:默认皮肤同名槽 {slotName}"); return at2; } }
if (defaultSkin != null) {
var entries = new List<Skin.SkinEntry>();
defaultSkin.GetAttachments(slotIndex, entries);
foreach (var e in entries)
if (e.Attachment != null) { if (logVerbose) Debug.Log($"模板:默认皮肤任意 {e.Name}");
return e.Attachment; } }
var current = skeleton.Slots.Items[slotIndex].Attachment;
if (current != null) { if (logVerbose) Debug.Log("模板:当前槽附件兜底"); return current; }
Debug.LogWarning($"找不到模板附件:slotIndex={slotIndex}"); return null; }