- Home /
Lerping & OnCollisionEnter - how do i lerp without update??
Hey Guys, Thankyou for trying to help me out,
I have "Script A" that is a component on enemy gameObjects. Within the script i have a variable that gives myself access to "Script B"
 public AdjustLighting adjustLightingScript;
and a Method that executes every time an enemy collides with my player:
 void OnTriggerEnter(Collider col) { 
         if (col.gameObject.tag == "Player") {
             adjustLightingScript.DimPlayerLight();
         }
     }
On "Script B" i have this method (the one that is being called from "Script A"):
 public void DimPlayerLight(){
         playerLight.light.range = Mathf.Lerp (playerLight.light.range, playerLight.light.range - 0.5f, Time.deltaTime);
     }
What i'm hoping to achieve is, every time a my player gets hurt, the point light i have attached to him gets dimmer in incremental steps, but with a smooth lerp, If i stick it in an update loop it won't achieve what i'm after.
Anyway, it works for a split second, but obviously doesn't finish the lerp because the OnTriggerEnter only gets called once,
how can i get the method to run until the lerp is complete?
Its very late and i'm sure that there is an easy solution but right now i have no idea and have been trying things for ages..... coding block!
The first idea on my head would be to set the method "DimPlayerLight" to an IEnumerator, and set a waiting time, just like this:
 public IEnumerator DimPlayerLight(){
          playerLight.light.range = $$anonymous$$athf.Lerp (playerLight.light.range, playerLight.light.range - 0.5f, Time.deltaTime);
 yield return new WaitForSeconds(4f);
 }
Then ins$$anonymous$$d of calling the method directly, you should use StartCoroutine(DimPlayerLight());
I didn't test this, so let me know if it works!
As $$anonymous$$idgardDev said, use an IEnumerator and a Coroutine. Also, check the Lerp documentation here, I think you want to do something like this:
 bool doingDimp = false;
 
     void OnTriggerEnter(Collider col)
     {
         if(!doingDimp)
         { 
             StartCoroutine(DimPlayerLight());
         }
     }
 
     IEnumerator DimPlayerLight()
     {
         doingDimp = true;
 
         float initialRange = playerLight.light.range;//Or the value you want
         float finalRange = playerLight.light.range - 0.5f;//Or the value you want
 
         float dimLightTime = 1.0f;//How much time will it take to dim the light
         float currentTime = 0.0f;
         bool done = false;
         while (!done)
         {
             float percent = currentTime / dimLightTime;
             if (percent >= 1.0f)
             {
                 percent = 1;
                 done = true;
             }
 
             playerLight.light.range = $$anonymous$$athf.Lerp(initialRange, finalRange, percent);
 
             currentTime += Time.deltaTime;
 
             yield return new WaitForEndOfFrame();
         }
 
         doingDimp = false;
     }
Answer by Chris_Dlala · Jan 13, 2015 at 12:58 PM
Hi, you can do this with a Coroutine as @MidgardDev suggested. However, I think the example he gave would not do what you need. In his example, the range will be set once, and then the coroutine will wait for 4 seconds and end. Below is a coroutine that should do what you want (untested and rushed):
     public IEnumerator DimPlayerLight(float startRange, float endRange, float duration)
     {
         float timeRemaining = duration;
         while (timeRemaining > 0)
         {
             timeRemaining -= Time.deltaTime;
             playerLight.light.range = Mathf.Lerp(startRange, endRange, Mathf.InverseLerp(duration, 0, timeRemaining));
             yield return null;
         }
         playerLight.light.range = endRange;
     }
You would call it like this: StartCoroutine(DimPlayerLight(100, 10, 3)); Be careful with coroutines being called more than once and conflicting with each other.
Hope that helps =D
Thankyou for all your answers but unfortunately i don't think in this situation it would be wise to use a coroutine, As i suspect many enemies to be colliding within short bursts of each other.
Does anyone know another way of accomplishing this without coroutines?
I think you're only choices are really to manage them in an Update or manage the coroutines. For example @AndresBarrera shows how to use a boolean to prevent the coroutine running more than once at a time.
Your answer
 
 
             Follow this Question
Related Questions
Multiple Cars not working 1 Answer
Distribute terrain in zones 3 Answers
how to use time on lerp 2 Answers
Mathf.Lerp not working 2 Answers
 koobas.hobune.stream
koobas.hobune.stream 
                       
                
                       
			     
			 
                