Reputation: 11
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
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
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