Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. Dismiss Notice

Follow object at a distance by adjusting speed and/or acceleration?

Discussion in 'Scripting' started by batvink, Jul 29, 2021.

  1. batvink

    batvink

    Joined:
    Sep 26, 2019
    Posts:
    53
    Let me explain with a simple example...

    • Object 1 is moving at 50 km/h. It may slow down, or speed up.
    • Object 2 must follow Object 1 at around 20 metres distance. It may need to catch up at times, or slow down to drop back. It may have been obstructed by another object and have to catch up significantly.
    • I am using Navmesh AI, so I can only make adjustments to maximum speed and acceleration to achieve this.

    I know I can increase maximum speed to catch up, and decrease it to drop back. But is there a smart way to adjust the speed back to that of Object A as Object B approaches its desired distance behind Object A? For example, to quickly catch up but adjust back to cruising speed over 3 seconds, and be at the correct distance.

    Thanks in advance for any help here!
     
  2. Kurt-Dekker

    Kurt-Dekker

    Joined:
    Mar 16, 2013
    Posts:
    36,749
    One way is to compute the desired point relative to Object 1 where you want Object 2 to try and be.

    Then simply feed that position periodically into Object2's destination.

    You can then periodically adjust Object 2's speed depending on how far away it is from where it should be.
     
  3. batvink

    batvink

    Joined:
    Sep 26, 2019
    Posts:
    53
    @Kurt-Dekker thanks for the suggestion. The additional challenge here is that the target for Object 2 is a waypoint further in the distance, so I cannot use the offset from Object 1 as my target.

    The full scenario is this:
    • I have a number of racers which must maintain an order (it is a simulation, not a real race).
    • While moving from waypoint to waypoint they are following an invisible bar which acts as the pacer.
    • The leader is 5 metres behind the bar, second place is 10 metres behind, and so on.
    • The bar is not impeded by obstacles, it simply maintains a path towards the next waypoint to set the pace.
    • The racers may have to adjust their path around obstacles and each other, hence the use of the Navmesh.

    Maybe I am solving the problem in the wrong way, I am open to any suggestions!
     
  4. RadRedPanda

    RadRedPanda

    Joined:
    May 9, 2018
    Posts:
    1,593
    I think I understand what you mean from that, took me a few reads. You want the car's "average velocity" to be the same.

    I think you'd be able to do something with SmoothDamping the velocity, I'll try to get more in depth once I get on my computer
     
  5. RadRedPanda

    RadRedPanda

    Joined:
    May 9, 2018
    Posts:
    1,593
    So I came back to it, but there's not really much to get into about it, you would just SmoothDamp the relative velocity of the racer to your target point. You would need some kind of "weight" system, since the car won't always want to speed up (in the case of obstacles).
     
  6. batvink

    batvink

    Joined:
    Sep 26, 2019
    Posts:
    53
    Thanks again, I now have a solution. @RadRedPanda I like the idea of damping the velocity, but I can't do this directly because the navmesh system controls this aspect.

    What I ended up doing was damping the maximum speed, so that the velocity would follow. Acceleration can also be set, but I left this as a constant. I set a distance at which the speed should be 10% faster (or slower), and set the ramping up/down of the speed around this point.
     
  7. exiguous

    exiguous

    Joined:
    Nov 21, 2010
    Posts:
    1,749
    Maybe this is overkill but wouldn't this be a perfect usecase for a PID controller?
     
  8. batvink

    batvink

    Joined:
    Sep 26, 2019
    Posts:
    53
    @exiguous I think that is what I have inadvertently done, but on a far more simplified level. The larger the error (further from desired point), the greater the corrective action.

    rankSpacing is the arbitrary distance that represents 20% speed increase/decrease

    float speedChange = ((raceDistanceCurrent - raceDistance) / raceDistance) * (raceManager.racebar.RankSpacing * 0.2f);
    nma.speed = raceManager.racebar.currentSpeed + speedChange;
     
    exiguous likes this.