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 Griffo · Oct 13, 2016 at 11:32 AM · lerpspeedlerping

Slow down in the same time over different distances

Hi,

I'm trying to slow down a object over different distances in the same time, say 3 seconds.

My slow down code is.

 function lerpSpeed (speed: float, lerpSpeedTime: float)
 {
     incomingFlightSpeed = flightPathScript.flightSpeed;
 
     i = 0;
     while(i < 1)
     {
         i += Time.deltaTime/lerpSpeedTime;
         i = Mathf.Clamp(i, 0, 1);
 
         flightPathScript.flightSpeed = Mathf.Lerp(incomingFlightSpeed, speed, i);
 
         yield;
     }
 }

So I call it with.

 waypointScript.lerpSpeed(1,(totaFlighpointsDistance/flightSpeed));

In the picture below I've draw a bezier curve and at the last 8 flight points (the red and yellow spheres) I want to start the slow down from the yellow sphere to the last red sphere.

I get the distance in between each of the last 8 flight points and total them up to give me the total distance, I understand to get the time it will take to travel that distance is time = total distance/speed, but as I'm slowing the speed in my function above this will not work.

And because every bezier curve I generate is different, some stretched out, with total distances sometimes ranging from 30 to 8.

So I'm a bit stuck here, thought I'd get this one, but unless I'm missing something simple I can't get my head around it, so any help would be greatly appreciated, thanks.

alt text

screen-shot-00.jpg (172.6 kB)
Comment
Add comment · Show 11
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 b1gry4n · Oct 13, 2016 at 11:42 AM 0
Share
 function lerpSpeed(desiredSpeed : float, overTime : float)
     {
         var elapsedTime : float = 0;
         inco$$anonymous$$gFlightSpeed = flightPathScript.flightSpeed;
         while (elapsedTime < overTime )
         {
             flightPathScript.flightSpeed = $$anonymous$$athf.Lerp(inco$$anonymous$$gFlightSpeed, desiredSpeed, (elapsedTime / overTime));
             elapsedTime += Time.deltaTime;
             yield;
         }
     }
avatar image Griffo b1gry4n · Oct 13, 2016 at 01:18 PM 0
Share

@b1gry4n Thanks for the answer, results are showing on a long bezier curve the bot slows down before the end and on a short bezier curve the bot does not seem to slow down, comes to a sudden halt.

avatar image b1gry4n Griffo · Oct 13, 2016 at 01:47 PM 0
Share

Never$$anonymous$$d, I am wrong. One second let me try to wrap my head around this. I completely understand what you are trying to do, the above script simply slows the character down over X time.

Show more comments
avatar image Griffo · Oct 13, 2016 at 03:34 PM 0
Share

@b1gry4b thanks for all this information ..

First let me say that when the bot first flies along the path he slowly accelerates up from 0 up to a speed of 6 or 10 over a period of time (say 3 seconds) depending if the next waypoint, (the end of this bezier curve and the start of the next one) is either higher or lower than him, so if higher a speed of 6 (effect of climbing) and if lower a speed of 10 (effect of descending).

So where does that leave your answer? As he does not fly along at a constant speed.

And I also forgot to say that at a random time a coroutine is called where he will slow down to a speed of 1 slowly rotate to face the player and throw a grenade, then rotate and accelerate back up to speed.

So I think it's not that simple anymore :(

I still think the way I must go is finding the solution to the slow down say over 3 seconds over the last 8 flight positions, or more if needed, as all the rest of the flight works great, just the last bit, the slow down.

Really appreciate your help ..

EDIT .. Just seen you edit about the animation curve, I'll look into that ..

avatar image b1gry4n Griffo · Oct 13, 2016 at 04:02 PM 0
Share

$$anonymous$$ore on the animation curve idea. You could control the start up and slow down with a single curve. Sample the current position in the entire path and evaluate the animation curve. Your curve would end up looking like a bell curve representing the speed of the bot over the course of the entire bezier curve

if youre able to get the last 5 nodes in a path, you surely are able to get a % traveled in the path. animCurve.Evaluate(currentNode/maxnodes)

avatar image Griffo · Oct 13, 2016 at 04:49 PM 0
Share

@b1gry4n Animation curves never used them.

I'm a bit confused you say divide the remaining distance by the max distance and you will get a value between 0.0 and 1.0 but in you code snippet you have ..

 float speed = slowDownCurve.Evaluate(currentDistance/maxDistance) * initialSpeed

I've done the two ..

 var floatSpeed_0 : float = slowDownCurve.Evaluate(currentDistance/flighpointsOverallDistance) * 6;
 var floatSpeed_1 : float = slowDownCurve.Evaluate(flighpointsLeftDistance/flighpointsOverallDistance) * 6;

And below is the output ..

alt text

but I can't see how floatSpeed_0 or floatSpeed_1 would be used in a animation curve to decrease the speed!

screen-shot-2016-10-13-at-173943.png (115.1 kB)
avatar image Griffo · Oct 14, 2016 at 05:18 AM 0
Share

@b1gry4n

Thank you very much for taking the time to explain all this in detail, I really do appreciate it.

Now thanks to you I have a better understanding of the power of using animation curves, that could just be what I'm looking for.

Thats my job for today, to nail this flightpath control, I'll keep you updated ..

avatar image Griffo · Oct 14, 2016 at 08:00 AM 0
Share

@b1gry4n Hi,

O$$anonymous$$ I'm liking the animation curve but I see a problem, I'm going with one like in your LIN$$anonymous$$

The problem as you can see in this VIDEO is the acceleration and deceleration is not constant when the distance is changed, is there a way to keep the ends constant no mater the length of the flightpath?

Or would I have to move the second and third points of the cure at runtime depending on the length of the flightpath?

Thanks.

avatar image b1gry4n Griffo · Oct 14, 2016 at 09:19 PM 0
Share

Like I said earlier, If you want time to slow down/speed up, you will need to change speed. Distance is the constant here. You have a set distance at all times, so the speed of the bot needs to dynamically change based off the distance it is traveling if you want him to cover varying distances in the same amount of time. If you want him to reach the end of the path in the same amount of time regardless of the distance between them, a very far distance = higher speeds. A very short distance = lower speeds.

The reason the slowdown/speedup seems inconsistent is because the bot is traveling the same speed. It is actually very consistent, the bot appears to be slowing/speeding up much faster because it is traversing the path at a constant speed. make the distance short and slow the maxspeed, you will see it slows and speeds up.

Show more comments

1 Reply

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

Answer by b1gry4n · Oct 13, 2016 at 09:36 PM

The code snippet above will give the inverse value. Below I modify it to make reading the curve easier.

Say your total distance of the bezier is 20 units. as you traverse the curve, your position (or distance from the end) in the curve will start to get smaller. It will start at 20 and as you move closer to the end it will be 19, 18, 15, 10, 5, etc. The remaining distance is something you will need to continuously track as you traverse the curve.

For the sake of continuity and clearly reading the animation curve, lets do it like this:

 remainingDistance / totalDistance = a value between 0.0 and 1.0. 

 20/20 = 1
 15/20 = .75
 10/20 = .5

So now, if we say:

 1.0f - (remainingDistance / totalDistance) 

we will get the inverse of what we just did. this isnt necessary but it makes reading the animation curve a little easier from left to right. Evaluating the curve with this value will return a modified value based on that curve.

If you were to create a curve like this: http://i.imgur.com/D5EjEck.jpg

you could evaluate the curve with:

 animCurve.Evaluate(1.0f - (remainingDistance/totalDistance))

For purposes of explanation, lets say you were 3/4ths the way through your bezier curve. That means if the total distance was 20, your remaining distance would be 5.

 1.0f - (5/20) = 0.75f

Now look at the image i linked. At the bottom follow the value over to 0.75, follow it up until it reaches the curve. The returned value will be about 0.62f. Now we take the received value and multiply it by our max speed.

 animCurve.Evaluate(1.0f - (distanceRemaining/totalDistance)) * maxSpeed

If the max speed at that time is 100, that means at this point in the curve we are traveling at a top speed of 62. As you can see, as you evaluate along the curve, the fastest you would be moving throughout the entire distance is halfway at 0.5. You can adjust this curve to be how you want. Something like this is what you want I am guessing : http://i.imgur.com/2m6DuiH.jpg

This will automatically slow down and speed up depending on the point you are in the curve. The speed of the character would not matter as you could slow down/speed up and evaluate.

 float finalSpeed = animCurve.Evaluate(1.0f - (remainingDistance/totalDistance)) * currentSpeed;

One thing to keep in mind is that if you set the beginning of the curve at a time of 0.0 and a value of 0.0, the returned value will be 0.0. Youll need to set the beginning of the curve to atleast 0.01 or do a check. if(returnedValue == 0) returnedValue = 0.01f

I have created a little demo script. I am creating the curve in the script, but you would want to hand tweak the curve to your desire.

SETUP: create 2 spheres. Place the script on one of the spheres and drag the other sphere into the "target" slot of the script. Press play. Notice how it starts slow, speeds up, and slows towards the end.

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 b1gry4n · Oct 13, 2016 at 09:50 PM 0
Share
 using UnityEngine;
 using System.Collections;
 
 public class Traverse : $$anonymous$$onoBehaviour {
     public Transform target;
     public AnimationCurve curve;
 
     public float maxSpeed = 1;
     public float currentSpeed;
 
     public float totalDistance;
     public float remainingDistance;
 
     Vector3 originalStart;
 
     void Start()
     {
         target.position = new Vector3(transform.position.x, transform.position.y, transform.position.z + 20);
         originalStart = transform.position;
         totalDistance = Vector3.Distance(transform.position, target.position);
         curve = new AnimationCurve();
         curve.Add$$anonymous$$ey(new $$anonymous$$eyframe(0.0f, 0.01f));
         curve.Add$$anonymous$$ey(new $$anonymous$$eyframe(0.5f, 1f));
         curve.Add$$anonymous$$ey(new $$anonymous$$eyframe(1.0f, 0.0f));
     }
 
     void Update()
     {
         remainingDistance = Vector3.Distance(transform.position, target.position);
         if (remainingDistance <= 0.1f)
         {
             Reset();
             return;
         }
         currentSpeed = curve.Evaluate(1.0f - (remainingDistance / totalDistance)) * maxSpeed;
 
         transform.LookAt(target);
         transform.Translate(Vector3.forward * currentSpeed);        
     }
 
     void Reset()
     {
         transform.position = originalStart;
     }
 }

You can change the "maxspeed" value to whatever you want. This would simulate your bot changing speeds throughout its time on the bezier curve. No mater the maxspeed, it will start slow, speed up, and stop slow. Also, while in play mode, mess around with the animation curve itself and look at how it changes the objects speed as it traverses the "path"

If you wanted to get really fancy, you could add keys to a runtime generated animation curve (similar to what I have done in the example) for each node of your bezier curve. Say you have 20 nodes in your curve, you would add 20 keys. The key time would be the currentNode/totalNodes and the key value could be based on the distance between the nodes. If you did it this way, you could control the speed of the object at each node in the curve.

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

59 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

Related Questions

lerp in shader doesn't work as imagined? 1 Answer

Lerp - Time Remaining 1 Answer

Lerp is not moving 2D Prefab over time. 2 Answers

Lerp waypoint path easing 1 Answer

Quaternion.Lerp and Vector3.MoveTowards arent smoothing 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