How to create UI transitional animations with Unity3D

Verónica Valls
Game & Frontend Development Stuff
5 min readApr 26, 2016
The blue sphere is animated in its x axis to go from the last button clicked to the current button clicked.

On this post I’ll explain the two ways I used to implement simple transitional animations for Image components of the Unity UI avoiding Unity’s last animation system Mecanim, just because I thought Mecanim had a bit complicated build up in comparison to the simple animation from point A to point B that I needed to make, so I tried to look for a simpler settling.

In this case I tried two different solutions, the first I tried was using Animation Legacy and the second was saving the positions in which the blue sphere had to move from and to and preparing the suitable code.

I’ll begin explaining both solutions taking into account the buttons and sphere position from the upper image’s design. The animation works as follows: when a button is clicked the blue sphere will move along x axis from the last clicked button to the current button clicked as a mark to know which is the last selected button or which section the user is currently visiting.

Solution 1: Animation Legacy

As we’re going to use the Animation Legacy, the first step is to add an Animation component to the Blue Sphere GameObject, if we don’t, when we open the Animation panel and create a new Animation, an Animator will be attached to our GameObject and the Animation won’t be Legacy.

Another way to change from Animation component to Animation Legacy component on a created Animation is, activate Debug by clicking on the 3 horizontal bar icon on the Inspector’s right part and check Legacy on the Animation.

Next step is to create the animation we need for the sphere to move, on this example, each 15 seconds, we set an animation point along x axis, each position is related with each button position:

For each animation position we’ll define an Animation Event (which is created clicking on the last icon of the bar below Animation tag) which will call StopAnimationSphere(int unit) this way when the animation goes through these events, we’ll compare its parameter unit with the selected unit button the user clicked to stop the sphere’s animation if both of them coincide.

We continue with the initiate sphere animation’s code:

public Animation sphereTweenMenu;
int previousUnit;
float previousPosition;
void AnimateSphereFromUnitMenu(int unit)
{
//We need to save the previous unit to know in which direction
//and from which point the sphere needs to be animated to
if(previousUnit<=unit)
{
sphereTweenMenu[“SphereAnimationMenuTween”].speed=1;
}
else if(previousUnit>unit)
{
sphereTweenMenu[“SphereAnimationMenuTween”].speed=-1;
}

sphereTweenMenu[“SphereAnimationMenuTween”].time=previousPosition;
sphereTweenMenu.Play(“SphereAnimationMenuTween”);

//Animation time parameter goes from 0 to 1, so we need to convert the time seconds positions from the Animation window to its equivalent. It would be interesting to store all these values in an array related with the enum Units to keep the code clean and better readable, this is taken into account in the second solution :)
if(MapManager.unitSelected==(int)Units.One)
{
previousPosition=0f;
}
else if(MapManager.unitSelected==(int)Units.Two)
{
previousPosition=0.25f;
}
else if(MapManager.unitSelected==(int)Units.Three)
{
previousPosition=0.50f;
}
else if(MapManager.unitSelected==(int)Units.Four)
{
previousPosition=0.75f;
}
else if(MapManager.unitSelected==(int)Units.All)
{
previousPosition=1f;
}
else if(MapManager.unitSelected==(int)Units.None)
{
previousPosition=1.25f;
}
previousUnit=unit;
}

The next function is the one called from the Animation Event, when the parameter from the Animation Event is the same as the last button clicked, the animation stops:

public void StopAnimationSphere(int unit)
{
if(unit==MapManager.unitSelected)
{
sphereTweenMenu.Stop();
}
}

Conclusion of this method: The advantage of this solution is that is clean and simple to mantain (imagine you have to add more buttons), the downsides are, in my case, sometimes the sphere didn’t stop at the exact animation position which was defined in the Animation window and that could be a problem in some UI’s designs (imagine the sphere goes inside a tight shape and is not perfectly centered or not completely inside), the second downside is that it’s legacy and some day Unity will stop supporting it.

Solution 2: Old school (saving positions and animating through Update)

First, we set the different animation positions along x axis according to the buttons positions, because of cleanliness we’ll store them in an array:

These positions are related with an enum structure of the Units buttons, this way when the button is selected its id coincides with the unit positions array:

enum Units
{
One, Two, Three, Four, All, None
}
void AnimateSphereFromUnitMenu(int unit)
{
selectedPosition=unitsPositions[MapManager.unitSelected];
isSphereTweenMenuMoving=true;
}

When the bool isSphereTweenMenuMoving changes value to true, on the Update function AnimateSphereFromUnitMenuBody code gets called:

float vel=4f;void Update()
{
AnimateSphereFromUnitMenuBody
();
}
void AnimateSphereFromUnitMenuBody()
{
if(isSphereTweenMenuMoving)
{
sphereTweenMenu.localPosition=
Vector3.Lerp(sphereTweenMenu.localPosition,
new Vector3(selectedPosition,
sphereTweenMenu.localPosition.y,
sphereTweenMenu.localPosition.z),
Time.deltaTime*vel);

float num=(float)Math.Round(sphereTweenMenu.localPosition.x, 2);


if(num==unitsPositions[MapManager.unitSelected])
{
isSphereTweenMenuMoving=false;
}
}
}

We check if the sphere current position is the same as the final animation position, when it’s the same value, isSphereTweenMenuMoving changes to false and exits from the function.

Conclusion of this method: I consider this method is dirtier than the first solution because of the need of using bool variables on the Update function, in addition, when it’s close to the final position, the animation slows down a bit, on the other hand, there’s no problem related with not reaching the exact final animation position neither related with legacies, it’s a safe method. In my case I stay with this one due to the animation positions mismatch of the first one.

As you can see there are pros and cons in both methods and on Mecanim too, it depends on your needs and also which method makes you feel more comfortable the way you think and code.

--

--

Verónica Valls
Game & Frontend Development Stuff

Mobile & frontend developer for real world projects. Game designer/developer for my mind’s delirium ideas. Cats & dogs dietetical and nutritional advisor.