I'm trying to create two lerps that go sequentially. I've done a lot of searching and there weren't any good answers. I tried using things like dottween and iTween and have ended up with nothing. I'm trying to move 2000 objects around. Essentially a timeline of data points from period 1 to period 2 to period 3. Using iTween destroyed my performance. My initial method was create the first coroutine to go A to B. Then at the end of that coroutine, call my second one. The first one gets called in update. But i did debug statements and seems that they don't get called sequentially. Any help would be appreciated.

Code (csharp): float Lerp3(float a, float b, float c, float t) { if (t <= 0.5f) { return Mathf.Lerp(a, b, t * 2f); } else { return Mathf.Lerp(b * 2f, c, t); } } Something like this? Untested.

Yes, something like that, but for a vector3 lerp, i was doing this: Code (CSharp): float distCovered = (Time.time - start_time) * lerp_speed; float fracJourney = distCovered / journey_length_1; transform.position = Vector3.Lerp (start_position, middle_position, fracJourney); then i had the same thing but with middle_position and end_position and journey_length_2. The journey lengths are simply the vector 3 lengths. In your example there is the same t values. What would i use for that?

t is a value between 0 and 1, which is common for any lerping library. 0 is A, 0.5 is B and 1 is C. Plug it in changing Mathf.Lerp to Vector3.Lerp and of course float ABC becomes Vector3 ABC.

Just a note, iTween is not the best choice. I would use Leantween or Dotween. Personally I use LeanTween for many things and it works great. There are different calls you can do. There are ways to create paths or at the end of a LeantTween call, you can do a OnComplete that has it do the next step when the tween is finished. Works super well. Code (CSharp): LeanTween.move(targetObject, someVector, .5f).setOnComplete(() => { //Tween is complete, do something next. }); This is just a basic example of moving something over .5 secs and then when it's done, it will do something else for example.

@Brathnann thanks, i will check it out. @hippocoder, So if i need to go from point A to B, i can't just use a discrete value. i need to keep incrementing it. So my first thought is, call the Lerp3 function in Update, and then increment t by .1. Is this the correct approach, so that it smoothly goes from a to b to c?

t += Time.deltaTime; if (t>=0.5f) Debug.Log("Reached B"); Not sure what's hard to understand, it behaves exactly like Unity's Mathf.Lerp or Vector3.Lerp, except with 3 values instead of 2?

Okay, so i created my lerp3 function and called it in update. I have 2 problems. One, it runs very fast. I want it to be slower and have control over the speed. Ideally it should run about 5 seconds. The second problem is that while the animation is running it runs at about 2 fps. Probably because there's 2000 objects and this function is being called on update in all of them. So how can i speed this up.

Coroutine's would be faster than update. But without looking at the code/profiler it would be hard to tell where to optimise

Just slow down your time parameter. A typical way to do this is to multiply time by a speed float. Don't call Update on 2000 objects. Use a manager class instead, with an array of 2000 objects. And loop through the objects in an array. If that doesn't work, consider switching the whole thing to a particle effect.

To add to what @BoredMormon says about a manager. This great article that Unity put out https://blogs.unity3d.com/2015/12/23/1k-update-calls/ which describes calling updates vs using a manager.

A few other general performance tips. Cache the Transforms of each object for looping (the transform getter has some safe-checking that only really needs to be done once during the lerp animation) Set localposition instead of position. (setting position causes unity to internally figure out the local position via traversing the ancestry of that object's heirarchy) multiply all your floats together before multiplying a vector with the float. A Vector*(float*float*float) gives the same result as Vector*float*float*float. But the first is 6 multiplications while the latter is 9 multiplications. keep the hierarchy of those 2000 objects as simple as possible. if each object has one child then the loop is actually affecting 4000 transforms. if each object has 4 children thats 10000 transforms to update. affecting the rotation will also multiply the number of calculations changing the local position and rotation of each object that has 4 children is actually 20000 updates Unity 5.5 has plans to greatly improve the performance of updating the transforms by using a dirty transform concept. and as BoredMormon said, use a manager. the less work that you don't have unity do for you automatically, the faster your code is going to run. One Update message is far faster than 2000 Update messages However, the most important thing to do off to bat to figure out this problem is. Use the Profiler! It'll tell you exactly whats killing your fps.

Here is a rethink of what you are doing.... Create methods that are reusable later on... (vs didnt say there were any errors, but I didnt run it.) Code (csharp): public Vector3 LerpOverDistance(Vector3[] vectors, float time){ time = Mathf.Clamp01(time); if(vectors == null || vectors.Length == 0){ throw(new Exception("Vectors input must have at least one value")); } if(vectors.Length == 1){ return vectors[0]; } if(time == 0){ return vectors[0]; } if(time == 1){ return vectors[vectors.Length - 1]; } float[] distances = new float[vectors.Length - 1]; float total = 0; for(int i=0; i<vectors.Length; i++){ distances[i] = (vectors[i] - vectors[i + 1]).sqrDistance; total += distances[i]; } float current = total * time; int p = 0; while(current - distances[p] > 0){ current -= distances[p++]; } if(distances[p] == 0) return vectors[p]; return Vector3.Lerp(vectors[p], vectors[p + 1], current / distances[p]); } public Vector3 LerpOverNumber(Vector3[] vectors, float time){ time = Mathf.Clamp01(time); if(vectors == null || vectors.Length == 0){ throw(new Exception("Vectors input must have at least one value")); } if(vectors.Length == 1){ return vectors[0]; } if(time == 0){ return vectors[0]; } if(time == 1){ return vectors[vectors.Length - 1]; } float t = time * vectors.Length; int p = (int)Mathf.floor(t); t -= p; return Vector3.Lerp(vectors[p], vectors[p + 1], t); }

this worked for me but in the else statement you need to multiply "b" by 2. "return Mathf.Lerp(b*2, c, t)"

I hate to come and be the "Well, actually," guy, but multiplying b by 2 is also wrong. You need to multiply t by the number of points - 1, and then subtract by the whatever number the leftmost point in the lerp is (so if you are lerping between points a & b, a is the 1st point and b is the 2nd, so you subtract 1). A bad formula for this is Lerp(point1, point2, t * (numberOfPoints - 1) - leftPointNumber So for 3 points and the 2nd lerp, it's Mathf.Lerp(b, c, (t * 2f) - 1f); Here's the code for this too. Hopefully, this saves someone in the future from 3 hours of figuring it out. Code (CSharp): float Lerp3(float a, float b, float c, float t) { if (t <= 0.5f) { return Mathf.Lerp(a, b, t * 2f); } else { return Mathf.Lerp(b, c, (t * 2f) - 1f); } }

Hey ! Here is a version less visible but without condition (indispensable for shader) : Code (CSharp): // t between -1 and 1 float Lerp3(float a, float b, float c, float t) { return lerp(lerp(a, b, min(t, 0.0f) + 1.0f), c, max(t, 0.0f)); } With t include in [-1, 1]. To convert t from [0, 1] to [-1, 1] apply: Code (CSharp): // t between 0 and 1 float Lerp3(float a, float b, float c, float t) { t = t * 2.0f - 1.0f; return lerp(lerp(a, b, min(t, 0.0f) + 1.0f), c, max(t, 0.0f)); } I would also like to state a limitation of all the proposed formulas. If we consider the area under the curve that occupies a, b and c. So, a will occupy 25%, b 50% and c 25%. If anyone has a mathematical solution to this problem, I would be curious to know it.