Wayback Machinekoobas.hobune.stream
May JUN Jul
Previous capture 12 Next capture
2021 2022 2023
1 capture
12 Jun 22 - 12 Jun 22
sparklines
Close Help
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
  • Asset Store
  • Get Unity

UNITY ACCOUNT

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account
  • Blog
  • Forums
  • Answers
  • Evangelists
  • User Groups
  • Beta Program
  • Advisory Panel

Navigation

  • Home
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
    • Blog
    • Forums
    • Answers
    • Evangelists
    • User Groups
    • Beta Program
    • Advisory Panel

Unity account

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account

Language

  • Chinese
  • Spanish
  • Japanese
  • Korean
  • Portuguese
  • Ask a question
  • Spaces
    • Default
    • Help Room
    • META
    • Moderators
    • Topics
    • Questions
    • Users
    • Badges
  • Home /
avatar image
0
Question by Jabes22 · Jan 19, 2017 at 05:27 PM · coroutinelerp

Howcome this coroutine loops once?

I'm having a bit of a hard time understand coroutine and lerp. This IEnumerator should iterate several times, but the loop only ever fires once. Also not sure if the Lerp is right.

Thanks for reading.

 IEnumerator move_item()
     {
 
         for (float t = 0; t < 1; t += Time.deltaTime / 1f) 
         {
 
             recievedItem.transform.position = Vector3.Lerp (recievedItem.transform.position, transform.position, t);
             yield return null;
             StartCoroutine (move_item());
         }
 
         yield return new WaitForSeconds(1f);
     }
Comment
Add comment · Show 1
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image Erethan · Jan 19, 2017 at 06:06 PM 0
Share

[meta] Jabes22, try not to ask multiple questions at the same time, and people here don't usually like pleasantries. Try to be as impersonal as possible.

2 Replies

· Add your reply
  • Sort: 
avatar image
0
Best Answer

Answer by Erethan · Jan 19, 2017 at 05:59 PM

Generally, you would want the Lerp method to have a stop condition related to the distance from object to target

 IEnumerator move_item()
 {
         if(Vector3.Distance(recievedItem.transform.position, transform.position) > 0.01f)
         {
                 recievedItem.transform.position = Vector3.Lerp(recievedItem.transform.position, transform.position, Time.deltaTime);
                 yield return null;
                 StartCoroutine(move_item());
         }
 }
  
Comment
Add comment · Show 9 · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image Erethan · Jan 19, 2017 at 06:02 PM 0
Share

Note that after every Vector3.Lerp call, recievedItem will be closer to its target (if the range is between 0 and 1). You don't need to increase your t value up to 1.

avatar image CesarNascimento · Jan 19, 2017 at 06:20 PM 1
Share

Ins$$anonymous$$d of always starting the Coroutine I think it'd be better to do it like this, no?

 IEnumerator move_item()
  {
          while(Vector3.Distance(recievedItem.transform.position, transform.position) > 0.01f)
          {
                  recievedItem.transform.position = Vector3.Lerp(recievedItem.transform.position, transform.position, Time.deltaTime);
                  yield return null;
          }
  }

avatar image Erethan CesarNascimento · Jan 19, 2017 at 06:30 PM 0
Share

It is indeed more efficient, but since the question was about coroutine loops, I thought to write it that way to illustrate the concept discussed.

avatar image Jabes22 CesarNascimento · Jan 19, 2017 at 06:39 PM 0
Share

I've done that exact code before. The ENumerator only runs once for some reason. Thanks for replying.

 using UnityEngine;
 using System.Collections;
 
 public class btn_script : $$anonymous$$onoBehaviour {
 
     // Player
 
     public GameObject player;
 
     public GameObject btn;
     public GameObject highlightBtn;
 
     private bool highlighted;
 
     private GameObject highlightedID;
     
     private GameObject recievedItem;
     private bool movingItem;
 
     // Use this for initialization
     void Start () {
 
         highlighted = false;
         movingItem = false;
 
     }
     
     // Update is called once per frame
     void Update () {
     
 
         if (highlighted && highlightedID == null) {
             
             highlightedID = (GameObject)Instantiate (highlightBtn, new Vector3 (btn.transform.position.x, btn.transform.position.y, 0f), transform.rotation);
             
         } else if(!highlighted && highlightedID != null){
 
                 Destroy (highlightedID);
 
         }
 
         if (movingItem) {
 
                 
         }
 
         // End update
     }
 
     void On$$anonymous$$ouseDown()
     {
 
         // Left clicked menu button
         if (Input.Get$$anonymous$$ouseButton (0)) 
         {
             if(name.Contains("close"))
             {
 
                 // Remove hover from all menu buttons
                 GameObject[] objects = GameObject.FindGameObjectsWithTag("floor_item");
 
                 foreach(GameObject item in objects)
                 {
                     
                     if(item.GetComponent<Hover$$anonymous$$enu>() != null)
                     {
 
                         item.GetComponent<Hover$$anonymous$$enu>().clear();
                         
                     }
                     
                 }
 
                 // End if button close clicked
             }else if(name.Contains ("take"))
             {
 
                 // Add the item to the player
                 recievedItem = player.GetComponent<Character>().return_last_clicked_item();
                 player.gameObject.GetComponent<Character>().recieve_item();
 
                 // Remove hover from all menu buttons
                 GameObject[] objects = GameObject.FindGameObjectsWithTag("floor_item");
                 
                 foreach(GameObject item in objects)
                 {
                     
                     if(item.GetComponent<Hover$$anonymous$$enu>() != null)
                     {
                         
                         item.GetComponent<Hover$$anonymous$$enu>().clear();
                         
                     }
                     
                 }
             
 
                 movingItem = true;
 
                 StartCoroutine (move_item());
                 // End take clicked
             }
             
             
             // End left clicked menu button
         }
 
 
     }
 
     IEnumerator move_item()
     {
         while(Vector3.Distance(recievedItem.transform.position, transform.position) > 0.01f)
         {
             recievedItem.transform.position = Vector3.Lerp(recievedItem.transform.position, transform.position, Time.deltaTime);
             yield return null;
         }
     }
 
 
     void On$$anonymous$$ouseOver()
     {
 
         // count all opened menues
             
         highlighted = true;
 
         // End On$$anonymous$$ouseOver
     }
 
     void On$$anonymous$$ouseExit()
     {
 
         highlighted = false;
 
     }
 
 }
 
avatar image Erethan Jabes22 · Jan 19, 2017 at 06:52 PM 0
Share

Try adding Debug.Log(Vector3.Distance(recievedItem.transform.position, transform.position)); before the while statement. Analyse what is going on. What are the values printed in that Debug.Log?

Show more comments
avatar image
1

Answer by CesarNascimento · Jan 19, 2017 at 06:53 PM

Ah now I see. You're using Lerp incorrectly. While using it, both the StartPosition and EndPosition should stay the same, only t should change. See http://wiki.unity3d.com/index.php?title=MoveObject and http://answers.unity3d.com/questions/14288/can-someone-explain-how-using-timedeltatime-as-t-i.html as examples.

In your case I'd use Vector3.MoveTowards, unless you absolutely needs to use Lerp. Something like this

 IEnumerator move_item()
   {
           float speed = 5f;
           float step = Time.deltaTime * speed;
           while(Vector3.Distance(recievedItem.transform.position, transform.position) > 0.01f)
           {
                   recievedItem.transform.position = Vector3.MoveTowards(recievedItem.transform.position, transform.position, step);
                   yield return null;
           }
   }


Comment
Add comment · Show 8 · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image Jabes22 · Jan 19, 2017 at 07:12 PM 0
Share

Same problem with that function. There must be something else, but I can't see what. Is something missing in the IEnumerator code? I never fully grasped it beyond it being a function that could run in the background.

When I click the take button the item moves a few pics right, and stops.

avatar image CesarNascimento Jabes22 · Jan 19, 2017 at 07:20 PM 0
Share

That's weird. Do as @Erethan said and log the values of both positions and the step.

avatar image Erethan · Jan 19, 2017 at 07:52 PM 0
Share

Both functions can be use but have different curves along the process. If you want a Lerp effect, you can use Vector3.Lerp. If you want a constant velocity, use $$anonymous$$oveTowards. However, the problem is not likely to be related to that.

avatar image CesarNascimento Erethan · Jan 19, 2017 at 08:00 PM 0
Share

Absolutely. Both methods should be working fine.

avatar image Jabes22 CesarNascimento · Jan 19, 2017 at 10:24 PM 0
Share

Weird. Okay, I did the log. The while loop never fires once, despite the condition being fine. The first log, before while, is a distance of 4.

 IEnumerator move_item()
     {
         float speed = 5f;
         float step = Time.deltaTime * speed;
         Debug.Log ("Before While: " + Vector3.Distance(recievedItem.transform.position, transform.position));
         while(Vector3.Distance(recievedItem.transform.position, transform.position) > 0.01f)
         {
             recievedItem.transform.position = Vector3.$$anonymous$$oveTowards(recievedItem.transform.position, transform.position, step);
             yield return null;
             Debug.Log ("After While: " + Vector3.Distance(recievedItem.transform.position, transform.position));
         }
 
     }


Show more comments
avatar image NoseKills Erethan · Jan 20, 2017 at 07:31 AM 1
Share

Both functions can be use but have different curves along the process.

I have to nitpick and say the curve part is not true... Both of the functions just calculate a position based on the parameters you put in.

The "curve" either one gives only depends on the parameters you feed in. $$anonymous$$any people use Lerp "the wrong way" a = Lerp(a , b, x);, which does give an effect that i guess you mean by "the Lerp effect" but that never returns the value of b (unless x == 1)

You get the same effect with $$anonymous$$oveTowards if you change the math to do the same thing

 var distance = (b-a).magnitude;
 var moveAmount = distance * x;
 a = Vector3.$$anonymous$$oveTowards(a, b, moveAmount);
 
 // Is the same as
 
 a = Vector3.Lerp(a, b, x);
 
 // Both move vector a 'x' percent of the way closer to b.



Your answer

Hint: You can notify a user about this post by typing @username

Up to 2 attachments (including images) can be used with a maximum of 524.3 kB each and 1.0 MB total.

Follow this Question

Answers Answers and Comments

67 People are following this question.

avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image

Related Questions

object's children not moving with it when using a Lerp-ing coroutine 0 Answers

Smooth damp the lowpass frequency in coroutine: value only changing in 1 frame 1 Answer

Why is my Mathf.Lerp not lasting for the intended duration, even though I'm not using Time.time as the t variable? 1 Answer

[HELP] How to make camera smooth change position while follow object? 1 Answer

If statement not being fullfilled until GameObject inspected in inspector. 0 Answers


Enterprise
Social Q&A

Social
Subscribe on YouTube social-youtube Follow on LinkedIn social-linkedin Follow on Twitter social-twitter Follow on Facebook social-facebook Follow on Instagram social-instagram

Footer

  • Purchase
    • Products
    • Subscription
    • Asset Store
    • Unity Gear
    • Resellers
  • Education
    • Students
    • Educators
    • Certification
    • Learn
    • Center of Excellence
  • Download
    • Unity
    • Beta Program
  • Unity Labs
    • Labs
    • Publications
  • Resources
    • Learn platform
    • Community
    • Documentation
    • Unity QA
    • FAQ
    • Services Status
    • Connect
  • About Unity
    • About Us
    • Blog
    • Events
    • Careers
    • Contact
    • Press
    • Partners
    • Affiliates
    • Security
Copyright © 2020 Unity Technologies
  • Legal
  • Privacy Policy
  • Cookies
  • Do Not Sell My Personal Information
  • Cookies Settings
"Unity", Unity logos, and other Unity trademarks are trademarks or registered trademarks of Unity Technologies or its affiliates in the U.S. and elsewhere (more info here). Other names or brands are trademarks of their respective owners.
  • Anonymous
  • Sign in
  • Create
  • Ask a question
  • Spaces
  • Default
  • Help Room
  • META
  • Moderators
  • Explore
  • Topics
  • Questions
  • Users
  • Badges