Hello Guest

Author Topic: Change sprite collection for an animation library?  (Read 12167 times)

ealtorfer

  • 2D Toolkit
  • Newbie
  • *
  • Posts: 6
    • View Profile
Change sprite collection for an animation library?
« on: June 10, 2013, 05:14:56 am »
I'm creating a 2D RPG and I have made sprite collections for each piece of armor in the game. Each armor has the same animations for walk, idle, etc. and each frame is named exactly the same way for every piece of armor.

Is there a way to change the sprite collection used by the animation at runtime? Or, if not, is there some way I can duplicate the animation library and just change the sprite collection it uses in the editor? I haven't found a method for either of these.

unikronsoftware

  • Administrator
  • Hero Member
  • *****
  • Posts: 9709
    • View Profile
Re: Change sprite collection for an animation library?
« Reply #1 on: June 10, 2013, 11:23:43 am »
The issue here is that the "animation library" can use more than one sprite collection. One unique sprite collection per frame of animation to be exact.

In your case, if you've constrained it such that there is only one sprite collection, you should make a proxy class to call Play on, which then feeds the tk2dSpriteAnimationClip to the animator (2.x) / animatedsprite (1.x).

SpriteCollectionSwitcherBehaviour
   make a copy of clips at start.
   Play( "walk" )
   SwitchCollection( newCollection ) - runs through all the clips, foreach frame, get sprite name from id, then find the id from the new collection. replace id & collection on the frame.

Basically, you call Play on this behaviour, and this in turn calls Play on the animator, using the modified tk2dSpriteAnimationClip instead of name.

Tina

  • Newbie
  • *
  • Posts: 4
    • View Profile
Re: Change sprite collection for an animation library?
« Reply #2 on: June 12, 2013, 09:33:19 pm »
Hi,
I'm currently working in a 2d game in the newest version of the 2d toolkit and I would like to know how I create a sprite animator at runtime.  I’m developing a game where depending on a random number a different animation has to be displayed.
Currently I’m using this code:
public tk2dSpriteAnimator anim;
GameObject two = new GameObject ();
anim = two.AddComponent<tk2dSpriteAnimator>();
The problem with this code is that Unity shows this error:
Sprite not found attached to tk2dSpriteAnimator.
I will appreciate your help!

Majicpanda

  • 2D Toolkit
  • Jr. Member
  • *
  • Posts: 62
    • View Profile
Re: Change sprite collection for an animation library?
« Reply #3 on: June 12, 2013, 10:09:13 pm »
Line 132 of tk2dSpriteAnimator ...
_sprite = GetComponent<tk2dBaseSprite>();

Line 134:
Debug.LogError("Sprite not found attached to tk2dSpriteAnimator.");

I believe all GO's with a sprite animator require a tk2d sprite to be on the object as well, so do this first:
sprite = two.AddComponent<tk2dSprite>();

tk2d 2.0 might now be tk2dBaseSprite so I'm not 100% sure which you're supposed to use.

unikronsoftware

  • Administrator
  • Hero Member
  • *****
  • Posts: 9709
    • View Profile
Re: Change sprite collection for an animation library?
« Reply #4 on: June 12, 2013, 10:29:19 pm »
@Tina - you just need to resolve the error message. The animator behaviour needs to be attached to a sprite to work.
Its works with tk2dSprite, tk2dClippedSprite, tk2dSlicedSprite or tk2dTiledSprite.
The tk2dSpriteAnimator can animate any of these :)

Code: [Select]
GameObject obj = new GameObject();
obj.AddComponent<tk2dSprite>();
tk2dSpriteAnimator animator = obj.AddComponent<tk2dSpriteAnimator>();
animator.Libary = library;
animator.Play( "clipname" );

ealtorfer

  • 2D Toolkit
  • Newbie
  • *
  • Posts: 6
    • View Profile
Re: Change sprite collection for an animation library?
« Reply #5 on: June 17, 2013, 06:13:52 am »
Thanks for the help...took me a while, but here's the code I came up with (using the 1.x library). I'd be curious to hear any feedback or optimizations.

Code: [Select]
    void SwitchSpriteCollection(tk2dAnimatedSprite animatedSprite, tk2dSpriteCollectionData spriteCollectionData)
    {
        // Set up the new sprite.
        tk2dAnimatedSprite newAnimatedSprite = animatedSprite.gameObject.AddComponent<tk2dAnimatedSprite>();
        newAnimatedSprite.anim = newAnimatedSprite.gameObject.AddComponent<tk2dSpriteAnimation>();
        newAnimatedSprite.anim.clips = new tk2dSpriteAnimationClip[animatedSprite.anim.clips.Length];
        newAnimatedSprite.Collection = spriteCollectionData;

        // Copy the clips from the original sprite animation.
        for (int i = 0; i < animatedSprite.anim.clips.Length; i++)
        {
            // Initialize the new clip.
            newAnimatedSprite.anim.clips[i] = new tk2dSpriteAnimationClip();

            // Store references to both clips.
            tk2dSpriteAnimationClip oldClip = animatedSprite.anim.clips[i];
            tk2dSpriteAnimationClip newClip = newAnimatedSprite.anim.clips[i];

            // Copy the old clip.
            newAnimatedSprite.anim.clips[i].CopyFrom(oldClip);

            for (int j = 0; j < oldClip.frames.Length; j++)
            {
                tk2dSpriteAnimationFrame oldFrame = oldClip.frames[j];
                tk2dSpriteAnimationFrame newFrame = newClip.frames[j];

                // Get the ID of the equivalent sprite in the new collection.
                string spriteFrameName = oldFrame.spriteCollection.spriteDefinitions[oldFrame.spriteId].name;
                int spriteFrameId = spriteCollectionData.GetSpriteIdByName(spriteFrameName);

                // Set up the information for the new (copied) frame.
                newFrame.spriteCollection = spriteCollectionData;
                newFrame.spriteId = spriteFrameId;
            }
        }

        // Destroy the animation we just replaced
        Destroy(animatedSprite);
    }

unikronsoftware

  • Administrator
  • Hero Member
  • *****
  • Posts: 9709
    • View Profile
Re: Change sprite collection for an animation library?
« Reply #6 on: June 17, 2013, 09:39:48 am »
That is pretty much perfect. Obviously won't work if you used more than one collection, but in your case you don't need to :)