- Home /
Moving an object smoothly with a set distance and time
So, I have an object which I want to move with values given in the inspector, for example I want the object to travel 1 unit with a 3 second time. Here's what I'm using:
This executes if isR1InUse is true (it keeps executing in the Update function of the base class) and only stops when the same variable is set to false as I do it in the code below when the time ends.
It does three seconds but the object travels way more than just one unit. What am I doing wrong?
protected override void MeleeAttack()
{
Vector3 startingPos = meleeWeapon.transform.localPosition;
meleeWeapon.transform.localPosition
= Vector3.Lerp(startingPos, startingPos += new Vector3(0, 0, maxMeleeDistance), meleeAttackSpeed * Time.deltaTime);
timeElapsed += Time.deltaTime;
if (timeElapsed >= meleeAttackSpeed)
{
isR1InUse = false;
timeElapsed = 0;
}
}
To use lerp properly over a period of pre-defined time you need to lerp it over said time, Lerp is a linear interpolation between two points with a percentage of interpolation as the factor, when lerping like you are, it does apply smooth movement, but not guaranteed movement over the course of a specific time, it simply smoothes out the movement in a curve, and will actually never reach the destination, at least not in any noticable time, since it's always going to be speed time.deltaTime, so if your speed time is never 1.0f, then you'll never be 100% at the destination you intended, you'll just inch slower and slower towards it, until it appears to stop, but it doesn't.
public float $$anonymous$$axAttackTIme = 1.0f;
public Vector3 attackFinalPosition;
private Vector3 originalPosition;
public void StartAttack()
{
originalPosition = transform.localPosition;
isAttacking = true;
attackTime = 0;
}
void Update()
{
if (isAttacking)
UpdateAttack();
}
void UpdateAttack()
{
if (attackTime < $$anonymous$$axAttackTime)
{
transform.localPosition = Vector3.Lerp(originalPosition, attackFinalPosition, $$anonymous$$athf.inverseLerp(0, $$anonymous$$axAttackTime, attackTime));
attackTime +=Time.deltaTime;
}
else
{
//attack position reached
isAttacking = false;
}
}
This helped a lot. Thank you so much!
Glad to help, you can make it even better by using an AnimationCurve, it is poorly named because its actually just a curve. You would still need the percent of time passed, but you can call the curve to evaluate the current percentage and get a nicer movement like this.
public float $$anonymous$$axAttackTIme = 1.0f;
public Vector3 attackFinalPosition;
private Vector3 originalPosition;
public AnimationCurve curve;
public void StartAttack()
{
originalPosition = transform.localPosition;
isAttacking = true;
attackTime = 0;
}
void Update()
{
if (isAttacking)
UpdateAttack();
}
void UpdateAttack()
{
if (attackTime < $$anonymous$$axAttackTime)
{
transform.localPosition = Vector3.Lerp(originalPosition, attackFinalPosition, curve.Evaluate($$anonymous$$athf.inverseLerp(0, $$anonymous$$axAttackTime, attackTime)));
attackTime +=Time.deltaTime;
}
else
{
//attack position reached
isAttacking = false;
}
}
Then just make sure your curve is $$anonymous$$ 0 and max 1.0f.
Answer by toddisarockstar · Apr 02, 2019 at 04:56 AM
to understand the basic math for this. first you need to know the distance you are traveling on the x and y from point a to b.
you can get this by simply subtracting the finish from the start. this gives you a vector that represents distance and direction.
time.deltatime is a cute unity function that tells you how often your update is running in one second. so multiplying your distance vector by time.deltatime is the same as dividing out the movement your object needs to move to accomplish its goal in once second.... finally if you multiply by your amount of seconds you wish to reach your goal. you will be traveling at that rate.
i hope this helps
float seconds;
Vector3 begin;
Vector3 end;
Vector3 difference ;
void Start () {
seconds = 5;
begin = transform.position;
end = new Vector3 (11, 12, 13);
difference = end - begin;
}
void Update(){
transform.position += difference * Time.deltatime* seconds;
}
Your answer
Follow this Question
Related Questions
How to smooth my camera (Vector3.Lerp) 0 Answers
Movement Script 1 Answer
How to achieve smooth movement using the scroll wheel? 1 Answer
Problems with Lerp. 1 Answer