How to move model on x axis in increments of 1? Starting from zero at a range of -2 to 2.

Firstly Im a noob to coding, clearly :D.

Ive followed a decent runner tutorial and then tried to make some changes to the movement on the x axis. The character currently moves using a character controller but does so smoothly while left or right is held down. I tried to change the script so that the character moves once to the left or right depending on the button pressed. Ive tried to make it so that the character is always locked to one of 5 positions on the x axis (-2, -1, 0, 1 & 2).

Ive tried many different tweaks to the code I have, but in the end I just ended up crashing the game with a do while loop. It is one of those things that seemed like it would be an easy change to make, but I ended up spending half of my day on it and now Im just too burnt out and frustrated to think clearly about this issue. Therefore I would really appreciate some advice from the geniuses on this site.

This is the script; it used to move left and right smoothly but not in increments when the x movement section used moveVector.x = -xSpeed; for left and the opposite for right, but ive made functions and added an if statement that checks the character’s position - and I thought that would limit the game from crashing as that function would only be called once when the button is pressed (instead of on every update) but the game crashes so Im lost now (im not even sure if it is the function getting called every update or the do while loop never ending, but whether i move left or right the game crashes currently - probably the loop?).

using UnityEngine;
using System.Collections;

public class CharacterMotor : MonoBehaviour {

    CharacterController controller;
    Vector3 moveVector;
    float verticalVelocity = 0.0f;
    public float gravity = 12.0f;
    private float animationDuration = 2.0f;
    bool isDead = false;

    float speed = 5.0f;
    float xSpeed = 10.0f;
    float startTime;
    Vector3 position;
    
	// Use this for initialization
	void Start () {
        controller = GetComponent<CharacterController>();
        startTime = Time.time;
	}
	
	// Update is called once per frame
	void Update () {

        if (isDead)
            return;

        if (Time.time - startTime < animationDuration)
        {
            controller.Move(Vector3.forward * speed * Time.deltaTime);
            return;
        }

        moveVector = Vector3.zero;

        if (controller.isGrounded)
        {
            verticalVelocity = -1f;
        }
        else
        {
            verticalVelocity -= gravity * Time.deltaTime;
        }

        //X - Left & Right
                 // old bit, before mobile build was this: moveVector.x = Input.GetAxisRaw("Horizontal") * xSpeed;
        if(Input.GetMouseButton(0))
        {
            if (transform.position.x == 0.0f || transform.position.x == 1.0f || transform.position.x == 2.0f || transform.position.x == -1.0f || transform.position.x == -2.0f)
            {
                

                if (Input.mousePosition.x > (Screen.width / 2) && position.x < 2)
                {
                    MoveRight();
                }

                else if (Input.mousePosition.x < (Screen.width / 2) && position.x > -2)
                {
                    MoveLeft();
                }
            }
        }
        //Y - Up & Down
        moveVector.y = verticalVelocity;

        //Z - Forward & Back
        moveVector.z = speed;

        controller.Move(moveVector * Time.deltaTime);
	
	}

    

    public void SetSpeed (float modifier)
    {
        speed = 5.0f + modifier;
    }

    private void OnControllerColliderHit(ControllerColliderHit hit)
    {
        if (hit.gameObject.tag == "Enemy" && hit.point.z > transform.position.z + (controller.radius/2)) //&& hit.point.y > 0.1f)
            Death();
    }

    private void Death()
    {
        isDead = true;
        Debug.Log("Dead");
        GetComponent<Score>().OnDeath();
    }

    void MoveRight()
    {
        position = transform.position;
        do
        {
            moveVector.x = xSpeed;
        } while (transform.position.x < position.x + 1.0f);
    }

    void MoveLeft()
    {
        position = transform.position;
        do
        {
            moveVector.x = -xSpeed;
        } while (transform.position.x > position.x - 1.0f);
    }
}

Learning coding is fun, but somehow playmaker (state machine) logic seemed to make sense for my brain much quicker…

Thank you all for any help or advice you can offer.

Do While loops are rarely used. It is a loop that guarantee to run one time before checking its condition. In your case I think all you need is to use the Transform Translate() Method.
Vector3.right is a shorthand for (1,0,0)=(X,Y,Z), and Vector3.left is a shorthand for (-1,0,0)=(X,Y,Z). I use them here as the parameter for the Translate Method.

    void MoveRight()
    {
        transform.Translate(Vector3.right, Space.World);
    }

    void MoveLeft()
    {
        transform.Translate(Vector3.left, Space.World);
    }

In Update you may want to use Input.GetMouseButtonDown(0) instead of Input.GetMouseButton(0) since …down is only called once per click.
I out commented the part that I don’t know what you’re doing with.

        if (Input.GetMouseButtonDown(0))
        {
            if (transform.position.x > -2f &&  transform.position.x < 2f)
            {
                //if (Input.mousePosition.x > (Screen.width / 2) && position.x < 2)
                //{
                //    MoveRight();
                //}

                //else if (Input.mousePosition.x < (Screen.width / 2) && position.x > -2)
                //{
                //    MoveLeft();
                //}
            }
        }

So as I imagined when I began, it was a simple mistake.

I simply should have put the Vector3 MoveTowards outside of the controler and position checking if statement.

Instead I was checking if my character was in a position from which he can move, checking for input, setting the position to move to, as well as moving in the same if statement. Of course; upon update my script never executed what was in that if statement ever again as the conditions were no longer true - therefore the player only moved 0.00006 and not a full 1.0.

Now the actual movement is above the if statement that changes the target position.

Haha such a stupid mistake, but makes me love coding so much more now that I solved it myself. Also I probably understand ‘Update’ much better and I will hopefully have learned to be a huge load more careful about what I put where.

Here is the script that actually does exactly what I wanted, my character moves smoothly at fixed intervals at a range from -2 to 2 (this is my entire movement script, scroll down to “//X - Left & Right Movement CONTROLLED HERE” for the left and right movement):

using UnityEngine;
using System.Collections;

public class CharacterMotor : MonoBehaviour
{

    CharacterController controller;
    Vector3 moveVector;
    float verticalVelocity = 0.0f;
    public float gravity = 12.0f;
    private float animationDuration = 2.0f;
    bool isDead = false;

    float speed = 5.0f;
    public float xSpeed = 5.0f;
    float startTime;
    Vector3 position;
    Vector3 moveToPos;

    // Use this for initialization
    void Start()
    {
        controller = GetComponent<CharacterController>();
        startTime = Time.time;
    }

    // Update is called once per frame
    void Update()
    {

        if (isDead)
            return;

        if (Time.time - startTime < animationDuration)
        {
            controller.Move(Vector3.forward * speed * Time.deltaTime);
            return;
        }

        moveVector = Vector3.zero;

        if (controller.isGrounded)
        {
            verticalVelocity = -1f;
        }
        else
        {
            verticalVelocity -= gravity * Time.deltaTime;
        }

        //X - Left & Right Movement CONTROLLED HERE
        
        
        transform.position = Vector3.MoveTowards(transform.position, new Vector3(position.x, transform.position.y, transform.position.z), xSpeed * Time.deltaTime);

        if (Input.GetMouseButtonDown(0) && (transform.position.x == 0.0f || transform.position.x == 1.0f || transform.position.x == 2.0f || transform.position.x == -1.0f || transform.position.x == -2.0f))
        {
            


            if (Input.mousePosition.x > (Screen.width / 2)  && transform.position.x < 2.0f)
            {
                position.x = ( transform.position.x + 1.0f);
                //This used to be here, now it is above this 'if statement', THIS WAS MY MAIN MISTAKE: transform.position = Vector3.MoveTowards(transform.position, new Vector3(position.x, transform.position.y, transform.position.z),xSpeed * Time.deltaTime);

            }

            else if (Input.mousePosition.x < (Screen.width / 2) && transform.position.x > -2.0f)
            {
                position.x = ( transform.position.x - 1.0f);
                //This used to be here, now it is above this 'if statement', THIS WAS MY MAIN MISTAKE: transform.position = Vector3.MoveTowards(transform.position, new Vector3(position.x, transform.position.y, transform.position.z), xSpeed * Time.deltaTime);
            }
           

      
        }
       
       
        //Y - Up & Down
        moveVector.y = verticalVelocity;

        //Z - Forward & Back
        moveVector.z = speed;

        controller.Move(moveVector * Time.deltaTime);

    }



    public void SetSpeed(float modifier)
    {
        speed = 5.0f + modifier;
    }

    private void OnControllerColliderHit(ControllerColliderHit hit)
    {
        if (hit.gameObject.tag == "Enemy" && hit.point.z > transform.position.z + (controller.radius / 2)) //&& hit.point.y > 0.1f)
            Death();
    }

    private void Death()
    {
        isDead = true;
        Debug.Log("Dead");
        GetComponent<Score>().OnDeath();
    }

}