Search Unity

Curve movement between two waypoints

Discussion in 'Scripting' started by idurvesh, Sep 1, 2015.

  1. idurvesh

    idurvesh

    Joined:
    Jun 9, 2014
    Posts:
    495
    We are developing racing game.I have set up waypoints to let player go ahead.

    I am stuck at how to add curvy movements on turn ? As you can see on following img I have to add lot of waypoints continuously side by side to give illusion of curve movement yet it is not working properly as player do not move in curve instead it moves robotically.



    Camera is child of player so with that setup camera keep moving left-right direction every frame which looks very buggy.

    So my question is how can I create curve between two waypoints and let player move smoothly in between them???
     
  2. gorbit99

    gorbit99

    Joined:
    Jul 14, 2015
    Posts:
    1,350
    Instead of rotating towards a poibt, you could just add some force, the movement will be curved, and it gives the cpu a bit of a fairness
     
  3. idurvesh

    idurvesh

    Joined:
    Jun 9, 2014
    Posts:
    495
    @gorbit99 actually I am using MoveTowards function for moving player
     
  4. MentalMoustache

    MentalMoustache

    Joined:
    Nov 14, 2011
    Posts:
    18
    I don't know if this is any help for you in this case, but it certainly has helped me a lot with smooth curves between two points.

    Here is a little helper function to get points from bezier curve. All it needs is two positions (lets say transforms) and for each position it neets a direction (lets say transform.forward and transform.back as tangents).

    Code (csharp):
    1. // parameter t ranges from 0f to 1f
    2. // this code might not compile!
    3. Vector3 GetBezierPosition(float t)
    4. {
    5.    Vector3 p0 = transformBegin.position;
    6.    Vector3 p1 = p0+transformBegin.forward;
    7.    Vector3 p3 = transformEnd.position;
    8.    Vector3 p2 = p3-transformEnd.back;
    9.  
    10. // here is where the magic happens!
    11.    return Mathf.Pow(1f-t,3f)*p0+3f*Mathf.Pow(1f-t,2f)*t*p1+3f*(1f-t)*Mathf.Pow(t,2f)*p2+Mathf.Pow(t,3f)*p3;
    12. }
    Here is the source I used to make this: https://en.wikipedia.org/wiki/Bézier_curve Those p0...p3 points are also visualized behind that link.

    Here is a screenshot of the bezier curve in action.
    BezierExample.png
    Top left is used with 1/16th increments in t value. Middle one is 1/8th and bottom is 1/4th. And there are only 2 points (with tangents) that creates each curve.
     
  5. DaVeF101

    DaVeF101

    Joined:
    Sep 7, 2014
    Posts:
    134
    I came across the problem whilst coding the AI for a car racing game (Not sure if you're using WheelColliders).

    I basically set a minimum distance to the way point value to each AI car before they started to turn to the next waypoint, so they didn't quite reach the waypoint and "curved" past it.

    Code (CSharp):
    1. using UnityEngine;
    2. using System.Collections;
    3.  
    4. public class AISteering : MonoBehaviour {
    5.  
    6.     public Transform[] pathPoints;
    7.     public float maxSteer = 15.0f;
    8.     public float distanceFromPoint;
    9.     public WheelCollider wheelFL;  
    10.     public WheelCollider wheelFR;
    11.  
    12.     private int currentPathPoint;
    13.    
    14.  
    15.     void Update () {
    16.         Steer();
    17.     }
    18.    
    19.     void Steer(){
    20.         Vector3 steerVector = transform.InverseTransformPoint(new Vector3(pathPoints[currentPathPoint].position.x,transform.position.y,pathPoints[currentPathPoint].position.z));
    21.         float newSteering = maxSteer * (steerVector.x / steerVector.magnitude);
    22.         wheelFL.steerAngle = newSteering;
    23.         wheelFR.steerAngle = newSteering;
    24.  
    25.         if (steerVector.magnitude <= distanceFromPoint){
    26.             currentPathPoint ++;
    27.             if (currentPathPoint >= pathPoints.Length)
    28.                 currentPathPoint = 0;
    29.         }
    30.     }
    31. }
     
    MohammadAlizadeh and idurvesh like this.
  6. MikeUpchat

    MikeUpchat

    Joined:
    Sep 24, 2010
    Posts:
    1,056
    Are you wanting to code the solution yourself as there are systems on the Asset Store that do this sort of thing.
     
  7. idurvesh

    idurvesh

    Joined:
    Jun 9, 2014
    Posts:
    495
    @MentalMoustache Thanks for overview, how you got those Green lines on editor? could you share code for it?

    @DaVeF101 Thanks for code, But I am not using WheelColliders, my players are on animals


    @MikeUpchat actually I want to code myself, are you referring to "Simple Waypoint system"?
     
  8. MikeUpchat

    MikeUpchat

    Joined:
    Sep 24, 2010
    Posts:
    1,056
    That's fine, actually it was more one of the spline systems such as MegaShapes or the vehicle AI systems.
     
  9. gorbit99

    gorbit99

    Joined:
    Jul 14, 2015
    Posts:
    1,350
    I thin he does the green lines with debug.drawline
     
  10. MentalMoustache

    MentalMoustache

    Joined:
    Nov 14, 2011
    Posts:
    18
    I use Debug.DrawLine(pointA, pointB, Color.green) to draw those lines as gorbit99 said.
     
  11. hsklunity

    hsklunity

    Joined:
    Jun 9, 2022
    Posts:
    13

    How did you solve the problem in the end? I am working on a similar project and the camera movement is also a problem.
     
  12. spiney199

    spiney199

    Joined:
    Feb 11, 2021
    Posts:
    7,861
    OP hasn't been online since 2021 so doubtful you'll get a reply.

    The answer is you're going to actually have to calculate a curve between two points rather than a straight line and move your object along that curve. There are tutorials on how to do so: https://catlikecoding.com/unity/tutorials/curves-and-splines/ (Old tutorial, but should still work in current day Unity as it did for me).

    Otherwise there are probably tools on the asset store, and I think Unity has an experimental package for curves as well.