iTween even velocity

I’m trying to find a way to move an object evenly along an iTween path. Linear easetype doesn’t work since the length of the path between each node will effect the object’s speed (this is the same using time or speed). It is the same with PutOnPath and PointOnPath and their use of percent.

For example here is my path (even if it’s strait it does this):
A------------------------------B–C–D

This is an extreme example to demonstrate the problem, but in this case the object would go really fast from point A to B and then slow down from B to D.

I don’t want the speed to be altered so a character’s walking animation will remain believable. Is there a way to make this happen with iTween? I’m thinking I would at least have to be able to locate the closest point on the path, have the character look at a point slightly ahead of that, and then move forward at it’s own velocity. It’s that first step I don’t know how to do. But I’m open to any solution for this. Any ideas?

Well, I figured it out!

You need to get the object’s current percentage position on the path (point on path). look ahead a little bit on that path, adding .01(1%) should be enough looking ahead. Get the distance between the obj’s position and the point ahead. Get the full length of that path, and take 1% of that path’s distance. Dividing the real distance by the distance you got from looking ahead will get you the amount the path is distorted at that point.

From there, just multiply the percentage of how much you should move that frame by the distortion, and that should give you the change in distorted percentage. Add that to your current position and to feed into PointOnPath or PutOnPath.

Unfortunately I don’t think there’s a way to do with with MoveTo or some of the others.

PathOnePercent = GetDistance(GetLocation(PointOnPath(ObjectPosition)), GetLocation(PointOnPath(ObjectPosition + .01)));

//I’m keeping it simple and only doing moving forward, you can do the logic for moving backwards. Basically get the length between the object on the path and the 1% we look ahead on the path.

RealOnePercent = PathLength(NameOfPath) * .01;

//all the function names I’m using I’m making up, some might be similar to what you can use.

Distortion = RealOnePercent / PathOnePercent;

RealPercentToMove = (Velocity * DeltaTime) / PathLength(NameOfPath);

//Get the real percentage you should be moving this frame (this is not the final number)

NewPercentPosition = (RealPercentToMove * Distortion) + ObjectPosition;

//Distort how much the object moves

PutOnPath(Object, PathName, NewPercentPosition);

//Moves the object to it’s new location

Hope this works out for you… I can’t really devote too much time to this right now.

I had the idea to pre-calculate the distortion of each segment while configuring the path. It seems to work ok.

First I created a class to hold the distortion of each segment

class SplineSegment
{
    public float StartPercentage;
    public float EndPercentage;
    public float Length;
    public float Distortion;
}

Then I calculated all of the values and placed them in a queue

var pathLength = iTween.PathLength(array);
var normalisedSegmentLength = pathLength / (array.Length - 1);

pathSegments = new Queue<SplineSegment>();

for (int i = 0; i < (array.Length-1); i++)
{
    var float_i = (float)i;
    var segmentLength = iTween.PathLength(new Vector3[] { array*, array[i + 1] });*

pathSegments.Enqueue(new SplineSegment()
{
Length = segmentLength,
StartPercentage = (float_i / (array.Length - 1)),
EndPercentage = ((float_i + 1) / (array.Length - 1)),
Distortion = normalisedSegmentLength / segmentLength
});
}
Finally, I update the position in the fixed update
void FixedUpdate()
{
if (progress > pathSegments.Peek().EndPercentage) pathSegments.Dequeue();
progress += Time.deltaTime * speed * pathSegments.Peek().Distortion;
iTween.PutOnPath(gameObject, path, progress);
}
A bit of extra work, appears functional

so, maybe I’m making this easier then it’s supposed to be but I’ve worked around this problem with iTween by using MoveTo (Next Point in Path), the distance to the next point used to alter the speed and the onComplete parameter to start the tween again for the point after the next point… easier to code then to say…

var path : Vector3[];
var nextPoint : int = 0;
var speed : float = 10.0;

function Start () {
	Tween();
}

function Tween () {
	var toPoint :  Vector3 = path[nextPoint];
	var distance : float = Vector3.Distance(toPoint, transform.position);
	iTween.MoveTo(gameObject,{"position":toPoint,"time":distance/speed,"easetype":"linear","oncomplete":"Complete"});
}

function Complete () {
	nextPoint++;
	if (nextPoint < path.Length) Tween();
}

Ah, I figured I couldn’t have been the only one having the problem, but the lack of responses made me think otherwise. Still wrote up a quick solution in case, sorry for the lack of detail and code. I actually put the solution together in uScript, so the code it generated for it probably isn’t best for learning how to do this. But maybe I can help you and we can provide the community with a good sample.

What part of my description is tripping you up? It’s okay to say the beginning, I just want to know where to start working from. There’s also the possibility I left something out since I wrote it up quick.

Sorry for the delay here, I’m pretty busy.

You’re right, you should know the percentage of where your object is on the path. From that point you need to look ahead in the direction you are moving. So you should add or subtract (depending on direction) .01 to that number. We get the position of out object, and then the position of this look ahead point, and we measure the distance between these two points. We do this by putting the coordinates for both points into PathLength.

Please note, at this point you’re not measuring along the line but creating a new line. Because of this slight errors can occur. I’ve had good success with what I’m doing, but if for some reason you need super accurate results, you might want to make sure this is the method for you before you use it. It’s a very small issue, and I don’t think many would need more accuracy, but here is a description of why it can cause errors. Imagine your 1% length of the path is on a section shaped like a ‘U’. You would be drawing a line across the top of the U instead of around it. Therefore for this one frame the calculation would be slightly off. I don’t know what you use Unity for (or what others using might be using it for) but for games I’d say this is probably good enough. If you’re using unity and iTween for some scientific research or something, you’ll have to decide if this is accurate enough for you. TL/DR: fine for games, maybe not for science.

Now we have the distance between these points, however, iTween distorts this 1%, so this distance isn’t really 1% of the path like it thinks. Thankfully, by using PathLength() we can get the distance of the whole path. It does all the magical math to figure out the distance of the path even if there are curves in it. So once we have the real length of the path, we need to compare 1% of the real length to the 1% of the iTween length.

So we take the real 1% distance and divide it by the iTween 1% distance. This will give us the amount that the iTween 1% distance is distorted.

You should convert your velocity into percentage the object moves on the path each frame. I’ll assume you don’t need this described. Take this movement percentage and multiply it by the distortion. This gives you the percentage amount you need to move by to compensate for the distortion. Add (or subtract, depending on direction) it to your object’s position percentage on the path.

Maths is pretty scary stuff, I agree. Best to avoid, but as game devs we can’t. :wink:

I’d love to get you some working code, but my algorithm is built using uScript, so the generated code from that isn’t going to be helpful. (You might consider uScript if you’d rather try scripting in a visual way, rather than straight up text. I think it’s great.)

Anyway, how about a compromise… I’ll take a look at my script again, and pseudo-code it out for you… I’m just a little too busy to rewrite it in code and test it out and such.

You can code it up and post it here and be the hero. You’ll get all the XP for slaying the math! :wink:

I don’t know if you still need this, but I developed a simple solution that works just fine for my purposes.
You have to create your path with the iTweenPathEditor and then add the C# script iTweenConstantSpeed.
Then you have to set two variables:
Amount → This variable takes care to go through all your path. The bigger, smaller will be the “pieces” of the path.
Distance → This variable takes care of the distance between points.

You see: one method to keep an equal velocity during a curve is to set all the waypoints with the same distance between them. And that’s what my script does. It divides all the path into several waypoints with the same distance between them.

I hope you enjoy it and it fits your purposes.

PS: I uploaded it to MediaFire because I couldn’t upload it here… =D

Posted this last week… so far nobody has looked into it, despite the need for this.
The post says it all, but this will let you sample a path with a float value(0-1) using realworld distance, regardless of point spacing.

link text