Hello, I am trying to move a part independent of the frame rate, so that the part won’t slow down with slow fps or speed up with fast fps. I am using deltaTime and Renderstepped. But, for some reason, the part is not moving and there are no errors. What could be the problem?
-- this is a localscript in the StarterPlayerScripts
local RunService = game:GetService("RunService")
local part = workspace:WaitForChild("HolePuncher2")
RunService.RenderStepped:Connect(function(deltaTime)
for i = 0, 120, 1 do
part.CFrame = part.CFrame + part.CFrame.RightVector * 0.25 * deltaTime
end
for i = 0, 120, 1 do
part.CFrame = part.CFrame + part.CFrame.RightVector * -0.25 * deltaTime
end
end)
Your code first moves the part forward 121 times and then moves it backwards 121 times by the same amount, so it ends up in the same position. And it does all this every frame. I’m not sure how your code is supposed to work, but the for loops in the renderstepped function don’t make sense.
oh, I want the part to move forward and backward 121 times but I want to have a delay so that the player can see the part moving, how would I go about doing that?
for i = 0, 120, 1 do
local deltatime = RunService.RenderStepped:Wait()
part.CFrame += part.CFrame.RightVector * 0.25 * deltatime
end
for i = 0, 120, 1 do
local deltatime = RunService.RenderStepped:Wait()
part.CFrame += part.CFrame.RightVector * -0.25 * deltatime
end
However, although the movement speed doesn’t depend on framerate, the total movement distance will increase when framerate decreases. Why do you want it to move exactly 121 times?
The reason i want it to loop 120 times is because 0.25 * 120 = 30 studs. I just want it to move 30 studs, and this is the way I did it. Is there a better way to do this? Because I don’t want the movement distance to change.
local RunService = game:GetService("RunService")
-- 1 / 60 is the time between frames if the frame rate is 60 fps.
local MOVE_30_STUDS_TIME = 120 * 1 / 60 -- change to what you want
local part = workspace:WaitForChild("HolePuncher2")
local originalCF = part.CFrame
local startTime = os.clock()
local conn
conn = Runservice.RenderStepped:Connect(function()
local timeSpent = os.clock() - startTime
if timeSpent >= 2 * MOVE_30_STUDS_TIME then
part.CFrame = originalCf
conn:Disconnect()
end
elseif timeSpent < MOVE_30_STUDS_TIME then
part.CFrame = originalCf + originalCf.RightVector * (timeSpent/MOVE_30_STUDS_TIME * 30)
else
part.CFrame = originalCf + originalCf.RightVector * ((2 - timeSpent/MOVE_30_STUDS_TIME) * 30)
end
end)
However, you could also use tweenservice. It would probably be the easiest way.
local TweenService = game:GetService("TweenService")
local MOVE_30_STUDS_TIME = 120 * 1 / 60 -- change to what you want
local part = workspace:WaitForChild("HolePuncher2")
local originalCf = part.CFrame
local tweenInfo = TweenInfo.new(MOVE_30_STUDS_TIME, Enum.EasingStyle.Linear)
local tween1 = TweenService:Create(part, tweenInfo, {CFrame = originalCf + originalCf.RightVector * 30)
local tween2 = TweenService:Create(part, tweenInfo, {CFrame = originalCf})
tween1:Play()
tween1.Completed:Wait()
tween2:Play()
Edit: I originally only set the tween time, but the easing style should also be set to linear.
MOVE_30_STUDS_TIME is how much time it should take for the part to move 30 studs. If you want it to take 30 seconds to move 30 studs, then you can just set MOVE_30_STUDS_TIME to 30.
Time spent is the time between when the script started running and the current time. So yes, it is the time that was spent moving the part to the location where it should be at that moment.
The code is working, but at the same time, in another localscript, I was rotating the part.
local RunService = game:GetService("RunService")
local part = workspace:WaitForChild("HolePuncher2")
while true do
part.CFrame = part.CFrame * CFrame.fromEulerAnglesXYZ(0.2,0,0)
RunService.Heartbeat:Wait()
end
When the part moves, it stops rotating, how would I add it to the first script
local RunService = game:GetService("RunService")
-- 1 / 60 is the time between frames if the frame rate is 60 fps.
local MOVE_30_STUDS_TIME = 120 * 1 / 60 -- change to what you want
local part = workspace:WaitForChild("HolePuncher2")
local originalCF = part.CFrame
local startTime = os.clock()
local conn
conn = Runservice.RenderStepped:Connect(function()
local timeSpent = os.clock() - startTime
if timeSpent >= 2 * MOVE_30_STUDS_TIME then
part.CFrame = originalCf
conn:Disconnect()
return
end
local moveMul
if timeSpent < MOVE_30_STUDS_TIME then
moveMul = timeSpent/MOVE_30_STUDS_TIME
else
moveMul = (2 - timeSpent/MOVE_30_STUDS_TIME)
end
part.CFrame = originalCf * CFrame.Angles(0.2 / (1 / 60) * timeSpent, 0, 0) + originalCf.RightVector * (moveMul * 30)
end)
It should do both. CFrame.new(originalCf.RightVector * (moveMul * 30)) is used for moving. Edit: I’m not sure if it’d have worked correctly, but I edited it and it probably works at least now.
It works now.
But I tried making it loop infinetly. Like this, and It stopped working.
local RunService = game:GetService("RunService")
-- 1 / 60 is the time between frames if the frame rate is 60 fps.
local MOVE_30_STUDS_TIME = 2 -- change to what you want
local part = workspace:WaitForChild("HolePuncher2")
local originalCF = part.CFrame
local startTime = os.clock()
while true do
local conn
conn = RunService.RenderStepped:Connect(function()
local timeSpent = os.clock() - startTime
if timeSpent >= 2 * MOVE_30_STUDS_TIME then
part.CFrame = originalCF
conn:Disconnect()
return
end
local moveMul
if timeSpent < MOVE_30_STUDS_TIME then
moveMul = timeSpent/MOVE_30_STUDS_TIME
else
moveMul = (2 - timeSpent/MOVE_30_STUDS_TIME)
end
part.CFrame = originalCF * CFrame.Angles(0.2 / (1 / 60) * timeSpent, 0, 0) + originalCF.RightVector * (moveMul * 30)
end)
wait()
end
local RunService = game:GetService("RunService")
-- 1 / 60 is the time between frames if the frame rate is 60 fps.
local MOVE_30_STUDS_TIME = 2 -- change to what you want
local ANGULAR_VELOCITY = 0.2 / (1 / 60)
local part = workspace:WaitForChild("HolePuncher2")
local originalCF = part.CFrame
local startTime = os.clock()
RunService.RenderStepped:Connect(function()
local timeSpent = os.clock() - startTime
local ful30StudsMoved = timeSpent / MOVE_30_STUDS_TIME
local modulo2 = ful30StudsMoved % 2
local moveMul = modulo2 <= 1 and modulo2 or (2 - modulo2)
part.CFrame = originalCF * CFrame.Angles(ANGULAR_VELOCITY * timeSpent, 0, 0) + originalCF.RightVector * (moveMul * 30)
end)
local moveMul
if modulo2 <= 1 then
moveMul = modulo2
else
moveMul = (2 - modulo2)
end
There are situations when an x = a and b or c doesn’t work the same way as an if statement, but that’s not a problem in this situation. It happens only when b is nil or false, and modulo2 is a number, so it can’t be nil or false. Basically this is just a shorter way to assign a value to a variable based on a condition.
The modulo operator (%) gives the remainder of division. For example, 0.45 % 2 = 0.45, 2 % 2 = 0, 2.3 % 2 = 0.3, 11.7 % 2 = 1.7. The value of modulo2 in the script is always >= 0 and < 2. If it’s between 0 and 1, the part should be moving to the right, and if its between 1 and 2, the part should be moving left.