1
\$\begingroup\$

I am trying to make a game that has an object on screen, which moves from one Y coordinate to another. Right now, I do it through translations, but that does it instantly. I want to do this as a kind of animation, where it transitions smoothly from one Y coordinate to another. What should I do?

Here is an image of what I'm talking about:

I want smooth transition from one co-ordinate to another.

\$\endgroup\$

2 Answers 2

2
\$\begingroup\$

Vector3.Lerp

What you want to be using is the Vector3.Lerp method1. Let's take a look at the Unity API.

Vector3.Lerp
public static Vector3 Lerp(Vector3 a, Vector3 b, float t);

Description
Linearly interpolates between two vectors.

Interpolates between the vectors a and b by the interpolant t. The parameter t is clamped to the range [0, 1]. This is most commonly used to find a point some fraction of the way along a line between two endpoints (e.g. to move an object gradually between those points).

When t = 0 returns a. When t = 1 returns b. When t = 0.5 returns the point midway between a and b.


Using Vector3.Lerp for a transition

You will want to play around with the method, to reach the transition effect you desire. An example of its use, as you describe, is as follows:

// We need to know where we are going. 
// Since you work that out, elsewhere, we do not need to go into how.
public Vector3 targetPostion;

public void Update()
{
    Vector3 currentPosition = gameObject.Transform.position;
    Vector3 newPosition = Vector3.Lerp(currentPosition, targetPosition, 0.2);

    gameObject.Transform.position = newPosition;
}

Using Vector3.Lerp for a smooth transition

In the above example, we are transitioning towards the new position by 20%, per update. This is a good start, and useful to understand how the method works. Keep in mind that for smooth transition, you will want to account for the delta time; a smoother transition would look something like this:

public void SmootherTransition()
{
    Vector3 currentPosition = gameObject.Transform.position;
    Vector3 transition = 0.2 * Time.deltaTime;
    Vector3 newPosition = Vector3.Lerp(currentPosition, targetPosition, transition);

    gameObject.Transform.position = newPosition;
}

Further Consideration

As stated, you will want to play around with the method, in order to reach the desired functionality.

As an example, you will initially find that the translation distance gets smaller, with each iteration. This is because each iteration sets a new currentPosition, which is naturally closer to the targetPosition than during the previous iteration. As a result, your working out the same fraction from a smaller distance, which in turn is itself a smaller distance. This becomes especially noticeable towards the end, where the object will appear to vibrate, as its movement distance becomes exponentially smaller and smaller. Simply checking for a minimum distance, and translating the object directly to the targetPosition if it is not outside of the minimum distance, should fix this problem.


1 You describe a 2D game, but since your game objects will still be using Vector3 positions by default, using Vector3.Lerp is more efficient. If you are in fact using Vector2 positions, you should be able to apply the exact same logic to Vector2.Lerp.

\$\endgroup\$
2
  • \$\begingroup\$ This is one of those rare situations where I can not actually test my answer, due to circumstance. I feel it unnecessary, due to the basic nature of that which I explain. That said, I am confident the changes to gameObject.transform will work, but you may need to retrieve and localise the data structure for local manipulation. I remember this being only restricted to the actual position, where you cant directly change the x, y and z values, but you can retrieve position into a local Vector3, change x, y, and z in the local Vector3, and resubmit it as the new position. \$\endgroup\$
    – Gnemlock
    Oct 2, 2016 at 6:45
  • \$\begingroup\$ Please leave a comment if I have made a mistake, so I can update my answer, accordingly. \$\endgroup\$
    – Gnemlock
    Oct 2, 2016 at 6:45
1
\$\begingroup\$

You have to move the object in every frame a bit until it is at its destination.

void Update()
{
    if (hasToMove)
    {
        if (transform.position.y - targetY > 0.1f)
            transform.position.y += 10.0f * Time.deltaTime;
        else
        {
            transform.position.y = targetY;
            hasToMove = false;
        }
}

You set hasToMove to true when you want the move to appear and targetY to your target. The script also assumes the script is attached to the moving object itself.

You can play a bit with the threshold0.1f and the speed 10.0f until it fits your needs.

\$\endgroup\$

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .