Skip to content

Using Unity Toolkit 2D and LeanTween

December 25, 2013

Even with Unity 4.3 and its latest 2D features, I am sure a lot of you still use the great 2D Toolkit on top of it. It has so much more great features that Unity does not offer (or only for Pro). For tweening, I use LeanTween, because it has great support and ― nomen est omen ― really operates very slick and lean. The one thing that I found a bit tedious is applying two of my most used tweens: alpha and scaling. Both can’t be applied in the regular fashion on the game object, but should rather be applied directly to the sprite component. So you need to fiddle around with LeanTween.value and write all the same code over and over to accomplish what it takes to do that properly. This also really messes up the code, so I created a nice helper that makes it really easy to do alpha and scale tweening directly on a sprite. All you need is the latest LeanTween (>= V2.031), since it offers some great new features that you’ll need to do that. If it’s not yet available on the Asset Store, you can always grab the latest version directly from Github.

Just create a new script named LeanTweenExtension.cs with the code below or download it ready-made. Then you can simply append setSprite() to your LeanTween alpha or scale statement, and the operation will be applied to the sprite component rather than to the gameobject. Everything else (looping, easing, …) works exactly the same as before. There are just two catches:

  • You can’t use your own onUpdate function on that tween, since it is already needed internally to do the magic
  • You can’t scale separate x/y/z values at the same time using LeanTween.scale. While you can (and need to) provide the scale as a Vector3 parameter, only the x component is used and applied to x and y at the same time. This is probably the 90% use case anyway, but if you need to do it separately, you can just use separate and consecutive LeanTween.scaleX/Y/Z  calls to achieve the same (The reason is that the LeanTween generic callback function that is used internally here just tweens on a single float, not a vector)

There are two signatures to call: setSprite() and setSprite(tk2dSprite sprite). The first will lookup the tk2dSprite component on the tweened gameobject, with the second you can provide it explicitly if you either tween on  a different gameobject that does not own the sprite, or if you simply have it at hand and want to save the additional lookup time. Call it like this:

  // shrink sprite to half size in one second
  LeanTween.scale(gameobject, new Vector2(0.5f, 0), 1f).setSprite();

  // pulse another sprite (fade in and out repeatedly) with a second frequency, but tied to the same tween gameobject  
  LeanTween.alpha(gameobject, 0, 1f).setSprite(anotherSprite).setLoopPingPong().setEase(LeanTweenType.easeInOutSine);

  // etc. ;-)

So as you can see, you can write very clean code even for complex tweens on your sprites. You can of course extend this helper extensions for other operations, but as far as I needed them up to now, these are the two that need special attention when used for sprite gameobjects.

And here is the beef:

using UnityEngine;
using System.Collections;

public static class LeanTweenExtension {

  // Extend LeanTween to operate on a tk2dsprite rather than the gameobject
  public static LTDescr setSprite(this LTDescr ltdescr, tk2dSprite sprite) {

    if (sprite == null) throw new UnityException("LeanTween.setSprite(): no sprite provided");

    switch (ltdescr.type) {

    case TweenAction.ALPHA:
      // set alpha directly on sprite color
      ltdescr.setFrom(new Vector3(sprite.color.a,0,0));
      ltdescr.setOnUpdate(delegate(float alpha, object tk2dspr) {
        Color col = ((tk2dSprite)tk2dspr).color;
        col.a = alpha;
        ((tk2dSprite)tk2dspr).color = col;
      }, sprite);
      break;

    case TweenAction.SCALE:
      // scale sprite only, not the game object!
      ltdescr.setFrom(sprite.scale);
      ltdescr.setOnUpdate(delegate(float scale, object tk2dspr) {
        ((tk2dSprite)tk2dspr).scale = new Vector3(scale, scale, sprite.scale.z);
      }, sprite);
      break;

    case TweenAction.SCALE_X:
      // scale sprite only, not the game object!
      ltdescr.setFrom(sprite.scale);
      ltdescr.setOnUpdate(delegate(float scale, object tk2dspr) {
        ((tk2dSprite)tk2dspr).scale = new Vector3(scale, sprite.scale.y, sprite.scale.z);
      }, sprite);
      break;

    case TweenAction.SCALE_Y:
      // scale sprite only, not the game object!
      ltdescr.setFrom(sprite.scale);
      ltdescr.setOnUpdate(delegate(float scale, object tk2dspr) {
        ((tk2dSprite)tk2dspr).scale = new Vector3(sprite.scale.x, scale, sprite.scale.z);
      }, sprite);
      break;

    case TweenAction.SCALE_Z:
      // scale sprite only, not the game object!
      ltdescr.setFrom(sprite.scale);
      ltdescr.setOnUpdate(delegate(float scale, object tk2dspr) {
        ((tk2dSprite)tk2dspr).scale = new Vector3(sprite.scale.x, sprite.scale.y, scale);
      }, sprite);
      break;

    default: throw new UnityException("LeanTween.setSprite(): action not yet supported " + ltdescr.type);
    }

    // make sure onUpdate is not set, otherwise object callback will not be called
    ltdescr.onUpdateFloat = null; 
    // change tween type to generic "value" callback
    ltdescr.type = TweenAction.CALLBACK;

    return ltdescr;
  }

  public static LTDescr setSprite(this LTDescr ltdescr) {
    if (ltdescr.trans == null) throw new UnityException("LeanTween.setSprite(): no gameobject set");
    tk2dSprite sprite = ltdescr.trans.GetComponent<tk2dSprite>();
    if (sprite == null) throw new UnityException("LeanTween.setSprite(): no sprite component found");
    return ltdescr.setSprite(sprite);
  }
}
Advertisements

From → Development

7 Comments
  1. Hey – thanks for sharing this. Very handy little extension.

    Just a note for anyone using it – it LeanTween changed the name of the LeanTweenDescr to LTDescr in recent versions, so you may need to replace that type name in a few places.

    • Hi,

      yes, that’s true. I updated the post and also refer explicitly now to the latest LeanTween version V2.031 to avoid inconsistencies.

      Thanks for the heads up,
      habitoti

  2. HomerJ permalink

    This is awesome.. thanks

  3. andi permalink

    Hi Rombos,

    first thanks for sharing this! I can’t get you code to work. When unity tries to compile it I get an error:

    Assets/LeanTween/LeanTweenExtension.cs(20,33): error CS1501: No overload for method `setOnUpdateObject’ takes `2′ arguments

    I had a look into the LeanTween code and there is no setOnUpdate method which takes two parameters (the sprite parameter in your code). How can I fix this?

    Thanks!

    • What version of LeanTween are you using? The latest version (2.1 by now) defintely contains the required signature
      public LTDescr setOnUpdate( Action onUpdate, object onUpdateParam = null )

      Not sure what you mean with setOnUpdateObject. My code is not using that.

      • andi permalink

        My fault that I didn’t checked if there is a new Lean Tween version. I used LeanTween 2.02. After updating to 2.1 your Extension is working. In 2.02 setOnUpdate only accepted one parameter. Thanks for the hint!

  4. Great work! May I suggest to add support for other sprite types, like tk2dTiledSprite, sliced and clipped?

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: