public static Attachment GetRemappedClone(this Attachment o, AtlasRegion atlasRegion, bool cloneMeshAsLinked = true, bool useOriginalRegionSize = false, float scale = 0.01f) { RegionAttachment attachment = o as RegionAttachment; if (attachment != null) { RegionAttachment clone = attachment.GetClone(); clone.SetRegion(atlasRegion, false); if (!useOriginalRegionSize) { clone.width = atlasRegion.width * scale; clone.height = atlasRegion.height * scale; } clone.UpdateOffset(); return(clone); } MeshAttachment attachment3 = o as MeshAttachment; if (attachment3 != null) { MeshAttachment attachment4 = !cloneMeshAsLinked?attachment3.GetClone() : attachment3.GetLinkedClone(cloneMeshAsLinked); attachment4.SetRegion(atlasRegion, true); return(attachment4); } return(o.GetClone(true)); }
public RegionAttachment NewRegionAttachment(Skin skin, string name, string path) { RegionAttachment regionAttachment = new RegionAttachment(name); Texture2D texture = this.sprite.get_texture(); int instanceID = texture.GetInstanceID(); AtlasRegion atlasRegion; if (SpriteAttachmentLoader.atlasTable.ContainsKey(instanceID)) { atlasRegion = SpriteAttachmentLoader.atlasTable.get_Item(instanceID); } else { Material material = new Material(this.shader); if (this.sprite.get_packed()) { material.set_name("Unity Packed Sprite Material"); } else { material.set_name(this.sprite.get_name() + " Sprite Material"); } material.set_mainTexture(texture); atlasRegion = new AtlasRegion(); atlasRegion.page = new AtlasPage { rendererObject = material }; SpriteAttachmentLoader.atlasTable.set_Item(instanceID, atlasRegion); } Rect textureRect = this.sprite.get_textureRect(); textureRect.set_x(Mathf.InverseLerp(0f, (float)texture.get_width(), textureRect.get_x())); textureRect.set_y(Mathf.InverseLerp(0f, (float)texture.get_height(), textureRect.get_y())); textureRect.set_width(Mathf.InverseLerp(0f, (float)texture.get_width(), textureRect.get_width())); textureRect.set_height(Mathf.InverseLerp(0f, (float)texture.get_height(), textureRect.get_height())); Bounds bounds = this.sprite.get_bounds(); Vector3 size = bounds.get_size(); bool rotate = false; if (this.sprite.get_packed()) { rotate = (this.sprite.get_packingRotation() == 15); } regionAttachment.SetUVs(textureRect.get_xMin(), textureRect.get_yMax(), textureRect.get_xMax(), textureRect.get_yMin(), rotate); regionAttachment.RendererObject = atlasRegion; regionAttachment.SetColor(Color.get_white()); regionAttachment.ScaleX = 1f; regionAttachment.ScaleY = 1f; regionAttachment.RegionOffsetX = this.sprite.get_rect().get_width() * (0.5f - Mathf.InverseLerp(bounds.get_min().x, bounds.get_max().x, 0f)) / this.sprite.get_pixelsPerUnit(); regionAttachment.RegionOffsetY = this.sprite.get_rect().get_height() * (0.5f - Mathf.InverseLerp(bounds.get_min().y, bounds.get_max().y, 0f)) / this.sprite.get_pixelsPerUnit(); regionAttachment.Width = size.x; regionAttachment.Height = size.y; regionAttachment.RegionWidth = size.x; regionAttachment.RegionHeight = size.y; regionAttachment.RegionOriginalWidth = size.x; regionAttachment.RegionOriginalHeight = size.y; regionAttachment.UpdateOffset(); return(regionAttachment); }
public static Attachment GetRemappedClone(this Attachment o, AtlasRegion atlasRegion, bool cloneMeshAsLinked = true, bool useOriginalRegionSize = false, float scale = 0.01f) { RegionAttachment regionAttachment = o as RegionAttachment; if (regionAttachment != null) { RegionAttachment clone = regionAttachment.GetClone(); clone.SetRegion(atlasRegion, updateOffset: false); if (!useOriginalRegionSize) { clone.width = (float)atlasRegion.width * scale; clone.height = (float)atlasRegion.height * scale; } clone.UpdateOffset(); return(clone); } MeshAttachment meshAttachment = o as MeshAttachment; if (meshAttachment != null) { MeshAttachment meshAttachment2 = (!cloneMeshAsLinked) ? meshAttachment.GetClone() : meshAttachment.GetLinkedClone(cloneMeshAsLinked); meshAttachment2.SetRegion(atlasRegion); return(meshAttachment2); } return(o.GetClone(cloneMeshesAsLinked: true)); }
/// <summary> /// Gets a clone of the attachment remapped with an atlasRegion image.</summary> /// <returns>The remapped clone.</returns> /// <param name="o">The original attachment.</param> /// <param name="atlasRegion">Atlas region.</param> /// <param name="cloneMeshAsLinked">If <c>true</c> MeshAttachments will be cloned as linked meshes and will inherit animation from the original attachment.</param> /// <param name="useOriginalRegionSize">If <c>true</c> the size of the original attachment will be followed, instead of using the Sprite size.</param> /// <param name="scale">Unity units per pixel scale used to scale the atlas region size when not using the original region size.</param> public static Attachment GetRemappedClone(this Attachment o, AtlasRegion atlasRegion, bool cloneMeshAsLinked = true, bool useOriginalRegionSize = false, float scale = 0.01f) { var regionAttachment = o as RegionAttachment; if (regionAttachment != null) { RegionAttachment newAttachment = (RegionAttachment)regionAttachment.Copy(); newAttachment.SetRegion(atlasRegion, false); if (!useOriginalRegionSize) { newAttachment.Width = atlasRegion.width * scale; newAttachment.Height = atlasRegion.height * scale; } newAttachment.UpdateOffset(); return(newAttachment); } else { var meshAttachment = o as MeshAttachment; if (meshAttachment != null) { MeshAttachment newAttachment = cloneMeshAsLinked ? meshAttachment.NewLinkedMesh() : (MeshAttachment)meshAttachment.Copy(); newAttachment.SetRegion(atlasRegion); return(newAttachment); } } return(o.Copy()); }
public static RegionAttachment ToRegionAttachment(this AtlasRegion region, string attachmentName, float scale = 0.01f) { if (string.IsNullOrEmpty(attachmentName)) { throw new ArgumentException("attachmentName can't be null or empty.", "attachmentName"); } if (region == null) { throw new ArgumentNullException("region"); } RegionAttachment regionAttachment = new RegionAttachment(attachmentName); regionAttachment.RendererObject = region; regionAttachment.SetUVs(region.u, region.v, region.u2, region.v2, region.rotate); regionAttachment.regionOffsetX = region.offsetX; regionAttachment.regionOffsetY = region.offsetY; regionAttachment.regionWidth = region.width; regionAttachment.regionHeight = region.height; regionAttachment.regionOriginalWidth = region.originalWidth; regionAttachment.regionOriginalHeight = region.originalHeight; regionAttachment.Path = region.name; regionAttachment.scaleX = 1f; regionAttachment.scaleY = 1f; regionAttachment.rotation = 0f; regionAttachment.r = 1f; regionAttachment.g = 1f; regionAttachment.b = 1f; regionAttachment.a = 1f; regionAttachment.width = regionAttachment.regionOriginalWidth * scale; regionAttachment.height = regionAttachment.regionOriginalHeight * scale; regionAttachment.SetColor(Color.white); regionAttachment.UpdateOffset(); return(regionAttachment); }
public RegionAttachment NewRegionAttachment(Skin skin, string name, string path) { RegionAttachment regionAttachment = new RegionAttachment(name); Texture2D texture = this.sprite.texture; int instanceID = texture.GetInstanceID(); AtlasRegion atlasRegion; if (!SpriteAttachmentLoader.atlasTable.TryGetValue(instanceID, out atlasRegion)) { Material material = new Material(this.shader); if (this.sprite.packed) { material.name = "Unity Packed Sprite Material"; } else { material.name = this.sprite.name + " Sprite Material"; } material.mainTexture = texture; atlasRegion = new AtlasRegion(); AtlasPage atlasPage = new AtlasPage(); atlasPage.rendererObject = material; atlasRegion.page = atlasPage; SpriteAttachmentLoader.atlasTable[instanceID] = atlasRegion; } Rect textureRect = this.sprite.textureRect; textureRect.x = Mathf.InverseLerp(0f, (float)texture.width, textureRect.x); textureRect.y = Mathf.InverseLerp(0f, (float)texture.height, textureRect.y); textureRect.width = Mathf.InverseLerp(0f, (float)texture.width, textureRect.width); textureRect.height = Mathf.InverseLerp(0f, (float)texture.height, textureRect.height); Bounds bounds = this.sprite.bounds; Vector2 vector = bounds.min; Vector2 vector2 = bounds.max; Vector2 vector3 = bounds.size; float num = 1f / this.sprite.pixelsPerUnit; bool rotate = false; if (this.sprite.packed) { rotate = (this.sprite.packingRotation == SpritePackingRotation.Any); } regionAttachment.SetUVs(textureRect.xMin, textureRect.yMax, textureRect.xMax, textureRect.yMin, rotate); regionAttachment.RendererObject = atlasRegion; regionAttachment.SetColor(Color.white); regionAttachment.ScaleX = 1f; regionAttachment.ScaleY = 1f; regionAttachment.RegionOffsetX = this.sprite.rect.width * (0.5f - SpriteAttachmentLoader.InverseLerp(vector.x, vector2.x, 0f)) * num; regionAttachment.RegionOffsetY = this.sprite.rect.height * (0.5f - SpriteAttachmentLoader.InverseLerp(vector.y, vector2.y, 0f)) * num; regionAttachment.Width = vector3.x; regionAttachment.Height = vector3.y; regionAttachment.RegionWidth = vector3.x; regionAttachment.RegionHeight = vector3.y; regionAttachment.RegionOriginalWidth = vector3.x; regionAttachment.RegionOriginalHeight = vector3.y; regionAttachment.UpdateOffset(); return(regionAttachment); }
void Apply(SkeletonRenderer skeletonRenderer) { atlas = AtlasAsset.GetAtlas(); if (atlas == null) { return; } float scale = skeletonRenderer.skeletonDataAsset.scale; foreach (var entry in attachments) { Slot slot = skeletonRenderer.Skeleton.FindSlot(entry.slot); Attachment originalAttachment = slot.Attachment; AtlasRegion region = atlas.FindRegion(entry.region); if (region == null) { slot.Attachment = null; } else if (inheritProperties && originalAttachment != null) { slot.Attachment = originalAttachment.GetRemappedClone(region, true, true, scale); } else { var newRegionAttachment = region.ToRegionAttachment(region.name, scale); slot.Attachment = newRegionAttachment; } if (!entry.UseOriginalData) { RegionAttachment ra = slot.Attachment as RegionAttachment; if (ra == null) { return; } ra = (RegionAttachment)ra.Copy(); //HeroAnimImgList.SlotRegionPair PAIR = SDDataManager.Instance // .GetPairBySlotAndRegion(CM.SkeletonIndex, entry.slot, entry.region); //Vector2 _pos = PAIR.PositionOffset; //Vector2 _scale = PAIR.Scale; //ra.Width = ra.RegionWidth * scale * _scale.x; //ra.Height = ra.RegionHeight * scale * _scale.y; //ra.SetPositionOffset( _pos * scale * _scale ); ra.UpdateOffset(); slot.Attachment = ra; } } }
void Start() { var skeletonAnimation = GetComponent <SkeletonAnimation>(); var skeleton = skeletonAnimation.Skeleton; // All attachment changes will be applied to the skin. We use a clone so other instances will not be affected. var newSkin = skeleton.UnshareSkin(true, false, skeletonAnimation.AnimationState); // Case 1: Create an attachment from an atlas. RegionAttachment newHand = handSource.GetAtlas().FindRegion(handRegion).ToRegionAttachment("new hand"); newHand.SetPositionOffset(newHandOffset); newHand.Rotation = newHandRotation; newHand.UpdateOffset(); int handSlotIndex = skeleton.FindSlotIndex(handSlot); handTexture = newHand.GetRegion().ToTexture(); newSkin.AddAttachment(handSlotIndex, handAttachmentName, newHand); // Case 2: Create an attachment from a Unity Sprite (Sprite texture needs to be Read/Write Enabled in the inspector. RegionAttachment newWeapon = dagger.ToRegionAttachmentPMAClone(Shader.Find("Spine/Skeleton")); newWeapon.SetScale(1.5f, 1.5f); newWeapon.UpdateOffset(); int weaponSlotIndex = skeleton.FindSlotIndex(weaponSlot); newSkin.AddAttachment(weaponSlotIndex, daggerName, newWeapon); // Case 3: Change an existing attachment's backing region. if (applyHeadRegion) { AtlasRegion spineBoyHead = headSource.GetAtlas().FindRegion(headRegion); int headSlotIndex = skeleton.FindSlotIndex(headSlot); var newHead = newSkin.GetAttachment(headSlotIndex, headAttachmentName).GetClone(true); newHead.SetRegion(spineBoyHead); newSkin.AddAttachment(headSlotIndex, headAttachmentName, newHead); } // Case 4: Repacking a mixed-and-matched skin to minimize draw calls. // Repacking requires that you set all source textures/sprites/atlases to be Read/Write enabled in the inspector. if (repack) { newSkin = newSkin.GetRepackedSkin("repacked", repackedShader, out runtimeMaterial, out runtimeAtlas); } skeleton.SetSkin(newSkin); skeleton.SetToSetupPose(); skeleton.SetAttachment(weaponSlot, daggerName); Resources.UnloadUnusedAssets(); }
private void addSkeletonAttachment(string slotName, string attachmentName, TextureData textureData) { RegionAttachment regionAttachment = new RegionAttachment(attachmentName); regionAttachment.RendererObject = textureData.Texture; regionAttachment.Width = regionAttachment.RegionWidth = regionAttachment.RegionOriginalWidth = textureData.Texture.Width; regionAttachment.Height = regionAttachment.RegionHeight = regionAttachment.RegionOriginalHeight = textureData.Texture.Height; regionAttachment.RegionOffsetX = textureData.OriginX; regionAttachment.RegionOffsetY = textureData.OriginY; regionAttachment.Rotation = textureData.Rotation; regionAttachment.SetUVs(0, 0, 1, 1, false); regionAttachment.UpdateOffset(); Skeleton.Data.FindSkin("default").AddAttachment(Skeleton.FindSlotIndex(slotName), attachmentName, regionAttachment); }
public static void SetRegion(this RegionAttachment attachment, AtlasRegion region, bool updateOffset = true) { if (region == null) { throw new ArgumentNullException("region"); } attachment.RendererObject = region; attachment.SetUVs(region.u, region.v, region.u2, region.v2, region.rotate); attachment.regionOffsetX = region.offsetX; attachment.regionOffsetY = region.offsetY; attachment.regionWidth = region.width; attachment.regionHeight = region.height; attachment.regionOriginalWidth = region.originalWidth; attachment.regionOriginalHeight = region.originalHeight; if (updateOffset) { attachment.UpdateOffset(); } }
/// <summary> /// Creates a new RegionAttachment from a given AtlasRegion.</summary> public static RegionAttachment ToRegionAttachment(this AtlasRegion region, string attachmentName, float scale = 0.01f, float rotation = 0f) { if (string.IsNullOrEmpty(attachmentName)) { throw new System.ArgumentException("attachmentName can't be null or empty.", "attachmentName"); } if (region == null) { throw new System.ArgumentNullException("region"); } // (AtlasAttachmentLoader.cs) var attachment = new RegionAttachment(attachmentName); attachment.RendererObject = region; attachment.SetUVs(region.u, region.v, region.u2, region.v2, region.rotate); attachment.regionOffsetX = region.offsetX; attachment.regionOffsetY = region.offsetY; attachment.regionWidth = region.width; attachment.regionHeight = region.height; attachment.regionOriginalWidth = region.originalWidth; attachment.regionOriginalHeight = region.originalHeight; attachment.Path = region.name; attachment.scaleX = 1; attachment.scaleY = 1; attachment.rotation = rotation; attachment.r = 1; attachment.g = 1; attachment.b = 1; attachment.a = 1; // pass OriginalWidth and OriginalHeight because UpdateOffset uses it in its calculation. attachment.width = attachment.regionOriginalWidth * scale; attachment.height = attachment.regionOriginalHeight * scale; attachment.SetColor(Color.white); attachment.UpdateOffset(); return(attachment); }
private void Apply(SkeletonRenderer skeletonRenderer) { this.atlas = this.atlasAsset.GetAtlas(); AtlasAttachmentLoader atlasAttachmentLoader = new AtlasAttachmentLoader(new Atlas[] { this.atlas }); float scale = skeletonRenderer.skeletonDataAsset.scale; foreach (object obj in this.attachments) { SlotRegionPair slotRegionPair = (SlotRegionPair)obj; RegionAttachment regionAttachment = atlasAttachmentLoader.NewRegionAttachment(null, slotRegionPair.region, slotRegionPair.region); regionAttachment.Width = regionAttachment.RegionOriginalWidth * scale; regionAttachment.Height = regionAttachment.RegionOriginalHeight * scale; regionAttachment.SetColor(new Color(1f, 1f, 1f, 1f)); regionAttachment.UpdateOffset(); Slot slot = skeletonRenderer.skeleton.FindSlot(slotRegionPair.slot); slot.Attachment = regionAttachment; } }
private void Apply(SkeletonRenderer skeletonRenderer) { this.atlas = this.atlasAsset.GetAtlas(); AtlasAttachmentLoader atlasAttachmentLoader = new AtlasAttachmentLoader(new Atlas[] { this.atlas }); float scale = skeletonRenderer.skeletonDataAsset.scale; IEnumerator enumerator = this.attachments.GetEnumerator(); while (enumerator.MoveNext()) { AtlasRegionAttacher.SlotRegionPair slotRegionPair = (AtlasRegionAttacher.SlotRegionPair)enumerator.get_Current(); RegionAttachment regionAttachment = atlasAttachmentLoader.NewRegionAttachment(null, slotRegionPair.region, slotRegionPair.region); regionAttachment.Width = regionAttachment.RegionOriginalWidth * scale; regionAttachment.Height = regionAttachment.RegionOriginalHeight * scale; regionAttachment.SetColor(new Color(1f, 1f, 1f, 1f)); regionAttachment.UpdateOffset(); Slot slot = skeletonRenderer.skeleton.FindSlot(slotRegionPair.slot); slot.Attachment = regionAttachment; } }
// // Use this for initialization void Start() { SkeletonAnimation _ani = this.GetComponent <SkeletonAnimation>(); Skeleton _skeleton = _ani.skeleton; Skin _newSkin = _skeleton.UnshareSkin(true, false, _ani.AnimationState); //HeadFront Setting RegionAttachment _newHeadFront = headFront.ToRegionAttachmentPMAClone(Shader.Find("Spine/Skeleton")); _newHeadFront.SetScale(1f, 1f); _newHeadFront.UpdateOffset(); int headFrontSlotIndex = _skeleton.FindSlotIndex(headFrontSlot); _newSkin.AddAttachment(headFrontSlotIndex, headFront.name, _newHeadFront); //repack _newSkin = _newSkin.GetRepackedSkin("repacked", repackedShader, out runtimeMaterial, out runtimeAtlas); _skeleton.SetSkin(_newSkin); _skeleton.SetToSetupPose(); //_skeleton.SetToSetupPose(); _skeleton.SetAttachment(headFrontSlot, headFront.name); }
public RegionAttachment NewRegionAttachment(Skin skin, string name, string path) { RegionAttachment attachment = new RegionAttachment(name); Texture2D tex = sprite.texture; int instanceId = tex.GetInstanceID(); AtlasRegion atlasRegion; //check cache first if (atlasTable.ContainsKey(instanceId)) { atlasRegion = atlasTable[instanceId]; } else { //Setup new material Material mat = new Material(shader); if (sprite.packed) { mat.name = "Unity Packed Sprite Material"; } else { mat.name = sprite.name + " Sprite Material"; } mat.mainTexture = tex; //create faux-region to play nice with SkeletonRenderer atlasRegion = new AtlasRegion(); AtlasPage page = new AtlasPage(); page.rendererObject = mat; atlasRegion.page = page; //cache it atlasTable[instanceId] = atlasRegion; } Rect texRect = sprite.textureRect; //normalize rect to UV space of packed atlas texRect.x = Mathf.InverseLerp(0, tex.width, texRect.x); texRect.y = Mathf.InverseLerp(0, tex.height, texRect.y); texRect.width = Mathf.InverseLerp(0, tex.width, texRect.width); texRect.height = Mathf.InverseLerp(0, tex.height, texRect.height); Bounds bounds = sprite.bounds; Vector3 size = bounds.size; //TODO: make sure this rotation thing actually works bool rotated = false; if (sprite.packed) { rotated = sprite.packingRotation == SpritePackingRotation.Any; } //do some math and assign UVs and sizes attachment.SetUVs(texRect.xMin, texRect.yMax, texRect.xMax, texRect.yMin, rotated); attachment.RendererObject = atlasRegion; attachment.SetColor(Color.white); attachment.ScaleX = 1; attachment.ScaleY = 1; attachment.RegionOffsetX = sprite.rect.width * (0.5f - Mathf.InverseLerp(bounds.min.x, bounds.max.x, 0)) / sprite.pixelsPerUnit; attachment.RegionOffsetY = sprite.rect.height * (0.5f - Mathf.InverseLerp(bounds.min.y, bounds.max.y, 0)) / sprite.pixelsPerUnit; attachment.Width = size.x; attachment.Height = size.y; attachment.RegionWidth = size.x; attachment.RegionHeight = size.y; attachment.RegionOriginalWidth = size.x; attachment.RegionOriginalHeight = size.y; attachment.UpdateOffset(); return(attachment); }
Attachment readAttachment(Skin skin, string attachmentName, bool nonessential) { string name = ReadString(); if (name == "") { name = attachmentName; } int type = Read(); switch ((AttachmentType)type) { case AttachmentType.region: { string path = ReadString(); if (path == "") { path = name; } RegionAttachment region = m_attachmentLoader.NewRegionAttachment(skin, name, path); if (region == null) { return(null); } region.Path = path; region.X = ReadFloat(); region.Y = ReadFloat(); region.ScaleX = ReadFloat(); region.ScaleY = ReadFloat(); region.Rotation = ReadFloat(); region.Width = ReadFloat(); region.Height = ReadFloat(); //Color Color color = ReadColor(); region.R = color.r; region.G = color.g; region.B = color.b; region.A = color.a; region.UpdateOffset(); return(region); } case AttachmentType.boundingbox: { BoundingBoxAttachment box = m_attachmentLoader.NewBoundingBoxAttachment(skin, name); if (box == null) { return(null); } box.Vertices = readFloatArray(); return(box); } case AttachmentType.mesh: { string path = ReadString(); if (path == "") { path = name; } MeshAttachment mesh = m_attachmentLoader.NewMeshAttachment(skin, name, path); if (mesh == null) { return(null); } mesh.Path = path; float[] uvs = readFloatArray(); int[] triangles = readShortArray(); float[] vertices = readFloatArray(); mesh.vertices = vertices; mesh.Triangles = triangles; mesh.regionUVs = uvs; mesh.UpdateUVs(); //Color Color color = ReadColor(); mesh.R = color.r; mesh.G = color.g; mesh.B = color.b; mesh.A = color.a; mesh.HullLength = ReadInt() * 2; if (nonessential) { mesh.Edges = readIntArray(); mesh.Width = ReadFloat(); mesh.Height = ReadFloat(); } return(mesh); } case AttachmentType.skinnedmesh: { string path = ReadString(); if (path == "") { path = name; } SkinnedMeshAttachment mesh = m_attachmentLoader.NewSkinnedMeshAttachment(skin, name, path); if (mesh == null) { return(null); } mesh.Path = path; float[] uvs = readFloatArray(); int[] triangles = readShortArray(); int vertexCount = ReadInt(); List <float> weights = new List <float>(uvs.Length * 3 * 3); List <int> bones = new List <int>(uvs.Length * 3); for (int i = 0; i < vertexCount; i++) { int boneCount = (int)ReadFloat(); bones.Add(boneCount); for (int j = i + boneCount * 4; i < j; i += 4) { bones.Add((int)ReadFloat()); weights.Add(ReadFloat()); weights.Add(ReadFloat()); weights.Add(ReadFloat()); } } mesh.bones = bones.ToArray(); mesh.Weights = weights.ToArray(); mesh.Triangles = triangles; mesh.regionUVs = uvs; mesh.UpdateUVs(); //Color Color color = ReadColor(); mesh.R = color.r; mesh.G = color.g; mesh.B = color.b; mesh.A = color.a; mesh.HullLength = ReadInt() * 2; if (nonessential) { mesh.Edges = readIntArray(); mesh.Width = ReadFloat(); mesh.Height = ReadFloat(); } return(mesh); } } return(null); }
/// <summary> /// 主要逻辑copy SkeletonJson.ReadAttachment /// </summary> /// <param name="sdEX"></param> /// <param name="atlasArray"></param> /// <returns></returns> public Skin GenSkinBySkniDataAsset(SkinDataEx sdEX, Atlas[] atlasArray) { #if SPINE_TK2D throw new NotImplementedException("GenSkinBySkniDataAsset Not Implemented"); #endif float scale = this.skeletonDataAsset.scale; var attachmentLoader = new AtlasAttachmentLoader(atlasArray); var skin = new Skin(sdEX.SkinName); var linkedMeshes = new List <SkeletonJson.LinkedMesh>(); Attachment attachment = null; foreach (var slot in sdEX.AllSlots) { var slotIndex = skeleton.Data.FindSlotIndex(slot.SlotName); foreach (var entry in slot.AllAttachments) { switch (entry.type) { case AttachmentType.Region: { RegionAttachment region = attachmentLoader.NewRegionAttachment(skin, entry.AttachmentName, entry.PathName); if (region == null) { Debug.LogError("RegionAttachment New Fail:" + entry.AttachmentName + "," + entry.PathName); continue; } region.Path = entry.PathName; #region Region数据的填充 CheckRegionData(entry.FloatValues); Single w = 32, h = 32; foreach (var f in entry.FloatValues) { switch (f.Key) { case "x": region.x = f.FloatValue * scale; break; case "y": region.y = f.FloatValue * scale; break; case "scaleX": region.scaleX = f.FloatValue; break; case "scaleY": region.scaleY = f.FloatValue; break; case "rotation": region.rotation = f.FloatValue; break; case "width": w = f.FloatValue; break; case "height": h = f.FloatValue; break; } } region.width = w * scale; region.height = h * scale; if (entry.ColorValues != null && entry.ColorValues.Count > 0) { foreach (var c in entry.ColorValues) { switch (c.Key) { case "color": region.r = c.ColorValue.r; region.g = c.ColorValue.g; region.b = c.ColorValue.b; region.a = c.ColorValue.a; break; } } } #endregion region.UpdateOffset(); attachment = region; } break; case AttachmentType.Boundingbox: { BoundingBoxAttachment box = attachmentLoader.NewBoundingBoxAttachment(skin, entry.AttachmentName); if (box == null) { Debug.LogError("BoundingBoxAttachment New Fail:" + entry.AttachmentName); continue; } #region Box数据填充 Int32 vertexCount = 0; if (entry.IntValues != null && entry.IntValues.Count > 0) { foreach (var i in entry.IntValues) { if (i.Key.Equals("vertexCount")) { vertexCount = i.IntValue; break; } } } foreach (var fs in entry.FloatArrayValues) { if (fs.Key.Equals("vertices")) { ReadVertices(fs, box, vertexCount << 1, scale); break; } } #endregion attachment = box; } break; case AttachmentType.Mesh: case AttachmentType.Linkedmesh: { MeshAttachment mesh = attachmentLoader.NewMeshAttachment(skin, entry.AttachmentName, entry.PathName); if (mesh == null) { Debug.LogError("MeshAttachment New Fail:" + entry.AttachmentName + "," + entry.PathName); continue; } #region Mesh数据填充 mesh.Path = entry.PathName; if (entry.ColorValues != null && entry.ColorValues.Count > 0) { foreach (var c in entry.ColorValues) { if (c.Key.Equals("color")) { mesh.r = c.ColorValue.r; mesh.g = c.ColorValue.g; mesh.b = c.ColorValue.b; mesh.a = c.ColorValue.a; break; } } } Single w = 0, h = 0; foreach (var f in entry.FloatValues) { switch (f.Key) { case "width": w = f.FloatValue * scale; break; case "height": h = f.FloatValue * scale; break; } } mesh.Width = w; mesh.Height = h; String parentStr = null, skinStr = null; Boolean deform = true; if (entry.StringValues != null && entry.StringValues.Count > 0) { foreach (var ss in entry.StringValues) { switch (ss.Key) { case "parent": parentStr = ss.StringValue; break; case "skin": skinStr = ss.StringValue; break; } } } if (entry.BoolValues != null && entry.BoolValues.Count > 0) { foreach (var b in entry.BoolValues) { if (b.Key.Equals("deform")) { deform = b.BooleanValue; break; } } } if (parentStr != null) { mesh.InheritDeform = deform; linkedMeshes.Add(new SkeletonJson.LinkedMesh(mesh, skinStr, slotIndex, parentStr)); } KeyFloatArrayPair kfap_Vs = new KeyFloatArrayPair(); Single[] uvs = null; foreach (var fs in entry.FloatArrayValues) { switch (fs.Key) { case "vertices": kfap_Vs = fs; break; case "uvs": uvs = fs.FloatArrayValue.ToArray(); break; } } ReadVertices(kfap_Vs, mesh, uvs.Length, scale); Int32[] triangles = null, edges = null; if (entry.IntArrayValues != null && entry.IntArrayValues.Count > 0) { foreach (var i32s in entry.IntArrayValues) { switch (i32s.Key) { case "triangles": triangles = i32s.IntArrayValue.ToArray(); break; case "edges": edges = i32s.IntArrayValue.ToArray(); break; } } } mesh.triangles = triangles; mesh.regionUVs = uvs; mesh.UpdateUVs(); Int32 hull = 0; if (entry.IntValues != null && entry.IntValues.Count > 0) { foreach (var i in entry.IntValues) { if (i.Key.Equals("hull")) { hull = i.IntValue * 2; break; } } } if (hull != 0) { mesh.HullLength = hull; } if (edges != null) { mesh.Edges = edges; } #endregion attachment = mesh; } break; case AttachmentType.Path: { PathAttachment pathAttachment = attachmentLoader.NewPathAttachment(skin, entry.AttachmentName); if (pathAttachment == null) { Debug.LogError("PathAttachment New Fail:" + entry.AttachmentName); continue; } #region Path填充数据 Boolean closed = false, constantSpeed = false; if (entry.BoolValues != null && entry.BoolValues.Count > 0) { foreach (var b in entry.BoolValues) { switch (b.Key) { case "closed": closed = b.BooleanValue; break; case "constantSpeed": constantSpeed = b.BooleanValue; break; } } } pathAttachment.closed = closed; pathAttachment.constantSpeed = constantSpeed; Int32 vertexCount = 0; if (entry.IntValues != null && entry.IntValues.Count > 0) { foreach (var i in entry.IntValues) { if (i.Key.Equals("vertexCount")) { vertexCount = i.IntValue; break; } } } foreach (var fs in entry.FloatArrayValues) { switch (fs.Key) { case "vertices": ReadVertices(fs, pathAttachment, vertexCount << 1, scale); break; case "lengths": var count = fs.FloatArrayValue.Count; pathAttachment.lengths = new Single[count]; for (var idx = 0; idx < count; idx++) { pathAttachment.lengths[idx] = fs.FloatArrayValue[idx] * scale; } break; } } #endregion attachment = pathAttachment; } break; case AttachmentType.Point: { PointAttachment point = attachmentLoader.NewPointAttachment(skin, entry.AttachmentName); if (point == null) { Debug.LogError("PointAttachment New Fail:" + entry.AttachmentName); continue; } #region Point填充数据 Single x = 0, y = 0, r = 0; if (entry.FloatValues != null && entry.FloatValues.Count > 0) { foreach (var f in entry.FloatValues) { switch (f.Key) { case "x": x = f.FloatValue * scale; break; case "y": y = f.FloatValue * scale; break; case "rotation": r = f.FloatValue; break; } } } point.x = x; point.y = y; point.rotation = r; #endregion attachment = point; } break; case AttachmentType.Clipping: { ClippingAttachment clip = attachmentLoader.NewClippingAttachment(skin, entry.AttachmentName); if (clip == null) { Debug.LogError("ClippingAttachment New Fail:" + entry.AttachmentName); continue; } #region Clipping填充数据 String end = null; if (entry.StringValues != null && entry.StringValues.Count > 0) { foreach (var s in entry.StringValues) { if (s.Key.Equals("end")) { end = s.StringValue; break; } } } if (end != null) { SlotData sd = skeleton.Data.FindSlot(end); if (sd == null) { throw new Exception("Clipping end slot not found: " + end); } clip.EndSlot = sd; } Int32 vertexCount = 0; if (entry.IntValues != null && entry.IntValues.Count > 0) { foreach (var i in entry.IntValues) { if (i.Key.Equals("vertexCount")) { vertexCount = i.IntValue; break; } } } foreach (var fs in entry.FloatArrayValues) { if (fs.Key.Equals("vertices")) { ReadVertices(fs, clip, vertexCount << 1, scale); break; } } #endregion attachment = clip; } break; default: break; } skin.SetAttachment(slot.SlotName, entry.AttachmentName, attachment, skeleton); } } // Linked meshes. for (int i = 0, n = linkedMeshes.Count; i < n; i++) { var linkedMesh = linkedMeshes[i]; Skin sk = linkedMesh.skin == null ? skeleton.Data.defaultSkin : skeleton.Data.FindSkin(linkedMesh.skin); if (sk == null) { throw new Exception("Slot not found: " + linkedMesh.skin); } Attachment parent = sk.GetAttachment(linkedMesh.slotIndex, linkedMesh.parent); if (parent == null) { throw new Exception("Parent mesh not found: " + linkedMesh.parent); } linkedMesh.mesh.ParentMesh = (MeshAttachment)parent; linkedMesh.mesh.UpdateUVs(); } skeleton.Data.Skins.Add(skin); return(skin); }
/// <summary> /// Creates a new RegionAttachment from a given AtlasRegion.</summary> public static RegionAttachment ToRegionAttachment (this AtlasRegion region, string attachmentName, float scale = 0.01f) { if (string.IsNullOrEmpty(attachmentName)) throw new System.ArgumentException("attachmentName can't be null or empty.", "attachmentName"); if (region == null) throw new System.ArgumentNullException("region"); // (AtlasAttachmentLoader.cs) var attachment = new RegionAttachment(attachmentName); attachment.RendererObject = region; attachment.SetUVs(region.u, region.v, region.u2, region.v2, region.rotate); attachment.regionOffsetX = region.offsetX; attachment.regionOffsetY = region.offsetY; attachment.regionWidth = region.width; attachment.regionHeight = region.height; attachment.regionOriginalWidth = region.originalWidth; attachment.regionOriginalHeight = region.originalHeight; attachment.Path = region.name; attachment.scaleX = 1; attachment.scaleY = 1; attachment.rotation = 0; // pass OriginalWidth and OriginalHeight because UpdateOffset uses it in its calculation. attachment.width = attachment.regionOriginalWidth * scale; attachment.height = attachment.regionOriginalHeight * scale; attachment.SetColor(Color.white); attachment.UpdateOffset(); return attachment; }
public RegionAttachment NewRegionAttachment(Skin skin, string name, string path) { RegionAttachment attachment = new RegionAttachment(name); Texture2D tex = sprite.texture; int instanceId = tex.GetInstanceID(); AtlasRegion atlasRegion; bool cachedMaterialExists = atlasTable.TryGetValue(instanceId, out atlasRegion); if (!cachedMaterialExists) { // Setup new material. var material = new Material(shader); if (sprite.packed) { material.name = "Unity Packed Sprite Material"; } else { material.name = sprite.name + " Sprite Material"; } material.mainTexture = tex; // Create faux-region to play nice with SkeletonRenderer. atlasRegion = new AtlasRegion(); var page = new AtlasPage(); page.rendererObject = material; atlasRegion.page = page; // Cache it. atlasTable[instanceId] = atlasRegion; } Rect texRect = sprite.textureRect; // Normalize rect to UV space of packed atlas texRect.x = Mathf.InverseLerp(0, tex.width, texRect.x); texRect.y = Mathf.InverseLerp(0, tex.height, texRect.y); texRect.width = Mathf.InverseLerp(0, tex.width, texRect.width); texRect.height = Mathf.InverseLerp(0, tex.height, texRect.height); Bounds bounds = sprite.bounds; Vector2 boundsMin = bounds.min, boundsMax = bounds.max; Vector2 size = bounds.size; float spriteUnitsPerPixel = 1f / sprite.pixelsPerUnit; bool rotated = false; if (sprite.packed) { rotated = sprite.packingRotation == SpritePackingRotation.Any; } attachment.SetUVs(texRect.xMin, texRect.yMax, texRect.xMax, texRect.yMin, rotated); attachment.RendererObject = atlasRegion; attachment.SetColor(Color.white); attachment.ScaleX = 1; attachment.ScaleY = 1; attachment.RegionOffsetX = sprite.rect.width * (0.5f - InverseLerp(boundsMin.x, boundsMax.x, 0)) * spriteUnitsPerPixel; attachment.RegionOffsetY = sprite.rect.height * (0.5f - InverseLerp(boundsMin.y, boundsMax.y, 0)) * spriteUnitsPerPixel; attachment.Width = size.x; attachment.Height = size.y; attachment.RegionWidth = size.x; attachment.RegionHeight = size.y; attachment.RegionOriginalWidth = size.x; attachment.RegionOriginalHeight = size.y; attachment.UpdateOffset(); return(attachment); }