public static void addAllAttahcmentsSlots(SpineData spineData, SpritesByName spriteByName, Dictionary<string, Slot> slotByName, int pixelsPerUnit, out List<Skin> skins, out AttachmentGOByNameBySlot attachmentGOByNameBySlot) { float ratio = 1.0f / (float) pixelsPerUnit; skins = new List<Skin>(); attachmentGOByNameBySlot= new AttachmentGOByNameBySlot(); foreach(KeyValuePair<string, SpineSkinSlots>kvp in spineData.skins){ string skinName = kvp.Key; Skin skin = new Skin(); skin.name = skinName; List<SkinSlot> slotList = new List<SkinSlot>(); bool isDefault = skinName.Equals("default"); foreach(KeyValuePair<string, SpineSkinSlotAttachments>kvp2 in spineData.skins[skinName]){ string slotName = kvp2.Key; GameObject slotGO = slotByName[slotName].gameObject; Slot slot = slotByName[slotName]; string spritePath = spineData.slotPathByName[ slotName ] + "/"; SkinSlot skinSlot = new SkinSlot(); skinSlot.name = slotName; skinSlot.gameObject = slotGO; List<SkinSlotAttachment> attachmentList = new List<SkinSlotAttachment>(); foreach(KeyValuePair<string, SpineSkinAttachment> kvp3 in spineData.skins[skinName][slotName]){ string attachmenName = kvp3.Key; SkinSlotAttachment attachment = new SkinSlotAttachment(); attachment.name = attachmenName; SpineSkinAttachment spineAttachment = kvp3.Value; // - create skined object or direct GO for default skin Sprite sprite; spriteByName.TryGetValue(spineAttachment.name, out sprite); GameObject parentGO; GameObject spriteGO; string fixedName = attachmenName.Replace("/",SLASH_REPLACEMENT); if (isDefault){ parentGO = slotGO; spriteGO = new GameObject(fixedName); spritePath += fixedName; Attachment a = new Attachment(attachmenName, AttachmentType.SINGLE_SPRITE, spriteGO); slot.addAttachment(a); } else { spriteGO = new GameObject(skinName); Attachment a; slot.attachmentByName.TryGetValue(attachmenName, out a); if (a == null){ GameObject attachmentGO = new GameObject(fixedName); attachmentGO.transform.parent = slotGO.transform; resetLocalTRS(attachmentGO); a = new Attachment(attachmenName, AttachmentType.SKINED_SPRITE, attachmentGO); slot.addAttachment(a); } spritePath += fixedName + "/" + skinName; parentGO = a.gameObject; } attachment.gameObject = spriteGO; attachment.ObPath = spritePath; spriteGO.transform.parent = parentGO.gameObject.transform; // - if (spineAttachment.type.Equals("region")){ SpriteRenderer sr = spriteGO.AddComponent<SpriteRenderer>(); sr.sprite = sprite; spriteGO.transform.localPosition = getAttachmentPosition(spineAttachment, ratio, 0); spriteGO.transform.localRotation = getAttachmentRotation(spineAttachment, spriteByName.rotatedSprites.Contains(sprite)); spriteGO.transform.localScale = getAttachmentScale(spineAttachment); attachment.sprite = sr; } else if (spineAttachment.type.Equals("boundingbox")) { PolygonCollider2D collider = spriteGO.AddComponent<PolygonCollider2D>(); resetLocalTRS(spriteGO); Vector2[] vertices = new Vector2[spineAttachment.vertices.Length/2]; for (int i = 0; i < spineAttachment.vertices.Length; i+=2) { float x = (float) spineAttachment.vertices[i ] * ratio; float y = (float) spineAttachment.vertices[i+1] * ratio; vertices[i/2] = new Vector2(x,y); } collider.points = vertices; collider.SetPath(0,vertices); }else { Debug.LogWarning("Attachment type " + spineAttachment.type + " is not supported yiet FIX MEEE"); } attachmentList.Add(attachment); } skinSlot.attachments = attachmentList.ToArray(); slotList.Add(skinSlot); } skin.slots = slotList.ToArray(); skins.Add(skin); } }
public static void addSlotAnimationToClip(AnimationClip clip, Dictionary<string, SpineSlotAnimation> slotsAnimation, SpineData spineData, List<Skin> skinList, AttachmentGOByNameBySlot attachmentGOByNameBySlot) { foreach(KeyValuePair<string, SpineSlotAnimation> kvp in slotsAnimation){ string slotName = kvp.Key; string defaultAttachment = spineData.slotDefaultAttachments[slotName]; if (string.IsNullOrEmpty(defaultAttachment)) continue; SpineSlotAnimation slotAnimation = kvp.Value; if (slotAnimation.attachment != null && slotAnimation.attachment.Count > 0){ Dictionary<string, AnimationCurve> curveByName = new Dictionary<string, AnimationCurve>(); for (int i = 0; i < slotAnimation.attachment.Count; i++) { bool nullAttachment = false; SpineSlotAttachmentAnimation anim = slotAnimation.attachment[i]; if (string.IsNullOrEmpty( anim.name)){ anim.name=getFirstAttachmentName(slotAnimation); nullAttachment = true; } if (anim.name.Equals("")) continue; AnimationCurve enableCurve; if (curveByName.ContainsKey(anim.name)){ enableCurve = curveByName[anim.name]; } else { enableCurve = new AnimationCurve(); if (anim.time > 0.0f) enableCurve.AddKey(KeyframeUtil.GetNew(0, 0.0f, TangentMode.Stepped)); curveByName.Add(anim.name, enableCurve); if (i==0 && !anim.name.Equals(defaultAttachment)){ AnimationCurve defSlotCurve = new AnimationCurve(); curveByName.Add(defaultAttachment, defSlotCurve); if (anim.time !=0.0f){ defSlotCurve.AddKey(KeyframeUtil.GetNew(0, nullAttachment ? 0 : 1, TangentMode.Stepped)); defSlotCurve.AddKey(KeyframeUtil.GetNew((float)anim.time, 0, TangentMode.Stepped)); } else { defSlotCurve.AddKey(KeyframeUtil.GetNew(0, 0, TangentMode.Stepped)); } } } enableCurve.AddKey(KeyframeUtil.GetNew((float)anim.time, nullAttachment ? 0 : 1, TangentMode.Stepped)); if (i< (slotAnimation.attachment.Count - 1)){ SpineSlotAttachmentAnimation nextAnim = slotAnimation.attachment[i+1]; bool nullNextAttachment =false; if (string.IsNullOrEmpty( nextAnim.name)){ nextAnim.name=getFirstAttachmentName(slotAnimation); nullNextAttachment = true; } if (!nextAnim.name.Equals(anim.name) || nullNextAttachment) enableCurve.AddKey(KeyframeUtil.GetNew((float)nextAnim.time, 0, TangentMode.Stepped)); } } foreach(KeyValuePair<string, AnimationCurve> kvp2 in curveByName){ string attachmentName = kvp2.Key; AnimationCurve animationCurve = kvp2.Value; string attachmentPath = spineData.slotPathByName[slotName] + "/" + attachmentName.Replace("/",SLASH_REPLACEMENT); clip.SetCurve(attachmentPath, typeof(GameObject),"m_IsActive", animationCurve); } } if (slotAnimation.color != null && slotAnimation.color.Count >0){ AnimationCurve Curv_R = new AnimationCurve( ); AnimationCurve Curv_G = new AnimationCurve( ); AnimationCurve Curv_B = new AnimationCurve( ); AnimationCurve Curv_A = new AnimationCurve( ); Keyframe startKeyFrame = new Keyframe( 0.0f, 1.0f ); Curv_R.AddKey( startKeyFrame ); Curv_G.AddKey( startKeyFrame ); Curv_B.AddKey( startKeyFrame ); Curv_A.AddKey( startKeyFrame ); JsonData[] curveData = new JsonData[ slotAnimation.color.Count ]; for( int i = 0 ; i != slotAnimation.color.Count ;i++ ) { SpineSlotColorAnimation color = slotAnimation.color[ i ]; uint col = Convert.ToUInt32( color.color, 16 ); uint r = ( col ) >> 24; uint g = (col & 0xff0000) >> 16; uint b = (col & 0xff00) >> 8; uint a = (col & 0xff); float t = ( (float) (color.time) ); Keyframe keyFrame_R = new Keyframe( t, r / 255.0f ); Keyframe keyFrame_G = new Keyframe( t, g / 255.0f ); Keyframe keyFrame_B = new Keyframe( t, b / 255.0f ); Keyframe keyFrame_A = new Keyframe( t, a / 255.0f ); Curv_R.AddKey( keyFrame_R ); Curv_G.AddKey( keyFrame_G ); Curv_B.AddKey( keyFrame_B ); Curv_A.AddKey( keyFrame_A ); curveData[ i ] = color.curve; } setTangents( Curv_R, curveData ); setTangents( Curv_G, curveData ); setTangents( Curv_B, curveData ); setTangents( Curv_A, curveData ); for ( int i = 0; i != skinList.Count; i++ ) { if ( skinList[ i ].containsSlot( slotName ) ) { SkinSlot skinSlot = skinList[ i ][ slotName ]; for ( int j = 0; j != skinSlot.attachments.Length; j++ ) { SpriteRenderer sprite = skinSlot.attachments[ j ].sprite; if ( sprite != null ) { string spritePath = skinSlot.attachments[ j ].ObPath; AnimationUtility.SetEditorCurve( clip, EditorCurveBinding.FloatCurve( spritePath, typeof( SpriteRenderer ), "m_Color.r" ), Curv_R ); AnimationUtility.SetEditorCurve( clip, EditorCurveBinding.FloatCurve( spritePath, typeof( SpriteRenderer ), "m_Color.g" ), Curv_G ); AnimationUtility.SetEditorCurve( clip, EditorCurveBinding.FloatCurve( spritePath, typeof( SpriteRenderer ), "m_Color.b" ), Curv_B ); AnimationUtility.SetEditorCurve( clip, EditorCurveBinding.FloatCurve( spritePath, typeof( SpriteRenderer ), "m_Color.a" ), Curv_A ); } } } } Debug.LogWarning("slot color animation is not supported yet"); } } }
public static void addSlotAnimationToClip(AnimationClip clip, Dictionary<string, SpineSlotAnimation> slotsAnimation, SpineData spineData, AttachmentGOByNameBySlot attachmentGOByNameBySlot) { foreach(KeyValuePair<string, SpineSlotAnimation> kvp in slotsAnimation){ string slotName = kvp.Key; string defaultAttachment = spineData.slotDefaultAttachments[slotName]; if (string.IsNullOrEmpty(defaultAttachment)) continue; SpineSlotAnimation slotAnimation = kvp.Value; if (slotAnimation.attachment != null && slotAnimation.attachment.Count > 0){ Dictionary<string, AnimationCurve> curveByName = new Dictionary<string, AnimationCurve>(); for (int i = 0; i < slotAnimation.attachment.Count; i++) { SpineSlotAttachmentAnimation anim = slotAnimation.attachment[i]; if (string.IsNullOrEmpty( anim.name)) continue; AnimationCurve enableCurve; if (curveByName.ContainsKey(anim.name)){ enableCurve = curveByName[anim.name]; } else { enableCurve = new AnimationCurve(); if (anim.time > 0.0f) enableCurve.AddKey(KeyframeUtil.GetNew(0, 0.0f, TangentMode.Stepped)); curveByName.Add(anim.name, enableCurve); if (i==0 && !anim.name.Equals(defaultAttachment)){ AnimationCurve defSlotCurve = new AnimationCurve(); curveByName.Add(defaultAttachment, defSlotCurve); if (anim.time !=0.0f){ defSlotCurve.AddKey(KeyframeUtil.GetNew(0, 1, TangentMode.Stepped)); defSlotCurve.AddKey(KeyframeUtil.GetNew((float)anim.time, 0, TangentMode.Stepped)); } else { defSlotCurve.AddKey(KeyframeUtil.GetNew(0, 0, TangentMode.Stepped)); } } } enableCurve.AddKey(KeyframeUtil.GetNew((float)anim.time, 1, TangentMode.Stepped)); if (i< (slotAnimation.attachment.Count - 1)){ SpineSlotAttachmentAnimation nextAnim = slotAnimation.attachment[i+1]; if (!nextAnim.name.Equals(anim.name)) enableCurve.AddKey(KeyframeUtil.GetNew((float)nextAnim.time, 0, TangentMode.Stepped)); } } foreach(KeyValuePair<string, AnimationCurve> kvp2 in curveByName){ string attachmentName = kvp2.Key; AnimationCurve animationCurve = kvp2.Value; string attachmentPath = spineData.slotPathByName[slotName] + "/" + attachmentName.Replace("/",SLASH_REPLACEMENT); clip.SetCurve(attachmentPath, typeof(GameObject),"m_IsActive", animationCurve); } } if (slotAnimation.color != null && slotAnimation.color.Count >0){ Debug.LogWarning("slot color animation is not supported yet"); } } }
public static void addAnimation(GameObject rootGO, string rootDirectory, SpineData spineData, Dictionary<string, GameObject> boneGOByName, Dictionary<string, Slot> slotByName, AttachmentGOByNameBySlot attachmentGOByNameBySlot, List<Skin> skinList, int pixelsPerUnit, float zStep, bool useLegacyAnimation, bool updateResources) { float ratio = 1.0f / (float)pixelsPerUnit; foreach(KeyValuePair<string,SpineAnimation> kvp in spineData.animations){ string animationName = kvp.Key; string animationFolder = rootDirectory+"/"+ANIMATION_FOLDER; string assetPath = animationFolder + "/" + animationName+".anim"; SpineAnimation spineAnimation = kvp.Value; AnimationClip animationClip = new AnimationClip(); bool updateCurve = false; if (File.Exists(assetPath)){ AnimationClip oldClip = AssetDatabase.LoadAssetAtPath(assetPath, typeof(AnimationClip)) as AnimationClip; if (oldClip != null){ animationClip = oldClip; animationClip.ClearCurves(); updateCurve = true; } } animationClip.legacy = useLegacyAnimation; if (spineAnimation.bones!=null) addBoneAnimationToClip(animationClip,spineAnimation.bones, spineData, boneGOByName, ratio); if (spineAnimation.slots!=null) addSlotAnimationToClip(animationClip, spineAnimation.slots, spineData, skinList, attachmentGOByNameBySlot); if ( spineAnimation.events != null ) AddEvents( animationClip, spineAnimation.events, animationName ); if (spineAnimation.draworder!=null) addDrawOrderAnimation( animationClip, spineAnimation.draworder, spineData, zStep, animationName, slotByName ); if (updateCurve){ EditorUtility.SetDirty(animationClip); AssetDatabase.SaveAssets(); } else { animationClip.frameRate = 30; createFolderIfNoExists(rootDirectory, ANIMATION_FOLDER); AssetDatabase.CreateAsset(animationClip, assetPath); AssetDatabase.SaveAssets(); if (useLegacyAnimation){ AddClipToLegacyAnimationComponent(rootGO, animationClip); } else { AddClipToAnimatorComponent(rootGO,animationClip); } } } }
public static void addAnimation(GameObject rootGO, string rootDirectory, SpineData spineData, Dictionary<string, GameObject> boneGOByName, AttachmentGOByNameBySlot attachmentGOByNameBySlot, int pixelsPerUnit, ModelImporterAnimationType modelImporterAnimationType, bool updateResources) { float ratio = 1.0f / (float)pixelsPerUnit; foreach(KeyValuePair<string,SpineAnimation> kvp in spineData.animations){ string animationName = kvp.Key; string animationFolder = rootDirectory+"/"+ANIMATION_FOLDER; string assetPath = animationFolder + "/" + animationName+".anim"; SpineAnimation spineAnimation = kvp.Value; AnimationClip animationClip = new AnimationClip(); bool updateCurve = false; if (File.Exists(assetPath)){ AnimationClip oldClip = AssetDatabase.LoadAssetAtPath(assetPath, typeof(AnimationClip)) as AnimationClip; if (oldClip != null){ animationClip = oldClip; animationClip.ClearCurves(); updateCurve = true; } } AnimationUtility.SetAnimationType(animationClip, modelImporterAnimationType); if (spineAnimation.bones!=null) addBoneAnimationToClip(animationClip,spineAnimation.bones, spineData, boneGOByName, ratio); if (spineAnimation.slots!=null) addSlotAnimationToClip(animationClip, spineAnimation.slots, spineData, attachmentGOByNameBySlot); if (spineAnimation.draworder!=null) Debug.LogWarning("draworder animation implemented yet"); if (updateCurve){ EditorUtility.SetDirty(animationClip); AssetDatabase.SaveAssets(); } else { animationClip.frameRate = 30; createFolderIfNoExists(rootDirectory, ANIMATION_FOLDER); AssetDatabase.CreateAsset(animationClip, assetPath); AssetDatabase.SaveAssets(); if (modelImporterAnimationType == ModelImporterAnimationType.Generic) AddClipToAnimatorComponent(rootGO,animationClip); else AddClipToLegacyAnimationComponent(rootGO, animationClip); } } }