15
\$\begingroup\$

I want to create a trailing, ghosting like effect of a sprite that's moving fast. Something very similar to this image of Sonic (apologies of bad quality, it's the only example I could find of the effect I'm looking to achieve)

Ghost trail

However, I don't want to do this at the sprite sheet level, to avoid having to essentially double (or possibly quadruple) the amount of sprites in my atlas. It's also very labor intensive.

So is there any other way to achieve this effect? Possibly by some shader voodoo magic? I am using Unity and 2D Toolkit, if that helps.

\$\endgroup\$
21
\$\begingroup\$

You could easily do this with a particle system and a shader. Set up the particle system to release 1 particle every X milliseconds with a max of 3 particles. (Choose an X based on how far apart you want the trailing sprites to be.) For the particle, use the same image as the character's current sprite, but with a different material. Try some of the alpha blended shaders on the material to get the effect that you want on the trailing particles.

If you want to get fancier, you could adjust the max # of particles and other settings based on the character's current speed.

Here is an example that I was able to do with just 1 Quad, 1 sprite, 2 materials, and a particle system.

I attached the particle system to the Quad and set the quad to use the Sonic sprite. I'm using only the Emission, Color over Life time, and Renderer settings of the Particle System.

Max particles: 5

Simulation Space: World

Start Lifetime: 1

Start Speed: 0

Color over lifetime: Fade from White (Alpha 255) to Black (Alpha 0)

Renderer Material: Using same image as the original, but with "Particles/Alpha Blended" shader.

Sonic with Trailing Particle Effect

| improve this answer | |
\$\endgroup\$
  • 1
    \$\begingroup\$ This works perfectly. The only thing I need to work out is how to programmatically set the material on the particle system renderer to match the current sprite image (again, I'm using 2D Toolkit so it's different from Unity's sprite system). \$\endgroup\$ – Cooper May 23 '14 at 22:01
4
\$\begingroup\$

Just like the particle system solution, you can use 2dtoolkit to create the same effect. Add 3 children game object to the character with only a sprite attached to them. Change the alpha and coloring as needed. Then you can vary the sprite's local positions depending on the speed of the character:

myTransform.localPosition = characterSpeed * distanceFactor;

It saves a draw call (compared to particles) and gives you total control on the spread of the effect, if you want to do it smooth or staggered.

| improve this answer | |
\$\endgroup\$
  • \$\begingroup\$ This actually lead me to a better solution that's much more suited when using 2D Toolkit, but I'm reluctant to mark as the accepted answer. The particle system method is a much more "Unity generic" way that's probably best fitted for most Unity developers. I'll post the solution I ended up using. \$\endgroup\$ – Cooper May 27 '14 at 21:51
3
\$\begingroup\$

While the particle system solution provided by LVBen does work, it's not the best suited solution when using 2D Toolkit for your sprites. The primary reason being is that it's impossible to sync up the ghost trail material in the particle system to the current sprite animation of the main prefab.

Here's the 2D Toolkit friendly solution I ended up using.

For the prefab in which you want the ghost trail to come from, attach an empty game object to it to act as the root. Under this root, attach any number of tk2dSprite or tk2dSpriteAnimator (depending if you want animated sprites or not) game objects (I added 4) and adjust their color alpha values as appropriate to achieve the ghosting/fading away effect.

In the top parent Update

// AmountToMove is a Vector3 of the amount we will translate this gameobject.
float y = (int)AmountToMove.y == 0 ? 0 : -AmountToMove.y;
float distanceFactor = 0.05f;
for (int i = 0; i < GhostingRoot.childCount; ++i) {
    // Based on the player's current speed and movement along the x and y axes,
    // position the ghost sprites to trail behind.
    Vector3 ghostSpriteLocalPos = Vector3.Lerp(
                                      GhostingRoot.GetChild(i).localPosition,
                                      new Vector3((-CurrentSpeed * distanceFactor * i),
                                                  (y * distanceFactor * i), 0),
                                      10f * Time.deltaTime);
    // GhostingRoot is the root gameobject that's parent to the ghost sprites.
    GhostingRoot.GetChild(i).localPosition = ghostSpriteLocalPos;
    // Sync the animations.
    // _ghostSprites is a List of the tk2dSpriteAnimator ghost sprites.
    _ghostSprites[i].Play(SpriteAnimator.CurrentClip.name);
    _ghostSprites[i].Sprite.FlipX = Sprite.FlipX;
}

This solution will create the trailing ghosting effect while syncing the animations of the ghost sprites with the main sprite.

| improve this answer | |
\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.