- Home /
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?
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.
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.
Hey syclamoth,
They are in order. I think grzdvd has replied via 'answer' rather than comment that's all.
Cheers
Answer by grzdvd · Dec 14, 2011 at 08:29 AM
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.
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
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!
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 = $$anonymous$$athf.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);
}
Answer by grzdvd · Jan 11, 2012 at 06:21 AM
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.
Here's the c# so far:
float Velocity = 1f;
float PathOnePercent = Vector3.Distance(iTween.PointOnPath(trunc,percentage) , iTween.PointOnPath(trunc,percentage + 0.1f));
float RealOnePercent = iTween.PathLength(trunc) * 0.1f;
float Distortion = RealOnePercent/PathOnePercent;
float RealPercentTo$$anonymous$$ove = (Velocity * Time.deltaTime) / iTween.PathLength(trunc);
float NewPercentPosition = (RealPercentTo$$anonymous$$ove * Distortion)+ ????
I'm not sure what you want here; you say position but I don't see how. Almost there though :-)
Cheers
p.s. Double check my interpretation so far is correct :-)
Oh I'm sorry, I think that ObjectPosition is just the object's location on the path... so the perecentage variable you used in the first like is what you can use here.
It sounds like what I was describing, it's been a few weeks since I solved this, so I hope I'm remembering it right... I did look through my uScript while writing it up to make sure though.
Sound like you're almost there I think.
What's good about this as well, is you should be able to use iTween with it. Okay maybe that sounded funny. But I mean something you'll be able to use the easing types and such along the much more even results this method will give you. For example you could use ValueTo to control your velocity. Or I think it could even be used to directly manipulate percentage if used from 0 to 1. This should even out the distortions on the path. Once you get it working, adding this might not be too hard.
float Velocity = 1f;
float PathOnePercent = Vector3.Distance(iTween.PointOnPath(trunc,percentage) , iTween.PointOnPath(trunc,percentage + 0.1f));
float RealOnePercent = iTween.PathLength(trunc) * 0.1f;
float Distortion = RealOnePercent/PathOnePercent;
float RealPercentTo$$anonymous$$ove = (Velocity * Time.deltaTime) / iTween.PathLength(trunc);
float NewPercentPosition = (RealPercentTo$$anonymous$$ove * Distortion) + PathOnePercent;
iTween.PutOnPath(gameObject,trunc,NewPercentPosition);
Doesn't work :-( Afraid I can't see what is wrong with the maths :-(((( Need you one last time grzdvd :-)))
Cheers
Do you mean values?.
Well, with a percentage of 0: (i.e. the start I get):
PathOnePercent: 0.09
RealOnePercent: 1.607
Distortion: 17.19
RealPercentTo$$anonymous$$ove: 0.001245
NewPercentPosition: 0.114
Then with percentage at 0.5f (i.e. half way):
PathOnePercent: 0.024
RealOnePercent: 1.228
Distortion:49.79
RealPercentTo$$anonymous$$ove:0.0016
NewPercentPosition:0.105
That help? :-)
Cheers
p.s these were 2 different paths $$anonymous$$d!!
Answer by Mr_Snuffle · May 16, 2012 at 08:39 AM
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
Answer by mtalbott · Jun 28, 2012 at 11:13 PM
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();
}
Answer by Sannyasi · May 29, 2013 at 01:38 AM
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.