Hallowed
Hallowed

Reputation: 11

Vector3.Lerp isn't moving the whole way

Basically I'm trying to create a rolling system for my top down RPG style game, but when I do the Vector3.Lerp it doesn't move the entire way

The code is:

public void CheckSpaceKey()
{
    if (exhausted == false)
    {
        if (Input.GetKey(KeyCode.Space) && canRoll)
        {
            if (rollDir == RollDir.Up)
            {
                Vector3 rollStartPos = new Vector3(transform.position.x, transform.position.y, -1.0f);
                Vector3 rollEndPos = new Vector3(transform.position.x, transform.position.y + 3, -1.0f);
                transform.position = Vector3.Lerp(rollStartPos, rollEndPos, Time.deltaTime);
                canRoll = false;
                playerStats.stamina -= 10;
                Invoke("RollCooldown", 1.5f);
            }
        }
    }
}

public void RollCooldown()
{
    canRoll = true;
}

This should be making my player move upwards 3 units, but it instead is moving a random number of around 0.35 to 0.45.

Also CheckSpaceKey is being called in update

Upvotes: 1

Views: 450

Answers (2)

nkazz
nkazz

Reputation: 560

This will not move 3 Units, you call transform.position only inside the if case and access the if case only once every 1.5 seconds. Lerp will not update your position every frame but only the frame it is called, if you the object to move constantly you have to update your position constantly you should crate rollStartPos and rollEndPos inside the first if and create add

else{ 
     time += Time.deltaTime;
     transform.position = Vector3.Lerp(rollStartPos, rollEndPos, time);
}

under the 2nd if. This way it will lerp til rollEndPos unless the ball(?) is exhausted, if it should roll even when it's exhausted you need to update the position outside the first if

Upvotes: 2

Ruzihm
Ruzihm

Reputation: 20269

Lerp doesn't do what you think it does. Assuming Time.deltaTime is about 1/60, it's going to move the unit 1/60th of the way to the destination, and that's it.

Consider using a coroutine that updates the t parameter for Lerp with each frame:

public void CheckSpaceKey()
{
    // by the way, this could just be `if (!exhausted)`
    // although some coding guidelines require this format below
    if (exhausted == false)
    {
        if (Input.GetKey(KeyCode.Space) && canRoll)
        {
            if (rollDir == RollDir.Up)
            {
                StartCoroutine(DoRoll(Vector3.up * 3));
            }
        }
    }
}

IEnumerator DoRoll(Vector3 offset)
{  
    float duration = 1f;

    canRoll = false;
    playerStats.stamina -= 10;
    Invoke("RollCooldown", 1.5f);

    Vector3 rollStartPos = new Vector3(transform.position.x, transform.position.y, -1.0f);
    Vector3 rollEndPos = rollStartPos + offset;

    float t = 0;
    while (t < 1f)
    {
        t = Mathf.Min(1f, t + Time.deltaTime/duration);
        transform.position = Vector3.Lerp(rollStartPos, rollEndPos, t);
        yield return null; 
    }
}

public void RollCooldown()
{
    canRoll = true;
}

Upvotes: 4

Related Questions