- Home /
Lerping outside of an Update Function
I have, for a long time now, tried using mathf.lerp outside of an update function but as of yet have never figured out how. The value simply jumps or goes half way. In the case of my current script, I'm trying to lerp the size of an object when it spawns. My problem is that the lerp is called before the object is instantiated into the game (which seems impossible to me as the script isn't even in the game yet).
function Update(){
if(Spawner.Starter == 1) {
Debug.Log('worked' + Spawner.Starter);
//Spawner.Starter is just a number I tried to use to tell this script when to start, it didn't
//work though
transform.localScale = new Vector3.(Mathf.Lerp(2, 0.1, Time.time/3), Mathf.Lerp(2, 0.1, Time.time/3), 0);
}
}
the sphere this code is assigned to is supposed to get smaller. Going from 2.0 x and y scale to 0.1 scale x and y. It should be called whenever the object is instantiated (keep in mind the object isn't even in the game anywhere until is is instantiated so I have no idea what is causing the script to run on awake even when the objects aren't active or in there)
I don't know if the code for the instantiating process is relevant but here it is;
var ThickWall : GameObject;
var ThinWall : GameObject;
var SpawnLocale : Transform;
static var Starter : int = 0;
yield WaitForSeconds(1);
Spawn(1, 0);
yield WaitForSeconds(1);
Spawn(1, 0);
function Spawn(num : int, rotation : float) {
if(num == 1) {
var clone : GameObject;
clone = Instantiate(ThickWall, SpawnLocale.position, Quaternion.Euler(0, 0, rotation));
clone.transform.localScale = Vector3(2, 2, 0);
Spawner.Starter = 1;
Spawner.Starter = 0;
yield WaitForSeconds(3);
Destroy(clone);
}
if(num == 2) {
var clone1 : GameObject;
clone1 = Instantiate(ThinWall, SpawnLocale.position, Quaternion.Euler(0, 0, rotation));
clone1.transform.localScale = Vector3(2, 2, 0);
Spawner.Starter = 1;
Spawner.Starter = 0;
yield WaitForSeconds(3);
Destroy(clone1);
}
}
I've been going over this problem for 6 hours now and have yet to find any solutions online or elsewhere. When the object is instantiated in (I instantiate it one second after the game runs) it starts out at a scale (it's a 2d circle so I will only be referring to a single plane size) of 1.5, even though the objects original scale is 2.0. It continues on with the lerp after this. The value is interpolating properly but it is starting to do it when it isn't supposed to. I'm making a game like super hexagon where it clones walls that spawn in on you (they shrink). Now when the first wall spawns in, it follows the lerp from where the lerp currently is (the lerp is working before I spawn the object in). When I spawn the second object, it spawns at the same position of the first object. It's as if the lerp function is starting when I start the game (which would be impossible since the script isn't even in the game yet) and not when the object with the script is instantiated. The interpolation happens once when the game starts and lasts 3 seconds. Any individual objects with the script that spawn in will keep their scale at the value of interpolation as if it is a global variable effecting everything. I really need help because to me this problem seems impossible. If the update function is removed the object simply spawns in and never shrinks or scales at all.
Did you read how $$anonymous$$athf.Lerp works and what the parameters are? Here's the doc
Lerp just calculates a value between the first 2 parameters based on the 3rd one. Since you pass in Time.time as the 3rd variable, the scale of all objects using this script only depends on how many seconds has passed since starting up the game.
Answer by yashpal · Jul 06, 2015 at 06:06 AM
hello @shadowkiller0071 ,
NoseKills is the right. Here I explain it in more detail.
Mathf.Lerp is Interpolates between a and b by t. t is clamped between 0 and 1. When t = 0 returns from. When t = 1 return to. When t = 0.5 returns the average of a and b.
ex:-
Mathf.Lerp(0,2,0.5); // this gives 1 because middle point between 0 and 2 is 1
Mathf.Lerp(0,2,0.25); // this gives 0.5,
Mathf.Lerp(0,2,0.75); // this gives 1.5,
And Time.time is continuously increasing from where game starts. game is so if you pass Time.time as 3rd parameter in the Lerp so it is only work for 1 sec.
and you need to find other way to do this.
I am using Lerp inside the Coroutine. and here is the video tutorial.
IEnumerator MyCoroutine (Transform target)
{
float timeToStart = Time.time;
while(Vector3.Distance(transform.position, target.position) > 0.05f)
{
transform.position = Vector3.Lerp(transform.position, target.position, (Time.time - timeToStart )* Speed ); //Here speed is the 1 or any number which decides the how fast it reach to one to other end.
yield return null;
}
print("Reached the target.");
yield return new WaitForSeconds(3f); // THis is just for how Coroutine works with delay
print("MyCoroutine is now finished.");
}
Hope this helps you.
Feel fee to ask if you still don't get.
EDITED:-
thank you @Hrungdak, you are right. i almost forget it.(the lerp gets slower over time because he uses transform.position. Also the endposition of the lerp is never reached (that's why the while-distance is neccessary). If you want to avoid this behaviour, you should use a fixed starting position.)
Here is code you can use. (it is in c#)
public Speed = 1f;
void Start()
{
StartCoroutine("MyCoroutine");
}
IEnumerator MyCoroutine ()
{
float timeToStart = Time.time;
while(transform.localScale.x != 0.1f) // This is your target size of object.
{
float tempTime = Mathf.Lerp(2, 0.1f, (Time.time - timeToStart )* Speed) ;//Here speed is the 1 or any number which decides the how fast it reach to one to other end.
transform.localScale = new Vector3 (tempTime , tempTime , 1);
yield return null;
}
print("Reached the target.");
}
Attach this script to gameObject which need to be shrink. Here MyCoroutine is called from the start so when gameobject is generate it this Coroutine called.
Interpolate is working but I can't find a way to signal it when to start, it seems to just start when the game is run and I can't figure out a way to control it.
then show some code, please. The solution of yashpal works, but the lerp gets slower over time because he uses transform.position. Also the endposition of the lerp is never reached (that's why the while-distance is neccessary). If you want to avoid this behaviour, you should use a fixed starting position.
I did... I see my code just fine in OP but here it is again: function Update(){ %|195149963_1|% %|-1922254334_2|% transform.localScale = new Vector3.($$anonymous$$athf.Lerp(2, 0.1, Time.time/3), $$anonymous$$athf.Lerp(2, 0.1, Time.time/3), 0); %|-1598980582_4|% }
reformatted op, the code button wasn't working beforehand.
@shadowkiller0071 Checkout my edited answer. hope it is more clear and useful for you. @Hrungdak thank you. i almost forget it.
Answer by Hrungdak · Jul 06, 2015 at 05:51 AM
You have to use a value that grows from 0 to 1 to use lerp. Lerp returns a value between minimum (1st parameter) and maximum (2nd parameter) based on parameter three. Some examples:
Mathf.Lerp(0, 100, 0f); // returns 0
Mathf.Lerp(0, 100, 0.5f); // returns 50
Mathf.Lerp(0, 100, 1f); // returns 100
So if you want to use this method, you must give a value between 0 and 1 as third parameter. And this is independent of Update().
So, if you want to lerp a value between say 100 and 500 over time:
private float m_TimeForLerpInSeconds = 10f;
private float m_ActualLerpTime = 0f;
private float m_FromLerp = 100f;
private float m_ToLerp = 500f;
void Update()
{
// Increase the time spent in the lerp
m_ActualLerpTime += Time.deltaTime;
// get a value between 0 and 1 out of the value
// rule of three
float lerpPercentage = (m_ActualLerpTime * 100 / m_TimeForLerpInSeconds) / 100;
// use the value in the lerp-method
float actualLerpValue = Mathf.Lerp(m_FromLerp, m_ToLerp, lerpPercentage);
}