- Home /
Saving the starting position of a Lerp during Update
I have seen a number of examples for Vector3.Lerp where the original starting position is stored in the start function and then later used to compare the current position in relation to the end target position. My issue is that I need to store the starting position of the lerp in update not start, since the lerp will be happening on a gameobject being moved around the scene and therefore its starting position will need to be set each time manually. Here is my simple code which sits in update:
if (doLerp) {
startPos = transform.position;
transform.position = Vector3.Lerp(transform.position, target.position, Time.deltaTime * speed);
}
The "doLerp" is set to true whenever a lerp needs to take place and hence when a "startPos" needs to be stored. The issue with the above of course is that once the "startPos" is stored it will continue to be updated while "doLerp" is true, and since the lerp is changing the transform.position this will mean that the startPos will change as well instead of staying the same. How can I record the starting position of a transform before a lerp and not have it changed when the lerp begins?
I need this so that I can do calculations such as the distance between the starting and target positions, and then compare those to the distance between the current and target positions; and find out the percentage of the "trip" that has been completed.
Can't you set the startPos wherever you set doLerp to true?
ie:
if(someCondition && !doLerp) {
doLerp = true;
startPos = transform.position;
}
I don't fully comprehend the issue, merely because I don't get why you want to make those calculations. You're explaining the technical reasons, but you're not giving us a context. Do you continuously use the Lerp? When is doLerp set to false? If one procedural movement finishes, another one commences right away? Honestly, I would use an IEnumerator for this. Before the while loop, I would have the value stored in a variable and upon exiting the loop, I would make my calculations. Inside of the loop, it would set the transform.position appropriately, without messing with the previous variable.
The basic idea of this question, is how to "do something" within the update function only once. In this case I have a lerp in update and I would like to store the starting position of the transform before the lerp begins moving the transform. But I need to store this so that the position doesn't continue to update during the lerp. The lerping begins whenever a specific bool is set to true, and therefore will happen several times within a session. Hence why I cannot use Start or Awake.
Answer by Deadcow_ · Apr 11, 2015 at 01:59 PM
You need to store initial position outside the Update function.
But in your case it'll be the best to use coroutine:
IEnumerator MyLerp()
{
if (!doLerp) yield break;
doLerp = false;
Vector3 initPos = transform.position;
float elapsed = 0;
while (elapsed < speed)
{
elapsed += Time.deltaTime;
transform.position = Vector3.Lerp(initPosition, target.Position, elapsed / speed);
yield return null;
}
}
and in update (or better where you set startPos to true)
if (doLerp) {
StartCoroutine(MyLerp());
}
Should work fine
Thanks for that. This does seem to store the "initPos" only once but for some reason placing the lerp inside the coroutine is making the lerp very choppy. Could this be done by leaving the lerp inside update and only use the coroutine to store the initial position?
In this case code inside While block will be executed as frequent as Update function. $$anonymous$$y code is assumes that 'doLerp = true' is assigned once when needed and won't be assigned again while lerp goes. In your case doLerp probably assigned several times, and coroutine starts several times (which make it choppy)
Okay, there is way to fix this, as I said - you need to put this StartCoroutine where you set startPos to true.
IEnumerator $$anonymous$$yLerp()
{
if (doLerp) yield break;
doLerp = true;
Vector3 initPos = transform.position;
float elapsed = 0;
while (elapsed < speed)
{
elapsed += Time.deltaTime;
transform.position = Vector3.Lerp(initPosition, target.Position, elapsed / speed);
yield return null;
}
doLerp = false;
}
so, you alter doLerp only inside the coroutine, to ensure it'll be executed once in a time.
don't know where you assign doLerp to true, it may be something like this:
if (Input.Get$$anonymous$$eyDown($$anonymous$$eyCode.L))
doLerp = true;
in update or anything else, just put
StartCoroutine($$anonymous$$yLerp());
ins$$anonymous$$d of
doLerp = true;
Answer by jtok4j · Apr 11, 2015 at 02:02 PM
Hey, I'm not much of a programmer, but on my third game, so I thought I'd comment.
Essential, I believe, your solution is already spelled out in your question/description.
You need to add another variable or perhaps two to the scripting. You need a "starting" variable, which is the very beginning one and doesn't change. Then you need a "current" variable (which you've got already, showing the current position when the dolerp is made true. Lastly, you need the "target position " variable, which might or might not change, according to your game.
So, I believe that your choice lies essentially in where to record/set the initial/starting position variable. Do you want to set it as soon as the object is created/spawned? Then use void Awake () { to get that right at the beginning. Otherwise, you may prefer to use a separate script to record this, if you must set the initial location later, perhaps with a collider of some sort, if this object is moving. (Set the collider around the object, so when it starts moving, it fires the script which record the colliding object's locations.
Sorry for the generalizations. Just trying to help that creative spark continue onward!
I think you're onto something here, I could store the position only when the lerp is not taking place and that way during any lerp I would be able to use the last position stored before the lerp.
Yes, Good point: "only when the lerp is not taking place". :) Now, just add this to what Deadcow_ has shown you and the pieces will come together. $$anonymous$$eep us updated, and we'll try to continue to help out. :)
Your answer
Follow this Question
Related Questions
Script variables resetting on play 0 Answers
Vector3.Lerp works outside of Update() 3 Answers
Ping pong position using lerp 3 Answers
How do I translate around a circle? 3 Answers