Wayback Machinekoobas.hobune.stream
May JUN Jul
Previous capture 14 Next capture
2021 2022 2023
2 captures
13 Jun 22 - 14 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
8
Question by Ronin6 · Aug 04, 2012 at 10:51 PM · transformvector3timelerpmovetowards

Move Transform to Target in X seconds

 public Transform a;
 public Transform target;
 public float x = 30f; //amount of seconds for A to reach Target

I have a Transform A and a Transform target. My goal is to make A reach Target in x seconds. I have tried both Vector3.Lerp and Vector3.MoveTowards but can not figure out the problem.

Comment
Add comment · Show 2
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 whydoidoit · Aug 04, 2012 at 10:57 PM 0
Share

What language? Would you prefer to do it in Update or in a coroutine?

avatar image Ronin6 · Aug 04, 2012 at 11:01 PM 0
Share

C#. I prefer Update but I would use a coroutine if I need to.

3 Replies

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

Answer by whydoidoit · Aug 04, 2012 at 11:05 PM

Ok so Lerp will move you there in a guaranteed amount of time, but you need to record the starting position - which is trickier in Update.

    float t;
    Vector3 startPosition;
    Vector3 target;
    float timeToReachTarget;

     void Start()
     {
             startPosition = target = transform.position;
     }

     void Update() 
     {
             t += Time.deltaTime/timeToReachTarget;
             transform.position = Vector3.Lerp(startPosition, target, t);
     }

     public void SetDestination(Vector3 destination, float time)
     {
            t = 0;
            startPosition = transform.position;
            timeToReachTarget = time;
            target = destination; 
     }
Comment
Add comment · Show 5 · 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 Ronin6 · Aug 04, 2012 at 11:37 PM 0
Share

Thanks a lot. After lots of hacking at my code I finally got it working correctly.

avatar image whydoidoit · Aug 04, 2012 at 11:40 PM 12
Share

It's easier in a coroutine because you can keep it all nicely in one place.

  public IEnumerator $$anonymous$$oveToPosition(Transform transform, Vector3 position, float timeTo$$anonymous$$ove)
   {
      var currentPos = transform.position;
      var t = 0f;
       while(t < 1)
       {
             t += Time.deltaTime / timeTo$$anonymous$$ove;
             transform.position = Vector3.Lerp(currentPos, position, t);
             yield return null;
      }
    }
avatar image dynamicvoltagegames · Aug 16, 2018 at 06:37 PM 0
Share

startPosition = target = transform.position;

should just be:

target = transform.position

avatar image Xakiru dynamicvoltagegames · Feb 07, 2019 at 10:07 AM 0
Share

void Start() { startPosition = transform.position; }

avatar image VirtuallyHealthy · Jun 20, 2020 at 06:13 PM 0
Share

Where/when do you call SetDestination though...?

avatar image
17

Answer by Lakeffect · Feb 25, 2016 at 08:27 AM

Move any object to any place at any speed (units/seconds) or in any time -- all done without using Update:

  StartCoroutine (MoveOverSeconds (gameObject, new Vector3 (0.0f, 10f, 0f), 5f));

  public IEnumerator MoveOverSpeed (GameObject objectToMove, Vector3 end, float speed){
     // speed should be 1 unit per second
     while (objectToMove.transform.position != end)
     {
         objectToMove.transform.position = Vector3.MoveTowards(objectToMove.transform.position, end, speed * Time.deltaTime);
         yield return new WaitForEndOfFrame ();
     }
 }

 public IEnumerator MoveOverSeconds (GameObject objectToMove, Vector3 end, float seconds)
 {
     float elapsedTime = 0;
     Vector3 startingPos = objectToMove.transform.position;
     while (elapsedTime < seconds)
     {
         objectToMove.transform.position = Vector3.Lerp(startingPos, end, (elapsedTime / seconds));
         elapsedTime += Time.deltaTime;
         yield return new WaitForEndOfFrame();
     }
     objectToMove.transform.position = end;
 }
Comment
Add comment · Show 7 · 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 naghekyan · Jul 26, 2017 at 05:10 PM 0
Share

This code is wrong. Should be objectTo$$anonymous$$ove. transform. position.

avatar image Lakeffect · Jul 26, 2017 at 10:16 PM 0
Share

Where? All instances of objectTo$$anonymous$$ove are followed by .transform.position in the code above -- I think...

avatar image naghekyan · Jul 27, 2017 at 04:29 AM 0
Share

transform.position = end; -> objectTo$$anonymous$$ove.transform.position = end;

transform.position = Vector3.Lerp(startingPos, end, (elapsedTime / seconds)); -> objectTo$$anonymous$$ove.transform.position = Vector3.Lerp(startingPos, end, (elapsedTime / seconds));

avatar image Lakeffect naghekyan · Sep 28, 2017 at 03:56 AM 0
Share

Thanks! You're absolutely right! Sorry about the confusion.

avatar image SamuelGoldenbaum · Dec 07, 2019 at 10:26 PM 0
Share

What is the purpose of objectTo$$anonymous$$ove.transform.position = end; - is this not handled in the while()?

avatar image R0hit97 SamuelGoldenbaum · Apr 20, 2020 at 01:40 PM 0
Share

i guess with the Lerp function you are never going to reach the target position, that is how the Lerp function works. That is why when it comes out of loop the position is set to exact target position.

avatar image Bunny83 R0hit97 · Apr 20, 2020 at 03:58 PM 0
Share

Lerp would work perfectly fine as long as the "t" value reaches 1 or surpasses it. However that's not the case in the original code. Since he first does the lerp and then increments his timer value he's always lagging one step behind. Since the while loop will break as soon as the timer is equal or greater than the target the last executed iteration has to result in a t value smaller than 1.


However a better solution would be to just swap the two lines and doing

 elapsedTime += Time.deltaTime;
 objectTo$$anonymous$$ove.transform.position = Vector3.Lerp(startingPos, end, (elapsedTime / seconds));

That way elapsedTime will actually reach (and most the time overshoot) the target "seconds" and therefore the last executed Lerp step would have a t value of at least 1 or slightly greater. Since Lerp internally clamps the t value between 0 and 1 you get a perfect 1 so you will get the target position when doing it this way.


Also you really shouldn't use WaitForEndOfFrame. It allocates memory for nothing and also carries out this calculation way after the current frame has rendered. So its effect would be seen the next frame. Just use "yield return null;" whenever you want to wait for the next frame. No garbage is allocated and it will be executed during the normal "logic" / tick time of the frame before the rendering is started.


ps: I should note that the way Unity implements Lerp for Vector3 it's not guaranteed to get the target value back with 100% accuracy. This is because they implemented it the "delta" way. The two different implementations have different advantages / disadvantages. While using the delta method does not necessarily reproduce the exact target value, the path it follows is more numerical stable a line between the two points. When using the (1-t)*a + t*b approach we get the target (`b`) to 100% when t is 1. However the path between a and b, while still being linear, could jitter a little bit more along the line. The delta / direction approach is slightly cheaper to calculate (6 additions +3 multiply vs 6 multiply + 3 additions + 1 subtraction when you cache "1-t")

avatar image
-2

Answer by JaPete · Dec 27, 2018 at 05:05 AM

Using --- public IEnumerator MoveToPosition(Transform transform, Vector3 position, float timeToMove) { var currentPos = transform.position; var t = 0f; while(t < 1) { t += Time.deltaTime / timeToMove; transform.position = Vector3.Lerp(currentPos, position, t); yield return null; } }


This code does not work as described above by "whydoidoit"

The code makes an object Move in 4-5 seconds, when the INPUT is 1.

BROKEN FORMULA

Comment
Add comment · Show 1 · 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 Decstar_G · Jan 27, 2019 at 09:46 PM 1
Share

That should be a comment, not an answer.

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

23 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

Related Questions

How to move an object from another position using Vector3.moveTowards precisely and slowly by swiping (mobile) 1 Answer

Setting target position in Vector3.MoveTowards 2 Answers

Vector3.MoveTowards and Quaternion.RotateTowards 1 Answer

How to smoothly rotate to certain directions using input axis 1 Answer

Move from one position to another in x seconds 2 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