Wayback Machinekoobas.hobune.stream
May JUN Jul
Previous capture 13 Next capture
2021 2022 2023
1 capture
13 Jun 22 - 13 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 Rick74 · Mar 20, 2014 at 09:42 PM · javascriptlerpvector3.lerp

Trying to set up a lerp position system for the camera and failing...

Well this has had me pulling my hair out all day. So I've given up and will post it here.

The goal; ( set up a state system for the camera which will tell it which position to lerp too, depending on the state it's in)

What's happening; works ok, except every other state switch camera "snaps" to the end position with no lerp. And the transforms never seem to hit the goal position I've set in code. ex. - instead of x 15. it will go to x 14.9997 and stop. I don't understand that.

the code;

 function Update ()
 {
     if ( moveCamLeft )                                                                                                    
     {
         MoveCamLeft ();    
                         
     }
     if ( moveCamRight )                                                            
     {
         MoveCamRight ();                                                        
         
     }                                                                
     if ( moveCamCenter )                                                        
     {
         MoveCamCenter ();
         
     }
 }
 
 function SetMainCamState ()
 {
     switch ( cameraState )
     {
         case MainCamState.LeftScreen : 
             
             hudOn             = false;
             mudHudOn         = false;
             moveCamLeft     = true;
             moveCamRight    = false;
             moveCamCenter    = false;
             
             
             //changeCam         = false;
             break;
     }
     switch ( cameraState )
     {
         case MainCamState.CenterScreen : 
             
             hudOn             = false;
             mudHudOn         = false;
             moveCamLeft     = false;
             moveCamRight    = false;
             moveCamCenter    = true;
             
             
             //changeCam         = false;
             break;
     }
     switch ( cameraState )
     {
         case MainCamState.RightScreen : 
             
             hudOn             = false;
             mudHudOn         = false;
             moveCamLeft     = false;
             moveCamRight    = true;
             moveCamCenter    = false;
             
             
             //changeCam         = false;
             break;
     }                
 }
 
 function MoveCamLeft ()
 {
     targetPosition = Vector3 (-11.5, 0, -5);
                  
        while (transform.position != targetPosition)
        {
               transform.position = Vector3.Lerp (transform.position, targetPosition, Time.deltaTime * camSpeed);
               yield;
               if (transform.position - targetPosition == 0)
               {
                   print ("breaking left");
                   moveCamLeft = false;
                   break;
               }
       }
 }
 
 function MoveCamCenter ()
 {
     targetPosition = Vector3 (0, 0, -5);
     
        while (transform.position != targetPosition)
        {
               transform.position = Vector3.Lerp (transform.position, targetPosition, Time.deltaTime * camSpeed);
               yield;
               if (transform.position - targetPosition == 0)
               {
                   print ("breaking Center");
                   moveCamCenter = false;
                   break;
               }
       }
 }
 
 function MoveCamRight ()
 {
     targetPosition = Vector3 (11.5, 0, -5);
     
     while (transform.position != targetPosition)
        {
               transform.position = Vector3.Lerp (transform.position, targetPosition, Time.deltaTime * camSpeed);
               yield;
               if (transform.position.x - targetPosition.x == 0)
               {
                   print ("breaking right");
                   moveCamRight = false;
                   break;
               }
       }
 }

As you can see I've been trying to break the lerp, but am failing miserably to do so. My theory is that it's snapping every other time, because the previous lerp hasn't finished it's thing yet. I think if I wait long enough between camera moves, I'll reduce the chance of the camera snapping to it's end position the next time it's asked to move.

So I think the way to solve this would be to successfully break the lerp?

  • note: I'm using lerp because I like the 'ease in' and 'ease out' effect it has.

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 Gruffy · Mar 20, 2014 at 10:03 PM 1
Share

The reason your Lerp isn`t working is because your are only calling it once in each of your methods. you should either place lerp function in Update function or continually call your method in update until it is finished. Alternativley, and probably for the best.. you should place you Lerp function into a co-routine. I have posted a link to UnityGems (Gotchas) this site will help you resolve you problem easily.. look for co routines (both js/us & C#) Take care dude, and let me know if oyur problem persists, we will go through it step by step

2 Replies

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

Answer by robertbu · Mar 20, 2014 at 10:24 PM

My theory is that it's snapping every other time, because the previous lerp hasn't finished it's thing yet.

Your analysis is likely correct. Your using Lerp() this way is common in Unity, but it is a non-traditional use of a Lerp(). The final parameter you are passing (Time.deltaTime * camSpeed) evaluates to some small value. That means that each time Lerp() is called, you move some small fraction between the current position and the destination. The fraction remains approximately the same, but the distance shrinks. Thant means that the amount moved each frame shrinks.

The 'problem' with this kind of logic is that it can take a really long time to reach the destination. It kinda like the old adage, "how many days will it take me to each my goal if I cover half the distance to the goal each day?" Answer: never. If Unity's vector comparison was exact (it actually compares to see if the magnitude of the difference in positions is below some thereshold), and if we had infinite precision floating point calculations, your 'transform.position != targetPosition' would never go to false. One fix is to use a threshold rather than Unity's comparison:

 while (Vector3.Distance(transform.position, targetPosition) > 0.05) {

This will dramatically reduce the time for the code to complete.

 function MoveCam ()
 {
     targetPosition = Vector3 (11.5, 0, -5);
     
     while (Vector3.Distance(transform.position, targetPosition) > 0.05)
     {
         transform.position = Vector3.Lerp (transform.position, targetPosition, Time.deltaTime * camSpeed);
         yield;
         if (Mathf.Abs(transform.position.x - targetPosition.x) < someThreshold)
         {
             print ("breaking right");
             moveCamRight = false;
             break;
         }
     }
 }

Note the one other change I made:

     if (Mathf.Abs(transform.position.x - targetPosition.x) < someThreshold)

You don't want to directly compare two floating point numbers (which was essentially what you were doing with the subtraction and comparison to zero). I doubt this line was ever firing. You'll have to figure out some appropriate value for 'someThreshold'.

Comment
Add comment · Show 2 · 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 Rick74 · Mar 21, 2014 at 01:34 AM 0
Share

All 3 of you we're very helpful. And you all have helped explain what I was doing wrong, thanks!

I'm goIng to go with robs suggestion as it should keep the ease in and out effect my using lerp() wrong has. Lol

avatar image suribe · Mar 21, 2014 at 07:45 AM 0
Share

If you want to have the ease in/out, then I suggest that ins$$anonymous$$d of using Lerp, you create an AnimationCurve with EaseInOut, and evaluate it's value using a variable between 0 and 1. I see a lot of people using Lerp this way, and while it is nice, it obfuscates its real meaning and sometimes causes confusion as why it is not working, as in your case.

avatar image
1

Answer by suribe · Mar 20, 2014 at 10:15 PM

Lerp means Linear Interpolator, which means that it interpolates linearly between two values, using a third one to determine the exact interpolation point. So if you provide values A and B, and ask for it to interpolate at 0, it will provide A. At 1 it will provide B, at 0.5 the exact middle value, etc. But instead of providing a value between 0 and 1, you are giving it small values (Time.deltaTime * camSpeed is probably always something below 0) and interpolating between the result of the previous interpolation and the value B. This will provide a smooth interpolation which is not linear, and will (theoretically) never finish.

So lets suppose A = 0, B = 100, t = Time.deltaTime * camSpeed = 0.1

A = Lerp (A, B, t) = Lerp (0, 100, 0.1) = 10 A = Lerp (A, B, t) = Lerp (10, 100, 0.1) = 19 ... After a while, this will look like:

 A        B        t
 0        100        0,1
 10        100        0,1
 19        100        0,1
 27,1    100        0,1
 34,39    100    0,1
 40,95    100    0,1
 46,85    100    0,1
 52,17    100    0,1
 56,95    100    0,1
 61,25    100    0,1

You see now why it never reaches the value you want? What you have to do is set a floating point variable such that it will go from 0 to 1, and interpolate from the initial camera position to the target one, using that value.

Something like:

 t = 0;
 targetPosition = Vector3 (0, 0, -5);
 initialPosition = transform.position;

 transform.position = Vector3.Lerp(initialPosition, targetPosition, t);
 ...
 t += Time.deltaTime;
 if (t >= 1) {
    t = 1;
    animating = false; // some way to know it finished...
 }

Second thing: do this in the Update() method. Just set up a variable like this animating = false, and set it to yes at the start.

 void Update()
 {
     if (animating) {
         t += Time.deltaTime * camSpeed;
         if (t >= 1) {
             animating = false;
         }
         transform.position = Vector3.Lerp(initialPosition, targetPosition, t);
     }
 }

Comment
Add comment · 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

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

22 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

Related Questions

Make Lerp or other more fluid or continuous 3 Answers

How to lerp an object's scale? 2 Answers

Vector3.Lerp move weapon up to players face 2 Answers

Computation of Vector3.Lerp, does it check for change? 3 Answers

Using lerp to scale 1 Answer


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