x


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?

more ▼

asked Dec 13 '11 at 06:58 AM

grzdvd gravatar image

grzdvd
16 3 4 4

Yes, have the same problem...That makes the speed param a bit useless and the time param look foolish, because you expect the speed to be constant.

Jan 02 '12 at 10:18 PM WhiteKnight

OP- could you please rearrange your many posts here to consolidate them in a single, chronologically-ordered place? It's kind of confusing as it is here, since answers aren't sorted by the order they are first posted in, and it makes this difficult to read. Remember that you can always edit any of your old posts.

Jan 11 '12 at 06:33 AM syclamoth

Hey syclamoth,

They are in order. I think grzdvd has replied via 'answer' rather than comment that's all.

Cheers

Jan 11 '12 at 12:35 PM markhula
(comments are locked)
10|3000 characters needed characters left

8 answers: sort voted first

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[i], 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

more ▼

answered May 16 '12 at 08:39 AM

Mr_Snuffle gravatar image

Mr_Snuffle
15 1 1 1

Very nice!

Jan 24 at 09:17 PM mcroswell
(comments are locked)
10|3000 characters needed characters left

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.

more ▼

answered Dec 14 '11 at 08:29 AM

grzdvd gravatar image

grzdvd
16 3 4 4

Hey, I think this is what I need; have you got a snippet of code for this as I'ma bit confused by your description.

Cheers

Jan 02 '12 at 02:58 PM markhula

Thanks! :-)

Firstly, you say get percentage on path, but surely you don't need that as you must already know the percentage (me mis-understanding more like). Distance between current point and next node; no problem Get full length of path; how?. You don't mean number of nodes do you? - or even combined distance between nodes - you mean actual length of wobbly path...??? - so how do you get the 'real distance'. Some rough c# would be really helpful as then I can see exactly what you are trying to do.

Your help is much appreciated!

Jan 04 '12 at 09:10 AM markhula

I tried the following but still don't get uniform speed. Am I missing something?

function PutOnPathTime(time : float) { //iTween.Stop(gameObject); LastPerc = CurrPerc; CurrPerc = Mathf.Clamp((time-StartTime)/LifeTime,0,1); var percent : float = CurrPerc; DeltaPerc = CurrPerc - LastPerc; var currPos : Vector3 = iTween.PointOnPath(iTweenPath.GetPath(PathName), percent); var nextPos : Vector3 = iTween.PointOnPath(iTweenPath.GetPath(PathName), percent + 0.001); Debug.Log(iTween.PathLength(iTweenPath.GetPath(PathName))); var dist : float = (currPos-nextPos).magnitude; scale = (iTween.PathLength(iTweenPath.GetPath(PathName)) * 0.001)/dist;

iTween.PutOnPath(gameObject, iTweenPath.GetPath(PathName), LastPerc + (CurrPerc-LastPerc)*scale);

}

Jan 08 at 03:20 PM richard3d
(comments are locked)
10|3000 characters needed characters left

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.

more ▼

answered Jan 04 '12 at 01:14 AM

grzdvd gravatar image

grzdvd
16 3 4 4

(comments are locked)
10|3000 characters needed characters left

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.

more ▼

answered Jan 06 '12 at 08:33 AM

grzdvd gravatar image

grzdvd
16 3 4 4

Crumbs! Firstly I really appreciate the time you have taken for your detailed response. I am unsurprisingly requiring this method for games so the accuracy should be fine. I think I get what you are saying so will attempt something. Though again if you could post any code example at all (no matter what language) would be really really really helpful. If I get this working in c# I will post my result to help others. Again I really appreciate the time you have taken, and forgive my noobness to maths and scary stuff :-))

Cheers

Jan 06 '12 at 09:25 AM markhula
(comments are locked)
10|3000 characters needed characters left

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();
}
more ▼

answered Jun 28 '12 at 11:13 PM

mtalbott gravatar image

mtalbott
1

(comments are locked)
10|3000 characters needed characters left
Your answer
toggle preview:

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

By Email:

Once you sign in you will be able to subscribe for any updates here

By RSS:

Answers

Answers and Comments

Topics:

x426
x318
x238

asked: Dec 13 '11 at 06:58 AM

Seen: 3380 times

Last Updated: Jan 24 at 09:17 PM