How to move 2D character from one place to another by "movement" and not "teleporting"?

Hi everyone

Introduction

I am making some controls for my character who moves only left and right on the x-axis. I posted the code for his movement to left and right. The idea is to have him only move those widths in the game so there’s like 5 places he can be on the screen.

public float fieldWidth = 3;

void FixedUpdate(){
	if (Input.GetKeyDown(KeyCode.LeftArrow)){
		transform.Translate(-fieldWidth, 0,0f, 0,0f);
	}

	if (Input.GetKeyDown(KeyCode.RightArrow)){
		transform.Translate(fieldWidth, 0,0f, 0,0f);
	}
}

Problem:

The main problem is that when I used translate in the code then the character “teleports” to those places. It’s cool that he can only move 5 places in total with 3.0f each step BUT I wanted to have him “move” those places instead of “teleporting”.

After all, I want to add an animation on the character when he moves from one place to another.

Alternative tries:

If I use deltaTime for his movement/velocity then he just moves at that speed and do not stop at one of the 5 places as he does now and is supposed to do.

Goal:

I want him to move 3.0f every time I press Right or Left arrowkey but he should show motion from one place to another instead of teleporting one place to another.

Question:

Could someone help me showing what I’m doing wrong, and what I should do to correct it?

You should determine your player’s target position when you press a key, then move him in the direction of your target position (3.0f in some direction from your current position) over time until he has arrived there. Easiest way is probably using Vector2.MoveTowards.

keep in mind that you should make sure that if a key is pressed while the player is moving it the target position is not changed (or changed to a position where you want your player to be able to go depending on what kind of behaviour you want)

There’s actually several ways to do this, on my opinion you should go with adding a rigidbody2D to you character and move it with velocity.

    private Vector3 _destinyPos;
    private float _distanceTolerance = 0.1f;
    public float fieldWidth = 3;
    public float speed = 3;

    private void Update(){
        if (Input.GetKeyDown(KeyCode.LeftArrow)){
            _destinyPos = transform.position - new Vector3(fieldWidth, 0, 0);
        }

        if (Input.GetKeyDown(KeyCode.RightArrow)){
            _destinyPos = transform.position + new Vector3(fieldWidth, 0, 0);
        }
    }

    private void FixedUpdate(){
        if (Mathf.Abs(_destinyPos.x - transform.position.x) > _distanceTolerance){
            if (_destinyPos.x < transform.position.x) rigidbody2D.velocity = -transform.right * speed;
            else rigidbody2D.velocity = transform.right * speed;
        }
        else rigidbody2D.velocity = Vector2.zero;
    }

Receiving Input should always be done on the Update() function. The FixedUpdate() should be used for physics calculations.

Another option is to move him with transform.Translate(). But after some experience recommend using rigidbody.