v1sionary
|
  |
| Joined: 03 Feb 2012 |
| Total Posts: 1981 |
|
|
| 22 May 2017 09:14 AM |
How would I move a part along a bezier curve using BodyVelocity?
|
|
|
| Report Abuse |
|
|
v1sionary
|
  |
| Joined: 03 Feb 2012 |
| Total Posts: 1981 |
|
| |
|
RogueMage
|
  |
| Joined: 28 Jan 2012 |
| Total Posts: 1235 |
|
|
| 22 May 2017 11:11 AM |
Just BodyVelocity downwards relative to the object enough to keep it down and a body velocity pushing it forward?
You don't really need that much math |
|
|
| Report Abuse |
|
|
v1sionary
|
  |
| Joined: 03 Feb 2012 |
| Total Posts: 1981 |
|
|
| 22 May 2017 11:23 AM |
I know how to make a bezier curve, but what I want to find out is how to move a part in a bezier curve using BodyVelocity.
|
|
|
| Report Abuse |
|
|
RogueMage
|
  |
| Joined: 28 Jan 2012 |
| Total Posts: 1235 |
|
|
| 22 May 2017 11:25 AM |
I'm not telling you how to make a bezier curve
Read what I said again |
|
|
| Report Abuse |
|
|
samy22
|
  |
| Joined: 28 Sep 2008 |
| Total Posts: 2181 |
|
|
| 22 May 2017 11:34 AM |
Find the derivative of the function producing a bezier curves. That will represent velocity I believe. You could google velocity bezier curve equation. |
|
|
| Report Abuse |
|
|
v1sionary
|
  |
| Joined: 03 Feb 2012 |
| Total Posts: 1981 |
|
|
| 22 May 2017 04:18 PM |
@samy22 can't find anything, I've been trying for hours to do this, but nothing really worked except using the roblox wiki article on bezier curves and using BodyPosition to set the parts position along a point on the curve, but this doesn't produce constant speed so the longer the curve is the faster the part on it would move. I'm out of ideas, can you help?
|
|
|
| Report Abuse |
|
|
samy22
|
  |
| Joined: 28 Sep 2008 |
| Total Posts: 2181 |
|
|
| 22 May 2017 04:32 PM |
If you know how to work with derivatives, there are some on the wiki page for Bezier curves with a bit of explanation.
Alternatively, you can use this for an approximation,
dy = y*(i+1) - y*(i) dx = x*(i+1) - x*(i) velocity = dy/dx
Generate enough points on the bezier curve though for a good approximation of velocity using this. |
|
|
| Report Abuse |
|
|
samy22
|
  |
| Joined: 28 Sep 2008 |
| Total Posts: 2181 |
|
|
| 22 May 2017 04:40 PM |
--Mistake
dy = y*(i+1) - y*(i) dx = x*(i+1) - x*(i) velocity = Vector3.new(dx,dy,0)
So in one second, your particle reaches the next point from it's previous point.
Have a variable which also adjusts for lag by measuring how long wait(1) takes.
That will probably need some more clearing up. Sometimes wait(1) can take a little longer than exactly 1 second and your particle may end up overshooting so it will need to adjust for this. Test it for now though.
|
|
|
| Report Abuse |
|
|
cntkillme
|
  |
| Joined: 07 Apr 2008 |
| Total Posts: 44956 |
|
|
| 22 May 2017 04:43 PM |
Assuming you want a constant speed, you can calculate the displacement and divide that by the timestep (pref. using renderstepped for most accurate results)
something like blah.RenderStepped:Connect(function(dt) local disp = bez(pts, t + dt) - bez(pts, t) local vel = disp/dt obj.Velocity = vel -- should probably ensure obj.Position is at bez(pts, t) at this point to prevent error accumulation end) |
|
|
| Report Abuse |
|
|
cntkillme
|
  |
| Joined: 07 Apr 2008 |
| Total Posts: 44956 |
|
|
| 22 May 2017 04:43 PM |
| Well that's not constant speed but more like "consistent" speed |
|
|
| Report Abuse |
|
|
samy22
|
  |
| Joined: 28 Sep 2008 |
| Total Posts: 2181 |
|
|
| 22 May 2017 05:09 PM |
Hang on...
Say a renderframe takes hypothetically 2 seconds. (So dt = 2).
Then the displacement is now at a position which it needs to reach in 2 seconds.
Velocity is now trying to reach that point in half the amount of time. So one second.
The next frame fires and lets say this one took 3 seconds hypothetically. (dt = 3).
Now it has done the previous trip three times (3*one second) and surely overshot the point? (Because in one second it reaches the point, then for the next 2 seconds continues going in that direction).
It will now then think it was at the position it was supposed to be at and try to go along the path between the point it was supposed to be at and the point after that. (Not along the path but in the same direction as that path.)
And it will continue to error/ not correct itself?
Correct me if i'm wrong
|
|
|
| Report Abuse |
|
|
samy22
|
  |
| Joined: 28 Sep 2008 |
| Total Posts: 2181 |
|
|
| 22 May 2017 05:16 PM |
"Velocity is now trying to reach that point in half the amount of time. So one second."
Oops, i mean...
if vel = disp...
then in one second, it will reach the next point (t+dt), right?
But it will now take twice as long (because it goes half the speed) where vel = disp/2,
(so in 2 seconds, it will reach the next point (t+dt) ).
And blah blah, if the next frame takes a hypothetical 3 seconds then we've still overshot and it doesn't correct itself. Right? :s
|
|
|
| Report Abuse |
|
|
samy22
|
  |
| Joined: 28 Sep 2008 |
| Total Posts: 2181 |
|
|
| 22 May 2017 05:32 PM |
This may fix; t = 0 --Starting value blah.RenderStepped:Connect(function(dt) local disp = bez(pts, t + dt) - particle.Position local vel = disp/dt obj.Velocity = vel t = t+dt end)
Ensuring that your particle.Position starts on the bezier curve of course (which you would want anyway.)
This would attempt to adjust for any overshooting and thus you wouldn't need to check that you are at the next point. |
|
|
| Report Abuse |
|
|
cntkillme
|
  |
| Joined: 07 Apr 2008 |
| Total Posts: 44956 |
|
|
| 22 May 2017 05:38 PM |
| It would be soo nice if we had a guarantee frames always rendered at the same rate no matter what but sadly that'll never realistically happen :_* |
|
|
| Report Abuse |
|
|
Aethex
|
  |
| Joined: 16 Oct 2011 |
| Total Posts: 2193 |
|
|
| 22 May 2017 05:46 PM |
| @cntkillme Really? I find it quite easy to maintain an FPS of zero. |
|
|
| Report Abuse |
|
|
samy22
|
  |
| Joined: 28 Sep 2008 |
| Total Posts: 2181 |
|
|
| 22 May 2017 05:47 PM |
Or even just a way for some prediction of how long the next renderframe will take ahead of time. (Though I don't imagine that would be easy or accurate.) (Would basically try to predict the future.) Would probably be chaotic too.
Also my bad, you would still need to check that you are at the next point before proceeding to try to reach the next point.
Boy this is tough...
Hold on, trying to work on a fix. |
|
|
| Report Abuse |
|
|
cntkillme
|
  |
| Joined: 07 Apr 2008 |
| Total Posts: 44956 |
|
|
| 22 May 2017 05:48 PM |
| I mean the simple method would just be to fix the position to where it should be. |
|
|
| Report Abuse |
|
|
samy22
|
  |
| Joined: 28 Sep 2008 |
| Total Posts: 2181 |
|
|
| 22 May 2017 05:57 PM |
Actually, what would be amazing and even better.
Some type of new velocity class which performs normal bodyvelocity but has a timer. i.e. Stops (resets to Vector3.new(0,0,0)) after exactly 2 seconds irregardless of how long the frame takes to render. So if the next frame took 3 seconds, it would just simply render it where it was supposed to stop.
Is this even possible already? Could probably just re position the particle where it was supposed to stop after every renderframe.
However, that then defeats the purpose of using velocity...
You could of just re-positioned the particle to move slowly along the path after every frame and not use velocity at all.
So... wat do |
|
|
| Report Abuse |
|
|
samy22
|
  |
| Joined: 28 Sep 2008 |
| Total Posts: 2181 |
|
| |
|
cntkillme
|
  |
| Joined: 07 Apr 2008 |
| Total Posts: 44956 |
|
|
| 22 May 2017 05:58 PM |
| set the velocity every frame and displace the object by the error obtained from doing the numerical integration and it should be so small that nobody will notice. |
|
|
| Report Abuse |
|
|
samy22
|
  |
| Joined: 28 Sep 2008 |
| Total Posts: 2181 |
|
|
| 22 May 2017 06:27 PM |
t = 0 --Starting value in bezier curve equation.
--Variables below should not be changed. prevstep = 0 sum = 0 HasFirstStepBeenFound = false
game:GetService("RunService").RenderStepped:Connect(function (dt)
if HasFirstStepBeenFound == true then
sum = sum + dt if sum < prevstep then --Do nothing else local disp = bez(pts, t + dt) - particle.Position local vel = disp/dt obj.Velocity = vel t = t+dt prevstep = dt sum = 0 end
else
HasFirstStepBeenFound = true local disp = bez(pts, t + dt) - particle.Position local vel = disp/dt obj.Velocity = vel t = t+dt prevstep = dt sum = 0
end
end)
There, should auto correct completely now as much as it can. At least I believe so. The Fix: Doesn't let you move on path to the next point until enough time has passed for you to reach your previous goal.
I believe this should work now. |
|
|
| Report Abuse |
|
|
v1sionary
|
  |
| Joined: 03 Feb 2012 |
| Total Posts: 1981 |
|
|
| 03 Jun 2017 06:36 PM |
What is bez() and particle?
|
|
|
| Report Abuse |
|
|
v1sionary
|
  |
| Joined: 03 Feb 2012 |
| Total Posts: 1981 |
|
| |
|
samy22
|
  |
| Joined: 28 Sep 2008 |
| Total Posts: 2181 |
|
|
| 04 Jun 2017 02:32 PM |
From what cntkillme originally posted,
I believe bez(pts, t value) is a function which takes two inputs,
First input; a table of points so e.g. pts = {Vector3.new(1,2,3), Vector3.new(1,9,4), etc.}.
Second input: value of t to be evaluated in bezier curve equation which as you know, t should be between 0 and 1.
Output: Takes table of points and produces bezier curve equation from it, and then calculates where t = (some value between 0 and 1) is on the curve by plugging that value into the bezier curve equation calculated from your table of points. Note that this output must be a Vector3.
You will also want to make sure it stops past t = 1 (the end of the bezier curve), which I forgot to add but is fairly easy to include in my final script.
If you are confused on how to make this function, check out the wiki for it.
Lastly, this will take 1 second in-game time for it to reach the end of the curve. If you want to change how fast this is so that it takes longer, have the function bez(pts, t value) divide the t value by some number before working out where it is on the bezier curve so that it needs to take larger inputted t values to get to the end of the bezier curve. (e.g. You could divide inputted t values by 10 in the bezier function then in the velocity function, don't stop until t = 10.)
|
|
|
| Report Abuse |
|
|