mirror of
https://github.com/EsotericSoftware/spine-runtimes.git
synced 2026-02-06 07:14:55 +08:00
[unity] Split the file AttachmentTools into 4 new files for each contained class.
This commit is contained in:
parent
ddf5082dc4
commit
dad97ecc06
@ -183,6 +183,7 @@
|
||||
* Moved `Modules/AnimationMatchModifier` directory to `Spine Examples/Scripts/MecanimAnimationMatchModifier`.
|
||||
* Moved `SkeletonRagdoll` and `SkeletonRagdoll2D` components from `Modules/Ragdoll` directory to `Spine Examples/Scripts/Sample Components/SkeletonUtility Modules`.
|
||||
* Moved `AttachmentTools.cs` to `Utility` directory.
|
||||
* Split the file `AttachmentTools` into 4 new files for each contained class. No namespace or other API changes performed.
|
||||
* Moved `SkeletonExtensions.cs` to `Utility` directory.
|
||||
* Moved `Modules/YieldInstructions` directory to `Utility/YieldInstructions`.
|
||||
* Moved corresponding editor scripts of the above components to restructured directories as well.
|
||||
|
||||
@ -32,179 +32,7 @@ using System.Collections.Generic;
|
||||
using System.Collections;
|
||||
|
||||
namespace Spine.Unity.AttachmentTools {
|
||||
public static class AttachmentRegionExtensions {
|
||||
#region GetRegion
|
||||
/// <summary>
|
||||
/// Tries to get the region (image) of a renderable attachment. If the attachment is not renderable, it returns null.</summary>
|
||||
public static AtlasRegion GetRegion (this Attachment attachment) {
|
||||
var renderableAttachment = attachment as IHasRendererObject;
|
||||
if (renderableAttachment != null)
|
||||
return renderableAttachment.RendererObject as AtlasRegion;
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/// <summary>Gets the region (image) of a RegionAttachment</summary>
|
||||
public static AtlasRegion GetRegion (this RegionAttachment regionAttachment) {
|
||||
return regionAttachment.RendererObject as AtlasRegion;
|
||||
}
|
||||
|
||||
/// <summary>Gets the region (image) of a MeshAttachment</summary>
|
||||
public static AtlasRegion GetRegion (this MeshAttachment meshAttachment) {
|
||||
return meshAttachment.RendererObject as AtlasRegion;
|
||||
}
|
||||
#endregion
|
||||
#region SetRegion
|
||||
/// <summary>
|
||||
/// Tries to set the region (image) of a renderable attachment. If the attachment is not renderable, nothing is applied.</summary>
|
||||
public static void SetRegion (this Attachment attachment, AtlasRegion region, bool updateOffset = true) {
|
||||
var regionAttachment = attachment as RegionAttachment;
|
||||
if (regionAttachment != null)
|
||||
regionAttachment.SetRegion(region, updateOffset);
|
||||
|
||||
var meshAttachment = attachment as MeshAttachment;
|
||||
if (meshAttachment != null)
|
||||
meshAttachment.SetRegion(region, updateOffset);
|
||||
}
|
||||
|
||||
/// <summary>Sets the region (image) of a RegionAttachment</summary>
|
||||
public static void SetRegion (this RegionAttachment attachment, AtlasRegion region, bool updateOffset = true) {
|
||||
if (region == null) throw new System.ArgumentNullException("region");
|
||||
|
||||
// (AtlasAttachmentLoader.cs)
|
||||
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>Sets the region (image) of a MeshAttachment</summary>
|
||||
public static void SetRegion (this MeshAttachment attachment, AtlasRegion region, bool updateUVs = true) {
|
||||
if (region == null) throw new System.ArgumentNullException("region");
|
||||
|
||||
// (AtlasAttachmentLoader.cs)
|
||||
attachment.RendererObject = region;
|
||||
attachment.RegionU = region.u;
|
||||
attachment.RegionV = region.v;
|
||||
attachment.RegionU2 = region.u2;
|
||||
attachment.RegionV2 = region.v2;
|
||||
attachment.RegionRotate = 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 (updateUVs) attachment.UpdateUVs();
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region Runtime RegionAttachments
|
||||
/// <summary>
|
||||
/// Creates a RegionAttachment based on a sprite. This method creates a real, usable AtlasRegion. That AtlasRegion uses a new AtlasPage with the Material provided./// </summary>
|
||||
public static RegionAttachment ToRegionAttachment (this Sprite sprite, Material material, float rotation = 0f) {
|
||||
return sprite.ToRegionAttachment(material.ToSpineAtlasPage(), rotation);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates a RegionAttachment based on a sprite. This method creates a real, usable AtlasRegion. That AtlasRegion uses the AtlasPage provided./// </summary>
|
||||
public static RegionAttachment ToRegionAttachment (this Sprite sprite, AtlasPage page, float rotation = 0f) {
|
||||
if (sprite == null) throw new System.ArgumentNullException("sprite");
|
||||
if (page == null) throw new System.ArgumentNullException("page");
|
||||
var region = sprite.ToAtlasRegion(page);
|
||||
var unitsPerPixel = 1f / sprite.pixelsPerUnit;
|
||||
return region.ToRegionAttachment(sprite.name, unitsPerPixel, rotation);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates a Spine.AtlasRegion that uses a premultiplied alpha duplicate texture of the Sprite's texture data. Returns a RegionAttachment that uses it. Use this if you plan to use a premultiply alpha shader such as "Spine/Skeleton"</summary>
|
||||
public static RegionAttachment ToRegionAttachmentPMAClone (this Sprite sprite, Shader shader, TextureFormat textureFormat = AtlasUtilities.SpineTextureFormat, bool mipmaps = AtlasUtilities.UseMipMaps, Material materialPropertySource = null, float rotation = 0f) {
|
||||
if (sprite == null) throw new System.ArgumentNullException("sprite");
|
||||
if (shader == null) throw new System.ArgumentNullException("shader");
|
||||
var region = sprite.ToAtlasRegionPMAClone(shader, textureFormat, mipmaps, materialPropertySource);
|
||||
var unitsPerPixel = 1f / sprite.pixelsPerUnit;
|
||||
return region.ToRegionAttachment(sprite.name, unitsPerPixel, rotation);
|
||||
}
|
||||
|
||||
public static RegionAttachment ToRegionAttachmentPMAClone (this Sprite sprite, Material materialPropertySource, TextureFormat textureFormat = AtlasUtilities.SpineTextureFormat, bool mipmaps = AtlasUtilities.UseMipMaps, float rotation = 0f) {
|
||||
return sprite.ToRegionAttachmentPMAClone(materialPropertySource.shader, textureFormat, mipmaps, materialPropertySource, rotation);
|
||||
}
|
||||
|
||||
/// <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;
|
||||
}
|
||||
|
||||
/// <summary> Sets the scale. Call regionAttachment.UpdateOffset to apply the change.</summary>
|
||||
public static void SetScale (this RegionAttachment regionAttachment, Vector2 scale) {
|
||||
regionAttachment.scaleX = scale.x;
|
||||
regionAttachment.scaleY = scale.y;
|
||||
}
|
||||
|
||||
/// <summary> Sets the scale. Call regionAttachment.UpdateOffset to apply the change.</summary>
|
||||
public static void SetScale (this RegionAttachment regionAttachment, float x, float y) {
|
||||
regionAttachment.scaleX = x;
|
||||
regionAttachment.scaleY = y;
|
||||
}
|
||||
|
||||
/// <summary> Sets the position offset. Call regionAttachment.UpdateOffset to apply the change.</summary>
|
||||
public static void SetPositionOffset (this RegionAttachment regionAttachment, Vector2 offset) {
|
||||
regionAttachment.x = offset.x;
|
||||
regionAttachment.y = offset.y;
|
||||
}
|
||||
|
||||
/// <summary> Sets the position offset. Call regionAttachment.UpdateOffset to apply the change.</summary>
|
||||
public static void SetPositionOffset (this RegionAttachment regionAttachment, float x, float y) {
|
||||
regionAttachment.x = x;
|
||||
regionAttachment.y = y;
|
||||
}
|
||||
|
||||
/// <summary> Sets the rotation. Call regionAttachment.UpdateOffset to apply the change.</summary>
|
||||
public static void SetRotation (this RegionAttachment regionAttachment, float rotation) {
|
||||
regionAttachment.rotation = rotation;
|
||||
}
|
||||
#endregion
|
||||
}
|
||||
|
||||
|
||||
public static class AtlasUtilities {
|
||||
internal const TextureFormat SpineTextureFormat = TextureFormat.RGBA32;
|
||||
internal const float DefaultMipmapBias = -0.5f;
|
||||
@ -753,212 +581,4 @@ namespace Spine.Unity.AttachmentTools {
|
||||
return (value - a) / (b - a);
|
||||
}
|
||||
}
|
||||
|
||||
public static class SkinUtilities {
|
||||
|
||||
#region Skeleton Skin Extensions
|
||||
/// <summary>
|
||||
/// Convenience method for duplicating a skeleton's current active skin so changes to it will not affect other skeleton instances. .</summary>
|
||||
public static Skin UnshareSkin (this Skeleton skeleton, bool includeDefaultSkin, bool unshareAttachments, AnimationState state = null) {
|
||||
// 1. Copy the current skin and set the skeleton's skin to the new one.
|
||||
var newSkin = skeleton.GetClonedSkin("cloned skin", includeDefaultSkin, unshareAttachments, true);
|
||||
skeleton.SetSkin(newSkin);
|
||||
|
||||
// 2. Apply correct attachments: skeleton.SetToSetupPose + animationState.Apply
|
||||
if (state != null) {
|
||||
skeleton.SetToSetupPose();
|
||||
state.Apply(skeleton);
|
||||
}
|
||||
|
||||
// 3. Return unshared skin.
|
||||
return newSkin;
|
||||
}
|
||||
|
||||
public static Skin GetClonedSkin (this Skeleton skeleton, string newSkinName, bool includeDefaultSkin = false, bool cloneAttachments = false, bool cloneMeshesAsLinked = true) {
|
||||
var newSkin = new Skin(newSkinName); // may have null name. Harmless.
|
||||
var defaultSkin = skeleton.data.DefaultSkin;
|
||||
var activeSkin = skeleton.skin;
|
||||
|
||||
if (includeDefaultSkin)
|
||||
defaultSkin.CopyTo(newSkin, true, cloneAttachments, cloneMeshesAsLinked);
|
||||
|
||||
if (activeSkin != null)
|
||||
activeSkin.CopyTo(newSkin, true, cloneAttachments, cloneMeshesAsLinked);
|
||||
|
||||
return newSkin;
|
||||
}
|
||||
#endregion
|
||||
|
||||
/// <summary>
|
||||
/// Gets a shallow copy of the skin. The cloned skin's attachments are shared with the original skin.</summary>
|
||||
public static Skin GetClone (this Skin original) {
|
||||
var newSkin = new Skin(original.name + " clone");
|
||||
var newSkinAttachments = newSkin.Attachments;
|
||||
|
||||
foreach (DictionaryEntry a in original.Attachments)
|
||||
newSkinAttachments[a.Key] = a.Value;
|
||||
|
||||
return newSkin;
|
||||
}
|
||||
|
||||
/// <summary>Adds an attachment to the skin for the specified slot index and name. If the name already exists for the slot, the previous value is replaced.</summary>
|
||||
public static void SetAttachment (this Skin skin, string slotName, string keyName, Attachment attachment, Skeleton skeleton) {
|
||||
int slotIndex = skeleton.FindSlotIndex(slotName);
|
||||
if (skeleton == null) throw new System.ArgumentNullException("skeleton", "skeleton cannot be null.");
|
||||
if (slotIndex == -1) throw new System.ArgumentException(string.Format("Slot '{0}' does not exist in skeleton.", slotName), "slotName");
|
||||
skin.SetAttachment(slotIndex, keyName, attachment);
|
||||
}
|
||||
|
||||
/// <summary>Adds skin items from another skin. For items that already exist, the previous values are replaced.</summary>
|
||||
public static void AddAttachments (this Skin skin, Skin otherSkin) {
|
||||
if (otherSkin == null) return;
|
||||
otherSkin.CopyTo(skin, true, false);
|
||||
}
|
||||
|
||||
/// <summary>Gets an attachment from the skin for the specified slot index and name.</summary>
|
||||
public static Attachment GetAttachment (this Skin skin, string slotName, string keyName, Skeleton skeleton) {
|
||||
int slotIndex = skeleton.FindSlotIndex(slotName);
|
||||
if (skeleton == null) throw new System.ArgumentNullException("skeleton", "skeleton cannot be null.");
|
||||
if (slotIndex == -1) throw new System.ArgumentException(string.Format("Slot '{0}' does not exist in skeleton.", slotName), "slotName");
|
||||
return skin.GetAttachment(slotIndex, keyName);
|
||||
}
|
||||
|
||||
/// <summary>Adds an attachment to the skin for the specified slot index and name. If the name already exists for the slot, the previous value is replaced.</summary>
|
||||
public static void SetAttachment (this Skin skin, int slotIndex, string keyName, Attachment attachment) {
|
||||
skin.SetAttachment(slotIndex, keyName, attachment);
|
||||
}
|
||||
|
||||
public static void RemoveAttachment (this Skin skin, string slotName, string keyName, SkeletonData skeletonData) {
|
||||
int slotIndex = skeletonData.FindSlotIndex(slotName);
|
||||
if (skeletonData == null) throw new System.ArgumentNullException("skeletonData", "skeletonData cannot be null.");
|
||||
if (slotIndex == -1) throw new System.ArgumentException(string.Format("Slot '{0}' does not exist in skeleton.", slotName), "slotName");
|
||||
skin.RemoveAttachment(slotIndex, keyName);
|
||||
}
|
||||
|
||||
public static void Clear (this Skin skin) {
|
||||
skin.Attachments.Clear();
|
||||
}
|
||||
|
||||
//[System.Obsolete]
|
||||
public static void Append (this Skin destination, Skin source) {
|
||||
source.CopyTo(destination, true, false);
|
||||
}
|
||||
|
||||
public static void CopyTo (this Skin source, Skin destination, bool overwrite, bool cloneAttachments, bool cloneMeshesAsLinked = true) {
|
||||
var sourceAttachments = source.Attachments;
|
||||
var destinationAttachments = destination.Attachments;
|
||||
|
||||
if (cloneAttachments) {
|
||||
if (overwrite) {
|
||||
foreach (DictionaryEntry e in sourceAttachments)
|
||||
destinationAttachments[e.Key] = ((Attachment)e.Value).GetCopy(cloneMeshesAsLinked);
|
||||
} else {
|
||||
foreach (DictionaryEntry e in sourceAttachments) {
|
||||
if (destinationAttachments.Contains(e.Key)) continue;
|
||||
destinationAttachments.Add(e.Key, ((Attachment)e.Value).GetCopy(cloneMeshesAsLinked));
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (overwrite) {
|
||||
foreach (DictionaryEntry e in sourceAttachments)
|
||||
destinationAttachments[e.Key] = e.Value;
|
||||
} else {
|
||||
foreach (DictionaryEntry e in sourceAttachments) {
|
||||
if (destinationAttachments.Contains(e.Key)) continue;
|
||||
destinationAttachments.Add(e.Key, e.Value);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
public static class AttachmentCloneExtensions {
|
||||
/// <summary>
|
||||
/// Clones the attachment.</summary>
|
||||
public static Attachment GetCopy (this Attachment o, bool cloneMeshesAsLinked) {
|
||||
var meshAttachment = o as MeshAttachment;
|
||||
if (meshAttachment != null && cloneMeshesAsLinked)
|
||||
return meshAttachment.NewLinkedMesh();
|
||||
return o.Copy();
|
||||
}
|
||||
|
||||
#region Runtime Linked MeshAttachments
|
||||
/// <summary>
|
||||
/// Returns a new linked mesh linked to this MeshAttachment. It will be mapped to the AtlasRegion provided.</summary>
|
||||
public static MeshAttachment GetLinkedMesh (this MeshAttachment o, string newLinkedMeshName, AtlasRegion region) {
|
||||
if (region == null) throw new System.ArgumentNullException("region");
|
||||
MeshAttachment mesh = o.NewLinkedMesh();
|
||||
mesh.SetRegion(region, false);
|
||||
return mesh;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns a new linked mesh linked to this MeshAttachment. It will be mapped to an AtlasRegion generated from a Sprite. The AtlasRegion will be mapped to a new Material based on the shader.
|
||||
/// For better caching and batching, use GetLinkedMesh(string, AtlasRegion, bool)</summary>
|
||||
public static MeshAttachment GetLinkedMesh (this MeshAttachment o, Sprite sprite, Shader shader, Material materialPropertySource = null) {
|
||||
var m = new Material(shader);
|
||||
if (materialPropertySource != null) {
|
||||
m.CopyPropertiesFromMaterial(materialPropertySource);
|
||||
m.shaderKeywords = materialPropertySource.shaderKeywords;
|
||||
}
|
||||
return o.GetLinkedMesh(sprite.name, sprite.ToAtlasRegion());
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns a new linked mesh linked to this MeshAttachment. It will be mapped to an AtlasRegion generated from a Sprite. The AtlasRegion will be mapped to a new Material based on the shader.
|
||||
/// For better caching and batching, use GetLinkedMesh(string, AtlasRegion, bool)</summary>
|
||||
public static MeshAttachment GetLinkedMesh (this MeshAttachment o, Sprite sprite, Material materialPropertySource) {
|
||||
return o.GetLinkedMesh(sprite, materialPropertySource.shader, materialPropertySource);
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region RemappedClone Convenience Methods
|
||||
/// <summary>
|
||||
/// Gets a clone of the attachment remapped with a sprite image.</summary>
|
||||
/// <returns>The remapped clone.</returns>
|
||||
/// <param name="o">The original attachment.</param>
|
||||
/// <param name="sprite">The sprite whose texture to use.</param>
|
||||
/// <param name="sourceMaterial">The source material used to copy the shader and material properties from.</param>
|
||||
/// <param name="premultiplyAlpha">If <c>true</c>, a premultiply alpha clone of the original texture will be created.</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>
|
||||
public static Attachment GetRemappedClone (this Attachment o, Sprite sprite, Material sourceMaterial, bool premultiplyAlpha = true, bool cloneMeshAsLinked = true, bool useOriginalRegionSize = false) {
|
||||
var atlasRegion = premultiplyAlpha ? sprite.ToAtlasRegionPMAClone(sourceMaterial) : sprite.ToAtlasRegion(new Material(sourceMaterial) { mainTexture = sprite.texture } );
|
||||
return o.GetRemappedClone(atlasRegion, cloneMeshAsLinked, useOriginalRegionSize, 1f/sprite.pixelsPerUnit);
|
||||
}
|
||||
|
||||
/// <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.GetCopy(true); // Non-renderable Attachments will return as normal cloned attachments.
|
||||
}
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
@ -1,6 +1,6 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 8dd46dbf979fcb7459246cd37aad09ef
|
||||
timeCreated: 1478437807
|
||||
guid: 25ceef568a3dad448bf8a14fcc326964
|
||||
timeCreated: 1563321428
|
||||
licenseType: Free
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
@ -0,0 +1,123 @@
|
||||
/******************************************************************************
|
||||
* Spine Runtimes License Agreement
|
||||
* Last updated May 1, 2019. Replaces all prior versions.
|
||||
*
|
||||
* Copyright (c) 2013-2019, Esoteric Software LLC
|
||||
*
|
||||
* Integration of the Spine Runtimes into software or otherwise creating
|
||||
* derivative works of the Spine Runtimes is permitted under the terms and
|
||||
* conditions of Section 2 of the Spine Editor License Agreement:
|
||||
* http://esotericsoftware.com/spine-editor-license
|
||||
*
|
||||
* Otherwise, it is permitted to integrate the Spine Runtimes into software
|
||||
* or otherwise create derivative works of the Spine Runtimes (collectively,
|
||||
* "Products"), provided that each user of the Products must obtain their own
|
||||
* Spine Editor license and redistribution of the Products in any form must
|
||||
* include this license and copyright notice.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY ESOTERIC SOFTWARE LLC "AS IS" AND ANY EXPRESS
|
||||
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
|
||||
* NO EVENT SHALL ESOTERIC SOFTWARE LLC BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, BUSINESS
|
||||
* INTERRUPTION, OR LOSS OF USE, DATA, OR PROFITS) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
|
||||
* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*****************************************************************************/
|
||||
|
||||
using UnityEngine;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections;
|
||||
|
||||
namespace Spine.Unity.AttachmentTools {
|
||||
|
||||
public static class AttachmentCloneExtensions {
|
||||
/// <summary>
|
||||
/// Clones the attachment.</summary>
|
||||
public static Attachment GetCopy (this Attachment o, bool cloneMeshesAsLinked) {
|
||||
var meshAttachment = o as MeshAttachment;
|
||||
if (meshAttachment != null && cloneMeshesAsLinked)
|
||||
return meshAttachment.NewLinkedMesh();
|
||||
return o.Copy();
|
||||
}
|
||||
|
||||
#region Runtime Linked MeshAttachments
|
||||
/// <summary>
|
||||
/// Returns a new linked mesh linked to this MeshAttachment. It will be mapped to the AtlasRegion provided.</summary>
|
||||
public static MeshAttachment GetLinkedMesh (this MeshAttachment o, string newLinkedMeshName, AtlasRegion region) {
|
||||
if (region == null) throw new System.ArgumentNullException("region");
|
||||
MeshAttachment mesh = o.NewLinkedMesh();
|
||||
mesh.SetRegion(region, false);
|
||||
return mesh;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns a new linked mesh linked to this MeshAttachment. It will be mapped to an AtlasRegion generated from a Sprite. The AtlasRegion will be mapped to a new Material based on the shader.
|
||||
/// For better caching and batching, use GetLinkedMesh(string, AtlasRegion, bool)</summary>
|
||||
public static MeshAttachment GetLinkedMesh (this MeshAttachment o, Sprite sprite, Shader shader, Material materialPropertySource = null) {
|
||||
var m = new Material(shader);
|
||||
if (materialPropertySource != null) {
|
||||
m.CopyPropertiesFromMaterial(materialPropertySource);
|
||||
m.shaderKeywords = materialPropertySource.shaderKeywords;
|
||||
}
|
||||
return o.GetLinkedMesh(sprite.name, sprite.ToAtlasRegion());
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns a new linked mesh linked to this MeshAttachment. It will be mapped to an AtlasRegion generated from a Sprite. The AtlasRegion will be mapped to a new Material based on the shader.
|
||||
/// For better caching and batching, use GetLinkedMesh(string, AtlasRegion, bool)</summary>
|
||||
public static MeshAttachment GetLinkedMesh (this MeshAttachment o, Sprite sprite, Material materialPropertySource) {
|
||||
return o.GetLinkedMesh(sprite, materialPropertySource.shader, materialPropertySource);
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region RemappedClone Convenience Methods
|
||||
/// <summary>
|
||||
/// Gets a clone of the attachment remapped with a sprite image.</summary>
|
||||
/// <returns>The remapped clone.</returns>
|
||||
/// <param name="o">The original attachment.</param>
|
||||
/// <param name="sprite">The sprite whose texture to use.</param>
|
||||
/// <param name="sourceMaterial">The source material used to copy the shader and material properties from.</param>
|
||||
/// <param name="premultiplyAlpha">If <c>true</c>, a premultiply alpha clone of the original texture will be created.</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>
|
||||
public static Attachment GetRemappedClone (this Attachment o, Sprite sprite, Material sourceMaterial, bool premultiplyAlpha = true, bool cloneMeshAsLinked = true, bool useOriginalRegionSize = false) {
|
||||
var atlasRegion = premultiplyAlpha ? sprite.ToAtlasRegionPMAClone(sourceMaterial) : sprite.ToAtlasRegion(new Material(sourceMaterial) { mainTexture = sprite.texture } );
|
||||
return o.GetRemappedClone(atlasRegion, cloneMeshAsLinked, useOriginalRegionSize, 1f/sprite.pixelsPerUnit);
|
||||
}
|
||||
|
||||
/// <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.GetCopy(true); // Non-renderable Attachments will return as normal cloned attachments.
|
||||
}
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 3431ed563b2c62f4c8c974a99365ba52
|
||||
timeCreated: 1563321428
|
||||
licenseType: Free
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@ -0,0 +1,207 @@
|
||||
/******************************************************************************
|
||||
* Spine Runtimes License Agreement
|
||||
* Last updated May 1, 2019. Replaces all prior versions.
|
||||
*
|
||||
* Copyright (c) 2013-2019, Esoteric Software LLC
|
||||
*
|
||||
* Integration of the Spine Runtimes into software or otherwise creating
|
||||
* derivative works of the Spine Runtimes is permitted under the terms and
|
||||
* conditions of Section 2 of the Spine Editor License Agreement:
|
||||
* http://esotericsoftware.com/spine-editor-license
|
||||
*
|
||||
* Otherwise, it is permitted to integrate the Spine Runtimes into software
|
||||
* or otherwise create derivative works of the Spine Runtimes (collectively,
|
||||
* "Products"), provided that each user of the Products must obtain their own
|
||||
* Spine Editor license and redistribution of the Products in any form must
|
||||
* include this license and copyright notice.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY ESOTERIC SOFTWARE LLC "AS IS" AND ANY EXPRESS
|
||||
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
|
||||
* NO EVENT SHALL ESOTERIC SOFTWARE LLC BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, BUSINESS
|
||||
* INTERRUPTION, OR LOSS OF USE, DATA, OR PROFITS) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
|
||||
* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*****************************************************************************/
|
||||
|
||||
using UnityEngine;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections;
|
||||
|
||||
namespace Spine.Unity.AttachmentTools {
|
||||
public static class AttachmentRegionExtensions {
|
||||
#region GetRegion
|
||||
/// <summary>
|
||||
/// Tries to get the region (image) of a renderable attachment. If the attachment is not renderable, it returns null.</summary>
|
||||
public static AtlasRegion GetRegion (this Attachment attachment) {
|
||||
var renderableAttachment = attachment as IHasRendererObject;
|
||||
if (renderableAttachment != null)
|
||||
return renderableAttachment.RendererObject as AtlasRegion;
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/// <summary>Gets the region (image) of a RegionAttachment</summary>
|
||||
public static AtlasRegion GetRegion (this RegionAttachment regionAttachment) {
|
||||
return regionAttachment.RendererObject as AtlasRegion;
|
||||
}
|
||||
|
||||
/// <summary>Gets the region (image) of a MeshAttachment</summary>
|
||||
public static AtlasRegion GetRegion (this MeshAttachment meshAttachment) {
|
||||
return meshAttachment.RendererObject as AtlasRegion;
|
||||
}
|
||||
#endregion
|
||||
#region SetRegion
|
||||
/// <summary>
|
||||
/// Tries to set the region (image) of a renderable attachment. If the attachment is not renderable, nothing is applied.</summary>
|
||||
public static void SetRegion (this Attachment attachment, AtlasRegion region, bool updateOffset = true) {
|
||||
var regionAttachment = attachment as RegionAttachment;
|
||||
if (regionAttachment != null)
|
||||
regionAttachment.SetRegion(region, updateOffset);
|
||||
|
||||
var meshAttachment = attachment as MeshAttachment;
|
||||
if (meshAttachment != null)
|
||||
meshAttachment.SetRegion(region, updateOffset);
|
||||
}
|
||||
|
||||
/// <summary>Sets the region (image) of a RegionAttachment</summary>
|
||||
public static void SetRegion (this RegionAttachment attachment, AtlasRegion region, bool updateOffset = true) {
|
||||
if (region == null) throw new System.ArgumentNullException("region");
|
||||
|
||||
// (AtlasAttachmentLoader.cs)
|
||||
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>Sets the region (image) of a MeshAttachment</summary>
|
||||
public static void SetRegion (this MeshAttachment attachment, AtlasRegion region, bool updateUVs = true) {
|
||||
if (region == null) throw new System.ArgumentNullException("region");
|
||||
|
||||
// (AtlasAttachmentLoader.cs)
|
||||
attachment.RendererObject = region;
|
||||
attachment.RegionU = region.u;
|
||||
attachment.RegionV = region.v;
|
||||
attachment.RegionU2 = region.u2;
|
||||
attachment.RegionV2 = region.v2;
|
||||
attachment.RegionRotate = 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 (updateUVs) attachment.UpdateUVs();
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region Runtime RegionAttachments
|
||||
/// <summary>
|
||||
/// Creates a RegionAttachment based on a sprite. This method creates a real, usable AtlasRegion. That AtlasRegion uses a new AtlasPage with the Material provided./// </summary>
|
||||
public static RegionAttachment ToRegionAttachment (this Sprite sprite, Material material, float rotation = 0f) {
|
||||
return sprite.ToRegionAttachment(material.ToSpineAtlasPage(), rotation);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates a RegionAttachment based on a sprite. This method creates a real, usable AtlasRegion. That AtlasRegion uses the AtlasPage provided./// </summary>
|
||||
public static RegionAttachment ToRegionAttachment (this Sprite sprite, AtlasPage page, float rotation = 0f) {
|
||||
if (sprite == null) throw new System.ArgumentNullException("sprite");
|
||||
if (page == null) throw new System.ArgumentNullException("page");
|
||||
var region = sprite.ToAtlasRegion(page);
|
||||
var unitsPerPixel = 1f / sprite.pixelsPerUnit;
|
||||
return region.ToRegionAttachment(sprite.name, unitsPerPixel, rotation);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates a Spine.AtlasRegion that uses a premultiplied alpha duplicate texture of the Sprite's texture data. Returns a RegionAttachment that uses it. Use this if you plan to use a premultiply alpha shader such as "Spine/Skeleton"</summary>
|
||||
public static RegionAttachment ToRegionAttachmentPMAClone (this Sprite sprite, Shader shader, TextureFormat textureFormat = AtlasUtilities.SpineTextureFormat, bool mipmaps = AtlasUtilities.UseMipMaps, Material materialPropertySource = null, float rotation = 0f) {
|
||||
if (sprite == null) throw new System.ArgumentNullException("sprite");
|
||||
if (shader == null) throw new System.ArgumentNullException("shader");
|
||||
var region = sprite.ToAtlasRegionPMAClone(shader, textureFormat, mipmaps, materialPropertySource);
|
||||
var unitsPerPixel = 1f / sprite.pixelsPerUnit;
|
||||
return region.ToRegionAttachment(sprite.name, unitsPerPixel, rotation);
|
||||
}
|
||||
|
||||
public static RegionAttachment ToRegionAttachmentPMAClone (this Sprite sprite, Material materialPropertySource, TextureFormat textureFormat = AtlasUtilities.SpineTextureFormat, bool mipmaps = AtlasUtilities.UseMipMaps, float rotation = 0f) {
|
||||
return sprite.ToRegionAttachmentPMAClone(materialPropertySource.shader, textureFormat, mipmaps, materialPropertySource, rotation);
|
||||
}
|
||||
|
||||
/// <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;
|
||||
}
|
||||
|
||||
/// <summary> Sets the scale. Call regionAttachment.UpdateOffset to apply the change.</summary>
|
||||
public static void SetScale (this RegionAttachment regionAttachment, Vector2 scale) {
|
||||
regionAttachment.scaleX = scale.x;
|
||||
regionAttachment.scaleY = scale.y;
|
||||
}
|
||||
|
||||
/// <summary> Sets the scale. Call regionAttachment.UpdateOffset to apply the change.</summary>
|
||||
public static void SetScale (this RegionAttachment regionAttachment, float x, float y) {
|
||||
regionAttachment.scaleX = x;
|
||||
regionAttachment.scaleY = y;
|
||||
}
|
||||
|
||||
/// <summary> Sets the position offset. Call regionAttachment.UpdateOffset to apply the change.</summary>
|
||||
public static void SetPositionOffset (this RegionAttachment regionAttachment, Vector2 offset) {
|
||||
regionAttachment.x = offset.x;
|
||||
regionAttachment.y = offset.y;
|
||||
}
|
||||
|
||||
/// <summary> Sets the position offset. Call regionAttachment.UpdateOffset to apply the change.</summary>
|
||||
public static void SetPositionOffset (this RegionAttachment regionAttachment, float x, float y) {
|
||||
regionAttachment.x = x;
|
||||
regionAttachment.y = y;
|
||||
}
|
||||
|
||||
/// <summary> Sets the rotation. Call regionAttachment.UpdateOffset to apply the change.</summary>
|
||||
public static void SetRotation (this RegionAttachment regionAttachment, float rotation) {
|
||||
regionAttachment.rotation = rotation;
|
||||
}
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 7e7eac783deea004e9bc403eca68a7dc
|
||||
timeCreated: 1563321428
|
||||
licenseType: Free
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@ -0,0 +1,156 @@
|
||||
/******************************************************************************
|
||||
* Spine Runtimes License Agreement
|
||||
* Last updated May 1, 2019. Replaces all prior versions.
|
||||
*
|
||||
* Copyright (c) 2013-2019, Esoteric Software LLC
|
||||
*
|
||||
* Integration of the Spine Runtimes into software or otherwise creating
|
||||
* derivative works of the Spine Runtimes is permitted under the terms and
|
||||
* conditions of Section 2 of the Spine Editor License Agreement:
|
||||
* http://esotericsoftware.com/spine-editor-license
|
||||
*
|
||||
* Otherwise, it is permitted to integrate the Spine Runtimes into software
|
||||
* or otherwise create derivative works of the Spine Runtimes (collectively,
|
||||
* "Products"), provided that each user of the Products must obtain their own
|
||||
* Spine Editor license and redistribution of the Products in any form must
|
||||
* include this license and copyright notice.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY ESOTERIC SOFTWARE LLC "AS IS" AND ANY EXPRESS
|
||||
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
|
||||
* NO EVENT SHALL ESOTERIC SOFTWARE LLC BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, BUSINESS
|
||||
* INTERRUPTION, OR LOSS OF USE, DATA, OR PROFITS) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
|
||||
* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*****************************************************************************/
|
||||
|
||||
using UnityEngine;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections;
|
||||
|
||||
namespace Spine.Unity.AttachmentTools {
|
||||
|
||||
public static class SkinUtilities {
|
||||
|
||||
#region Skeleton Skin Extensions
|
||||
/// <summary>
|
||||
/// Convenience method for duplicating a skeleton's current active skin so changes to it will not affect other skeleton instances. .</summary>
|
||||
public static Skin UnshareSkin (this Skeleton skeleton, bool includeDefaultSkin, bool unshareAttachments, AnimationState state = null) {
|
||||
// 1. Copy the current skin and set the skeleton's skin to the new one.
|
||||
var newSkin = skeleton.GetClonedSkin("cloned skin", includeDefaultSkin, unshareAttachments, true);
|
||||
skeleton.SetSkin(newSkin);
|
||||
|
||||
// 2. Apply correct attachments: skeleton.SetToSetupPose + animationState.Apply
|
||||
if (state != null) {
|
||||
skeleton.SetToSetupPose();
|
||||
state.Apply(skeleton);
|
||||
}
|
||||
|
||||
// 3. Return unshared skin.
|
||||
return newSkin;
|
||||
}
|
||||
|
||||
public static Skin GetClonedSkin (this Skeleton skeleton, string newSkinName, bool includeDefaultSkin = false, bool cloneAttachments = false, bool cloneMeshesAsLinked = true) {
|
||||
var newSkin = new Skin(newSkinName); // may have null name. Harmless.
|
||||
var defaultSkin = skeleton.data.DefaultSkin;
|
||||
var activeSkin = skeleton.skin;
|
||||
|
||||
if (includeDefaultSkin)
|
||||
defaultSkin.CopyTo(newSkin, true, cloneAttachments, cloneMeshesAsLinked);
|
||||
|
||||
if (activeSkin != null)
|
||||
activeSkin.CopyTo(newSkin, true, cloneAttachments, cloneMeshesAsLinked);
|
||||
|
||||
return newSkin;
|
||||
}
|
||||
#endregion
|
||||
|
||||
/// <summary>
|
||||
/// Gets a shallow copy of the skin. The cloned skin's attachments are shared with the original skin.</summary>
|
||||
public static Skin GetClone (this Skin original) {
|
||||
var newSkin = new Skin(original.name + " clone");
|
||||
var newSkinAttachments = newSkin.Attachments;
|
||||
|
||||
foreach (DictionaryEntry a in original.Attachments)
|
||||
newSkinAttachments[a.Key] = a.Value;
|
||||
|
||||
return newSkin;
|
||||
}
|
||||
|
||||
/// <summary>Adds an attachment to the skin for the specified slot index and name. If the name already exists for the slot, the previous value is replaced.</summary>
|
||||
public static void SetAttachment (this Skin skin, string slotName, string keyName, Attachment attachment, Skeleton skeleton) {
|
||||
int slotIndex = skeleton.FindSlotIndex(slotName);
|
||||
if (skeleton == null) throw new System.ArgumentNullException("skeleton", "skeleton cannot be null.");
|
||||
if (slotIndex == -1) throw new System.ArgumentException(string.Format("Slot '{0}' does not exist in skeleton.", slotName), "slotName");
|
||||
skin.SetAttachment(slotIndex, keyName, attachment);
|
||||
}
|
||||
|
||||
/// <summary>Adds skin items from another skin. For items that already exist, the previous values are replaced.</summary>
|
||||
public static void AddAttachments (this Skin skin, Skin otherSkin) {
|
||||
if (otherSkin == null) return;
|
||||
otherSkin.CopyTo(skin, true, false);
|
||||
}
|
||||
|
||||
/// <summary>Gets an attachment from the skin for the specified slot index and name.</summary>
|
||||
public static Attachment GetAttachment (this Skin skin, string slotName, string keyName, Skeleton skeleton) {
|
||||
int slotIndex = skeleton.FindSlotIndex(slotName);
|
||||
if (skeleton == null) throw new System.ArgumentNullException("skeleton", "skeleton cannot be null.");
|
||||
if (slotIndex == -1) throw new System.ArgumentException(string.Format("Slot '{0}' does not exist in skeleton.", slotName), "slotName");
|
||||
return skin.GetAttachment(slotIndex, keyName);
|
||||
}
|
||||
|
||||
/// <summary>Adds an attachment to the skin for the specified slot index and name. If the name already exists for the slot, the previous value is replaced.</summary>
|
||||
public static void SetAttachment (this Skin skin, int slotIndex, string keyName, Attachment attachment) {
|
||||
skin.SetAttachment(slotIndex, keyName, attachment);
|
||||
}
|
||||
|
||||
public static void RemoveAttachment (this Skin skin, string slotName, string keyName, SkeletonData skeletonData) {
|
||||
int slotIndex = skeletonData.FindSlotIndex(slotName);
|
||||
if (skeletonData == null) throw new System.ArgumentNullException("skeletonData", "skeletonData cannot be null.");
|
||||
if (slotIndex == -1) throw new System.ArgumentException(string.Format("Slot '{0}' does not exist in skeleton.", slotName), "slotName");
|
||||
skin.RemoveAttachment(slotIndex, keyName);
|
||||
}
|
||||
|
||||
public static void Clear (this Skin skin) {
|
||||
skin.Attachments.Clear();
|
||||
}
|
||||
|
||||
//[System.Obsolete]
|
||||
public static void Append (this Skin destination, Skin source) {
|
||||
source.CopyTo(destination, true, false);
|
||||
}
|
||||
|
||||
public static void CopyTo (this Skin source, Skin destination, bool overwrite, bool cloneAttachments, bool cloneMeshesAsLinked = true) {
|
||||
var sourceAttachments = source.Attachments;
|
||||
var destinationAttachments = destination.Attachments;
|
||||
|
||||
if (cloneAttachments) {
|
||||
if (overwrite) {
|
||||
foreach (DictionaryEntry e in sourceAttachments)
|
||||
destinationAttachments[e.Key] = ((Attachment)e.Value).GetCopy(cloneMeshesAsLinked);
|
||||
} else {
|
||||
foreach (DictionaryEntry e in sourceAttachments) {
|
||||
if (destinationAttachments.Contains(e.Key)) continue;
|
||||
destinationAttachments.Add(e.Key, ((Attachment)e.Value).GetCopy(cloneMeshesAsLinked));
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (overwrite) {
|
||||
foreach (DictionaryEntry e in sourceAttachments)
|
||||
destinationAttachments[e.Key] = e.Value;
|
||||
} else {
|
||||
foreach (DictionaryEntry e in sourceAttachments) {
|
||||
if (destinationAttachments.Contains(e.Key)) continue;
|
||||
destinationAttachments.Add(e.Key, e.Value);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: f4692b9527684d048862210ba3f9834e
|
||||
timeCreated: 1563321428
|
||||
licenseType: Free
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
Loading…
x
Reference in New Issue
Block a user