Waypoints and constant/variable speed problems?

Hi all,

Basically I have my waypoints all setup and working, however my gameobject slows down as it reaches a waypoint, this means that my gameobject does not travel at a constant speed around all my waypoints.

I have read lots of forum topics on this subject, and I have tried a fair few waypoint implementations to get this to work, I did manage to get the gameobject to travel at a constant speed using Sam at FPS waypoint solution.

http://forum.unity3d.com/viewtopic.php?t=31412

However, I need my waypoint solution to work with a player controlled variable speed gameobject.

And Sam’s example calculates the waypoint bezier curve based on time to complete the waypoints layout, prior to moving the gameobject.

I have had this working using Darkbasic Professional, see video below:
http://www.alabsoft.com/vSlot/vSlot%20-%20Work%20in%20progress/vSlot%20-%20Work%20in%20progress.html

However, I want to code this project in Unity now, as Unity is so much more powerful, and with cross-browser support etc.

In Darkbasic Professinal there is a command called CurveAngle.

Function CurveAngle(fA As Single, fDa As Single, fSp As Single) As Single

This command will return an auto-interpolated angle based on a given speed. This command will gradually move a number from its current value to a destination value at a certain speed.

I have found a similar command in the MathFX class from the Unify Wiki called Clerp.

But I cannot get it to work? here is my pseudo code, I know the transform.eulerAngles.y does not work? all I want to do is get the current y angle of the gameobject that my script is attached too.

if(Vector3.Distance(transform.position,waypoints[currentWaypoint])<=damping) {
  //Debug.Log("Collided with waypoint");
  currentWaypoint++;
  currentHeading = waypoints[currentWaypoint];
}

// Get players current/old y angle
oldangle = transform.eulerAngles.y;
	
// Point player in direction of current waypoint
//transform.LookAt(currentHeading);	
	
// Get players new y angle
newangle = transform.eulerAngles.y;
	
// Now interpolate (create a smooth curve) the angle based on the speed and new and old angles
//finalangle = Mathfx.Clerp(oldangle, newangle, speed);

// Rotate player	
transform.eulerAngles = Vector3(0, finalangle, 0);

// Move player forwards	
transform.Translate(0, 0, speed * Time.deltaTime);

Here are some screenshots of my app in Unity.


This shows how the layout is constructed at runtime using Instantiate command, and the placement of the waypoints for each lane.


This shows the Hierarchy view with the cloned track sections.


This final image shows the layout with the waypoints hidden.

I have big plans for this project, multi-player, huge layouts, fastest lap competitions etc, etc, so any help with getting the basics working will be greatly appreciated! :slight_smile:

[/img]

1 Like

I’ve attached a Bezier/spline library script. It is still not finished, but I think it might help you out here. There’s a class defined in it called CRSpline (ie, Catmull-Rom spline). This basically takes any number of waypoints and interpolates a smooth curve between them. This is mostly pretty straightforward but for one thing. Catmull-Rom splines actually have an “invisible” extra control point at the start and another at the end of the curve. This is to control the speed and direction of the curve at the start and the end of the interpolation. To create a cyclic track, you will need to set the first point of the spline to be one waypoint behind the start point and the last point in of the spline to be one beyond the finish, if you get what I mean.

This is by no means foolproof, but it should help reduce discontinuities in speed going from one track section to the next. The main other problem with speed is when waypoints are not evenly spaced. There is a GizmoDraw function in the CRSpline class that draws the curve along with a velocity vector. As you increase its parameter from 0 to 1, the velocity vector will move along the curve, showing you the velocity of the curve at that point (ie, the length of the line). This should help you diagnose where speed changes are happening and suggest where the waypoints need to be closer together or farther apart.

As I said, not entirely foolproof - please ask again if you have any trouble with this. I’ll “launch” this library properly soon, when the missing functionality is in place.

213942–7849–$curve_443.cs (3.37 KB)

1 Like

Thanks for info, I will download and take a look.

andeeee, did you improve your code?
Can I use it in my Antares Project ?

It works OK as it is. I think my intention at the time was to add a natural spline too, but the existing code has been used quite a few times and seems to be OK.

I have splines too in my Antares project, but other type.
Can I use your code (with your credits) in my public open source project ?

It’s public domain and I wrote it while working for Unity, so no credit required :wink:

Ok. Thank you.

Awesome, thank you Andee ! :smile:

I have 4 waypoints represented by the green arrows where I want the target to loop through these waypoints. The code that I used works fine i suppose but the problem is that when the target reaches the waypoints, it sticks to them as if the waypoint is holding the target and at a certain point the target is released and goes to the next waypoint.

anybody knows what’s the problem? Thanks in advance

I also provided a link where I recorded my problem.

CODE:

var waypoint : Transform[ ];
var speed : float = 5000;
private var currentWaypoint: int;
var loop : boolean = true;

function Awake(){
waypoint[0] = transform;
}

function Update () {
if(currentWaypoint < waypoint.length){
var target : Vector3 = waypoint[currentWaypoint].position;
var moveDirection : Vector3 = target - transform.position;

var velocity = rigidbody.velocity;
if(moveDirection.magnitude < 1){
currentWaypoint++;
}
else{
velocity = moveDirection.normalized * speed;
}
}
else{
if(loop){
currentWaypoint=0;
}
else{
velocity = Vector3.zero;
}
}

rigidbody.velocity = velocity;

}

Hi Andy (or anyone)

I’m using this script to draw curves and it works really well, thanks. I just want to know how can I get the yValue on the curve based on the xPosition of one of my gameobjects? Tjis object is a time line and it loops from -10 to 10 on the x axis. I just need to find the yValue of the curve at any given point.

Please help me with this urgent problem, thanks

anyone that can shed some light?

I remember this stuff back when I was doing a zuma clone. The solution I used was incredibly simple:

  1. after setting up splines in my editor, I would generate a linear array of points.

  2. to create the array you traverse the spline as you normally do, however you only add a point to the array when DISTANCE between the current position and the last sample point is greater than n.

  3. then you have an array of points each perfectly spaced apart.

  4. then you use Mathf.Lerp() to go between, and use only the time parameter to travel.

x = lerp (prevpos, newpos, position)

  • when position >1 you add one to prevpos and newpos, and subtract 1 from position.

Thats all there is to it for constant speed, thats how I did it. It also solves issues of missing waypoints and so on.

Thanks Hippo

I’m just a bit unclear about point 2 that you mentioned? Do you mean that I shoudl modify the way that I’m currently adding the points to my array so that the x values are evenly spaced? If so, I’m not sure how I’m going to achieve that…

I just tried to take sample points of the curve, but that does not work., Man, if I could test some collider with the line renderer and get the x value at a point, that might even work - so frustrating…

Hi,

If any one involved with mouse/ touch dragged-path following after releasing the mouse button or touch control (NOT following the mouse point) in a game like Air Traffic Controller/ Hurbour Master, plase assist me to control the speed of the object movement.

In my current script the mouse dragged path is followed by player object but the moving speed depends on the mouse-dragged/ touch dragged-speed. I just need to move the object in a constant speed.

I’ve attached the current script and please simply download the script and attached it to a game object and set smooth value to a value like 1000. It’s works…!. But the object movement speed is relative to the mouse dragged speed/ touch-dragged speed.

Please assist me to move the object in a constant speed. It should not depend on the dragging speed.

Thank you in advance… :slight_smile:
Cheers…

Regards,
Jeewanthasas

690397–24854–$TestOnMousedrag_DragonOnTestScene.cs (3.66 KB)

I wish I could help, but I have not even solved my problem - i’ve been ignoring it for the last month doing other stuff;)

Hi,

Thanks chubbspet, I could solve the issue and if anyone interested in the solution I would love to assist them.

Regards,

I will be very interrested!

Hello,

thx for the great spline class, it works great!!

As you mentioned andeeee, the speed along the spline depends on the control points distance. In my scene I using this spline class to generate a camera path. The problem here is that I want to design a constant movement speed along this spline. How do I do this? I tried taking the velocity’s magnitude and calculating it with my parameter t:

void Update()
{
float magnitude = crSpline.Velocity((speed * Time.time) % 1.0f).magnitude;
renderingCamera.transform.position = crSpline.Interp((speed * Time.time / magnitude) % 1.0f);
}

but this does not work, any suggestions guys??