最近在研究用FairyGUI的装载器GLoader加载的图片替换掉Spine文件里面的某一张贴图。GLoader里面的Texture用的是自定义类型NTxture,可以通过NTxture.nativeTexture获取到整张的纹理集,然后通过设置uv值来构建AtlasRegion。Spine取UV的方式跟FairyGUI有点区别,需要把uv和u2v2倒转一下。
首先搞清楚Spine的设置关系,先是有了AtlasRegion,里面有许多组成一个个体(角色)的各部分的Slot,然后Slot里包含Attachment,里面又存放了图片信息。
所以我们的换装思路是:使用NTexture构建AtlasRegion,然后再构建RegionAttachment,然后获取要换掉的Slot,最后对Slot的Attachment进行换图。
下面是部分关键代码:
private static AtlasRegion CreateRegion(NTexture texture)
{
var region = new AtlasRegion();
region.width = texture.width;
region.height = texture.height;
region.originalWidth = texture.width;
region.originalHeight = texture.height;
region.rotate = false;
region.page = new AtlasPage();
region.page.name = texture.nativeTexture.name;
region.page.width = texture.nativeTexture.width;
region.page.height = texture.nativeTexture.height;
region.page.uWrap = TextureWrap.ClampToEdge;
region.page.vWrap = TextureWrap.ClampToEdge;
var offset = texture.offset;
region.offsetX = offset.x;
region.offsetY = offset.y;
var uvs = new Vector2[4];
texture.GetUV(uvs);
region.u = uvs[3].x;
region.v = uvs[1].y;
region.u2 = uvs[1].x;
region.v2 = uvs[3].y;
var mat = new Material(Shader.Find("Sprites/Default"));
mat.mainTexture = texture.nativeTexture;
region.page.rendererObject = mat;
return region;
}
public static RegionAttachment NewLinkedMeshAttachment (string attachmentName, AtlasRegion region, RegionAttachment parentMesh)
{
if (string.IsNullOrEmpty(attachmentName)) throw new System.ArgumentException("attachmentName can't be null or empty.", "attachmentName");
if (region == null) throw new System.ArgumentNullException("region");
if (parentMesh == null) throw new System.ArgumentNullException("parentMesh");
var mesh = new RegionAttachment(attachmentName);
mesh.Path = attachmentName;
mesh.Width = parentMesh.width;
mesh.Height = parentMesh.height;
mesh.X = parentMesh.x;
mesh.Y = parentMesh.y;
mesh.region = region.Clone();
mesh.UpdateRegion();
return mesh;
}
public static void SetAttachment(Skeleton skeleton, string slotName, string skinName, string attachmentName, Attachment attachment)
{
var slotIndex = skeleton.FindSlotIndex(slotName);
var skin = string.IsNullOrEmpty(skinName)
? skeleton.data.defaultSkin
: skeleton.data.FindSkin(skinName);
skin.SetAttachment(slotIndex, attachmentName ,attachment);
}