What's the proper way to make an object follow a path using iTween at a constant speed? Is there a specific easetype I should use?
The key to consistent speed on paths with iTween really lies with evening out the space between your points. Sorry that's the limitation of things until I can figure out a way to interpolate evenly regardless of the point placement.
I had the same problem with iTween and I started to use the Antares Project. It has a functionality to create smooth curves that can be travelled at a constant speed with little code. As pixelplacement1 said, the key is spacing evenly the control points and Antares Project do it automatically, but I like more the interpolation method used by iTween... I wish iTween included that functionality, but meanwhile, I use Antares Project for smooth path creation and iTween for everything else.
Cool, thanks for the responses guys. I really enjoy iTween, but the lack of constant speed is an issue for me. It's good to hear that you're going to look at it eventually, pixel. Until then, I'll just play with the points a bit and see what I can do. Thanks again!
I know that time is the scarcest resource, you have done a great job so far I'm sure you'll make iTween even better when you have time. I was only providing a "temporal workaround" until you have time to include that functionality in iTween. By the way, if I get some money with my current project, I will donate some money to you and the Antares Project creator: both of you have helped me a lot and you deserve it.
Hi, you should be able to replace your interpolation mechanism for the curves with a hermite algorithm - this will give you a constant rate 0->1.0 for the length of a curve and thus give you the ability to do constant speed. I'll look at what modifications iTween needs for this - I suspect it should be able to be made an 'addon'. Cheers, Dave Lannan
I'm glad to hear this issue is being addressed. I love iTween already (just started with unity) but the speed thing was confusing me as dispite paying for examples I thought I was doing something wrong. I'd love to see the fix!
Been looking up how to do calculus. This is going to take me a while to learn. I figured I might post this here since some of you might get some info from it. Any real programmer will be able to learn and implement it faster than me. http://www.geometrictools.com/LibMathematics/CurvesSurfacesVolumes/CurvesSurfacesVolumes.html More importantly http://www.geometrictools.com/Documentation/MovingAlongCurveSpecifiedSpeed.pdf Also, upon further reading I have come accross what needs to be done for those with know how. Apparently you need to reparameterize the curve so that all the points are equal distance to each other. I am going to try and make a Bezier Curve script that gives you archlength, bezier curve, and allows you to go from one curve to another. Again, I have to learn calculus first, but meh, my studies have been going well for now.
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. View attachment $iTweenPathConstantSpeed.unitypackage
Hm, to which object should i attach the script? I attached it to the pathholder object, and got an object reference error. I attached it to the object that should move along the path, and got an object reference error too.
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(); }
Hi, I am currently working on solving this very problem, unfortunately Felipetnh's solution isn't quite right. To get rid of your errors, you need to rename the GetPath name to the name of your path that you created with iTweenPathEditor, like this... If your path in named "Path1" then you need to modify this line to... position = iTweenPath.GetPath("Path1"); This should now work if you attach the script to the same object you attached your path to, and will show the extra WayPoints that the script creates... The solution isn't quite right because it simply adds more points to the path by dividing the total length into more WayPoints, so a long straight will still result in faster movement along that straight. To see what I mean, create a smallish path on a 4x4 plane, with about 10 points, 1 longish straight and a few twisty turny bits, it'll move faster along the straight. The solution is a little more complex but fairly easy to do using Felipetnh's as a base, the path needs to be sub-divided further into perhaps 10,000 pieces, then a minimum distance for a WayPoint should be defined as say "d", step through the smaller 10,000 distances until the minimum required distance is met "d", then use this as a new WayPoint. This needs to be done as simply dividing the path into smaller distances for WayPoint would still make the traversing of the path non-constant, but somewhat less variable as it was with say 10 WayPoints. Stepping along in micro-steps until the desired distance for a waypoint is met is much more accurate and will result in a constant speed along the path.... So do I have the code? ...Nope not yet, just sussed out what I need to do and I'll work on this either over this weekend, or early next week when I get time and post up the results for you and anyone else that needs it... My solution "should" work, although I've not tried it yet it does make sense, so the code may change slightly, but it will result in a constant speed when I've finished with it... I need this too because my path's can be drawn by the user, then my code has to re-interpret those paths, draw the GFX, and make the waypoints at equal distance so the speed can be controlled. This seems the most logical way to me to do it, as it prepares a new array of points before the code is run alleviating processor workload . Doing the Maths in real time as some others have suggested, on the fly in the Update function, so to speak will result in unnecessary processing when the game is running, plus I need my game to work on iPhone etc... Will post back soon, maybe you've sussed your error already, but my update to this problem will come shortly...
Hi there, I'm still here, and yes I did solve that and yes if your interested I will post my solution. Sorry I missed your request until now, I'm on here regularly, thought I might get some kind of notification that the thread had been updated, I happened to come back here coincidentally searching for something else. So if your still around, and interested in my solution, I'll check back regularly, then post it up, after I've commented the code a little better and tidied it up a little for public consumption... I've also fixed some redraw issues with iTweenPathEditor too and added some extras to it to make it's use a bit more pleasant... ...It had issues when increasing Nodes by a typed in amount changing from say 60 to 69 by overtyping the 0 to 9 in the inspector, you could just use the slider but this isn't always the best way, and should work anyway so I fixed it. ...And I've also made it save a backup list of Nodes, so if you delete any it will restore them from backup first, then create new Nodes in a relative position to the previous ones so they don't start at Vector3.zero. Makes creating a path a much easier and hassle free experience, without the annoyances of accidentally removing already created Nodes. ...I also grabbed someone else's handles code for the nodes, so you could change the way they appear in the Scene view when dragging your path about, the old handles also slowed my machine down a little, so having little spheres helps instead of the default ones. All this works silently behind the scenes, so no extra settings or anything needed, just does it's job a little better than before. Let me know here, and I'll prepare and post anything you need, time to give a little back I reckon, I've had lots of help from these boards. Merry Xmas..
@Zerpico - I would very much appreciate it if you could post your solutions. I just started researching possible solutions to this problem and stumbled upon this older thread one day after your last post. Kismet!
Thanks for the reply Zerpico I completely missed it until now! That would be brilliant this issue keeps poping up in project I'm doing a nice solution like yours would be great.
whydoidoit posted an excellent constant speed script here: http://whydoidoit.com/2012/04/06/unity-curved-path-following-with-easing/
HOTWeen claims to have constant speed regardless of spaceing between points . I've been using it since encountering the same issue with iTween and I've been happy with it so far. IMHO HOTween also has a superior API.
Use PathLength to get the absolute path distance. From it calculate the velocity relative to given path (measured in path percents / s) - calculation: relativeVelocity = velocity / pathLentgh. And finally in Update use PutOnPath with the calculated percent (relativeVelocity * Time.deltaTime). No suprise here, plain and simple ... or am I missing something? This seems to work for me, just tested that..
I'm bumping this thread since i haven't been able to find any solutions while searching so far. Has anyone found a simple workaround for this problem so far? @DiskobolosCZ I tried this solution since it makes really good sense in my head. But i couldn't get it to work. Does anyone have the code for it? Cheers!
I wrote this script. Does constant speed perfectly! What it does is takes the length of path and how much time it should take to traverse and finds the average velocity which should be consistent throughout. Then for each Update frame, finds what percent should be increased and finds the distance it would move if it does travel to the new percentage point. So according to our average path velocity, find out how much distance it should have moved in deltaTime. Find their ratio and multiply the percent to be moved in this frame by that ratio. Ta-Da! Enjoy... Code (CSharp): public Transform[] waypointArray; public float percentsPerSecond = 0.2f; // %2 of the path moved per second float currentPathPercent = 0.0f; //min 0, max 1 float pathVelocity; float pathLength = 0; void Start() { pathLength = iTween.PathLength(waypointArray); pathVelocity = pathLength * percentsPerSecond; Debug.Log(pathLength); Debug.Log(pathVelocity); } void Update() { float deltaPercent = percentsPerSecond * Time.deltaTime; Vector3 nextPoint = iTween.PointOnPath(waypointArray, currentPathPercent + deltaPercent); float calcDist = Vector3.Magnitude(nextPoint - transform.position); float calcVelocity = calcDist / Time.deltaTime; float velocityScale = pathVelocity / calcVelocity; // if we are going at double velocity, velocityScale is 1/2; if at half vel, it's 2 currentPathPercent += (deltaPercent * velocityScale); // For looping if(currentPathPercent > 1.0f) currentPathPercent -= 1.0f; else if(currentPathPercent < 0) currentPathPercent += 1.0f; iTween.PutOnPath(gameObject, waypointArray, currentPathPercent); }
I'm new to iTween and struggling with speed as well. I read you guys suggesting keeping it even the distance between nodes, but my "path" is a simple "A to B" thing, and not even looped. It keeps a constant speed for about 90% of the way and gets awkwardly slow on the last 10%. Why do we even have a "time" parameter then, if it means absolutely nothing at all? I'm probably missing something, as it seems to me just an arbitrary number from which you never know what you'll gonna get. Any light on this would be very welcome! Thanks! And wish you all a great day.
So I don't necessarily know exactly how iTween does its path tweening. But when I wrote my tween library, and I then wrote my waypoint/spline library, I had a similar issue. For reference... Tween Library: https://github.com/lordofduct/spacepuppy-unity-framework-3.0/tree/master/SPTween/Tween Waypoint/Spline Library: https://github.com/lordofduct/spacepuppy-unity-framework-3.0/tree/master/SPWaypoint/Waypoints So if my knowledge of iTween is correct, they use a Catmull-rom cardinal spline. If you took the derivatives of this spline you'd find the acceleration of it is variable which causes 't' to move you through the curve at different speeds as you progress along it (even if you only have 2 nodes). When I wrote my waypoint/spline lib I had this effect when attached to my tween lib, and it annoyed me and my artist. To compensate I had to write a speed table to normalize the speed over the curve. You'll see here in my implementation of catmull-rom that I allow turning on/off the speed table (because it adds performance cost to have it on): https://github.com/lordofduct/space...Waypoint/Waypoints/CardinalSplinePath.cs#L144 And the actual speed table: https://github.com/lordofduct/space...Waypoint/Waypoints/CurveConstantSpeedTable.cs ... Now of course this isn't exactly much direct help to you for your problem since my whole thing is really part of my library and not part of itween. I more or less was posting it as an explanation for why itween probably had this issue, it's an inherit issue of the catmull-rom algorithm. I'm also surprised to learn that iTween, which has been around for years, has never dealt with this aspect of the curve in its own manner. I would say that since I wrote my CurveConstantSpeedTable in an ambiguous manner (note it takes in a delegate for calculating the curve). It could be relatively simple to adapt to another library. Using this class: https://github.com/lordofduct/space...Waypoint/Waypoints/CurveConstantSpeedTable.cs You'd have to call 'Clean' passing in the number of subdivisions you want, and a delegate for calculating the positions across the curve from t=0->1. Then when you call your tween, instead of having itween directly animate. Instead have itween tween your t for you, then with that unnormalized t you call 'GetConstPathPercFromTimePerc' on my class, and then use that to calculate the normalized position along the spline.