简体   繁体   中英

What is the best way to move game objects, smoothly rather than teleporting it?

I'm trying to move a game object, pokemon, from the centre of the screen to the left of the screen (only along the horizontal axis), smoothly. However, it keeps teleporting instantly.

WHAT THE CODE DOES = Changes from one sprite to another sprite in an endless loop. When it changes to another sprite, it also changes its scale.

WHAT I WANT THE CODE TO DO = Before changing to a different sprite, move left on the horizontal axes.

I have tried linear interpolation (lerp) and transform.translate.

public class Transitions : MonoBehaviour
{

    public Sprite Pokemon_0; // VARIABLES FOR SPRITES (Pokemons/ game objects) 
    public Sprite Pokemon_1;

    float timer = 1f; // CHANGING SPRITES VALUES (delays)
    float delay = 5f;

    Vector2 temp;     //CHANGING POSITION VARIABLES
    Vector2 tempPos;
    Vector2 finalPosition;


    void Start()
    {
        this.gameObject.GetComponent<SpriteRenderer>().sprite = Pokemon_0;
    }

    void Update()
    {
        timer -= Time.deltaTime;
    if (timer <= 0)
    {
        if (this.gameObject.GetComponent<SpriteRenderer>().sprite == Pokemon_0) // TO CHANGE FROM POKEMON 1 TO POKEMON 2 
        {
            this.gameObject.GetComponent<SpriteRenderer>().sprite = Pokemon_1;

            temp = transform.localScale;  // TO SET THE SCALE WHEN EACH POKEMON CHANGES (works)
            temp.x = -380;
            temp.y = 350;
            transform.localScale = temp;
            timer = delay;

            finalPosition = new Vector2(167, -107);
            transform.position = Vector3.Lerp(transform.position, finalPosition, 1f * Time.deltaTime);

            //tempPos = transform.position; // Tried and tested method. Doesn't work. 
            //tempPos.x = 1f;
            //transform.position = tempPos;



            return;

        }
        if (this.gameObject.GetComponent<SpriteRenderer>().sprite == Pokemon_1) // TO CHANGE BACK FROM POKEMON 2 TO POKEMON 1
        {
            this.gameObject.GetComponent<SpriteRenderer>().sprite = Pokemon_0;
            timer = delay;
            return;

        }

    }

On execution, this code does change pokemon and changing the scale. However, the position remains the same.

I am open fairly new so I'm constantly trying our different suggestions, thanks.

In your code example, it appears you are using the position's x value differently. The xy and z values are used together to form a point, which is represented in the 3D environment. Settings the object's position to the previous position it had while changing the x value to 1 each time will lock it on the horizontal axis.

You can use either interpolation to smooth out the transition between two position states or use Unity's built-in Vector3.MoveTowards (or Vector2 if in a 2D landscape).

Interpolation

Your desired position is the exact position you want to change to. Your current position will be transform.position .

float step; // Set this to how fast you want to increment movement (1f, 5f, 10f)
Vector3 start; // Set this to the transform.position when you want to start interpolating
Vector3 desired; // Set this to a new Vector3(x, y) with the place you want to move to

void Update(){
    // Here, we set the object's position to it's current position, but interpolated to it's desired position
    transform.position = Vector3.Lerp(start, desired, step * Time.deltaTime);
}

MoveTowards

float step; // Set this to how fast you want to increment movement (1f, 5f, 10f)
Vector3 desired; // Set this to a new Vector3(x, y) with the place you want to move to

void Update(){
    transform.position = Vector3.MoveTowards(transform.position, desired, step * Time.deltaTime);
}

Its better to use a tween engine , like http://dotween.demigiant.com/ .

If you install Dotween then you can simply use

transform.DOMove(new vector3(1 ,0 , 1) , duration);

You can also set Ease for tweens. or use Oncomplete fucntions;

transform.DOMove(new vector3(1 ,0 , 1) , duration)
    .SetEase(Ease.OutCubic)
    .OnCompelete(() => { shouldClose = true; }); 

You can also set loop for your tween .SetLoops(-1) .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM