I have a script right here which basically moves a part to another parts position with Lerp. I basically want to gradually lerp parts.
Here’s a video of it
Here’s the code
local RunService = game:GetService("RunService")
local part = script.Parent
local bruh = workspace:WaitForChild("Bruh")
local runningTime = 0
local lerpTime = 10
local connection
connection = RunService.Heartbeat:Connect(function(deltaTime)
runningTime += deltaTime -- deltaTime, the time (seconds) between each frame (different deltaTimes)
-- runningTime will be the amount of time that has been running since the first Heartbeat
-- if delta the runningTime value increases, the hearbeat will be fired more
local alpha = runningTime/ lerpTime
print(alpha)
part.CFrame = part.CFrame:Lerp(bruh.CFrame, alpha)
if alpha >= 1 then
connection:Disconnect()
print("yes")
elseif alpha >= 0.5 then
part.BrickColor = BrickColor.random()
part.CFrame *= CFrame.new(0, -30, 0)
print("yes")
connection:Disconnect()
end
end)
However, I encounter issues such as the part doesn’t move to half of the “Lerp journey”. I mean the alpha parameter.
After the part moves to the targeted parts CFrame, after some time, it starts changing it’s color as well as its CFrame. It basically didn’t stop moving to the targeted parts CFrame even after it has reached its destination.
Everything is pretty much delayed, it still prints the alpha value even when the part has reached its destination.
Is there also some sort of a delay for RunService? (like task.wait() for loops) I checked the script performance for the script with the code above and it’s activity is like 1.9%. It will ruin the game performance. So what’s the benefit of it over loops?
I also don’t know if lerp is just as laggy as tweenservice when not tweened on the client. Is it the same as tweening?
delta time lacks accuracy, just use start tick and tick method.
local start = tick()
local max_time = 10
local connection = ...
function RenderStep()
local progress = tick() - start
local alpha = progress / max_time
part.CFrame = part.CFrame:Lerp(bruh.CFrame, alpha)
if alpha >= 1 then
connection:Disconnect()
print("yes")
elseif alpha >= 0.5 then
part.BrickColor = BrickColor.random()
part.CFrame *= CFrame.new(0, -30, 0)
print("yes")
connection:Disconnect()
end
end
I don't remember though if tick returns time in milliseconds or seconds so...
local RunService = game:GetService("RunService")
local part = script.Parent
local bruh = workspace:WaitForChild("Bruh")
local runningTime = 0
local lerpTime = 10
local connection
connection = RunService.Heartbeat:Connect(function(deltaTime)
runningTime = runningTime + deltaTime -- deltaTime, the time (seconds) between each frame (different deltaTimes)
-- runningTime will be the amount of time that has been running since the first Heartbeat
-- if the runningTime value increases, the heartbeat will be fired more
local alpha = math.clamp(runningTime / lerpTime, 0, 1)
print(alpha)
part.CFrame = part.CFrame:Lerp(bruh.CFrame, alpha)
if alpha >= 1 then
connection:Disconnect()
print("Reached destination")
elseif alpha >= 0.5 then
part.BrickColor = BrickColor.random()
part.CFrame = part.CFrame * CFrame.new(0, -30, 0)
print("Halfway there")
end
end)
It’s because you’re interpolating between the current part’s CFrame and its final destination - each frame, that distance will shorten, and your alpha will increase; thus, the time it takes to travel between the two will become exponentially smaller
You need to record the part’s initial CFrame, and interpolate between the start and goal positions, i.e.:
local RunService = game:GetService("RunService")
local part = script.Parent
local bruh = workspace:WaitForChild("Bruh")
local runningTime = 0
local lerpTime = 10
-- origin of the part
local origin = part.CFrame
local connection
connection = RunService.Heartbeat:Connect(function(deltaTime)
runningTime += deltaTime -- deltaTime, the time (seconds) between each frame (different deltaTimes)
-- runningTime will be the amount of time that has been running since the first Heartbeat
-- if delta the runningTime value increases, the hearbeat will be fired more
local alpha = runningTime / lerpTime
print(alpha)
part.CFrame = origin:Lerp(bruh.CFrame, alpha) -- lerp between the initial position and the final position
if alpha >= 1 then
connection:Disconnect()
print("yes")
elseif alpha >= 0.5 then
part.BrickColor = BrickColor.random()
part.CFrame *= CFrame.new(0, -30, 0)
print("yes")
connection:Disconnect()
end
end)
Also, is there a way to decrease the it’s activity?
Every time I use RunService and I check the script performance, it has a high activity, therefore ruining game performance.
I don’t understand I have this other script, but using a loop.
local part = script.Parent
local clickDetector = part:WaitForChild("ClickDetector")
local targets = workspace:WaitForChild("Targets")
local target1 = targets:WaitForChild("1")
local connection1
connection1 = clickDetector.MouseClick:Connect(function(plr)
while true do
if part.CFrame == target1.CFrame then
print("yes")
break
end
task.wait(0.001)
part.CFrame = part.CFrame:Lerp(target1.CFrame, 0.1)
end
connection1:Disconnect()
print(connection1.Connected)
end)
the :Lerp() function will only work if I use the part’s current CFrame and no the initial CFrame. Isn’t RunService the same as loops? The print statement never executes too even when a condition has met.
As you may or may not know, lerps only calculate the percentage of values, meaning if you want evenly spaced out positions, you must calculate every step before animating between them. Otherwise you will get exponential movement, as seen in your first post.
--non-tested example code of using lerps
local steps = 15
local StepsTable = {}
for i = 1, steps do
local LerpedPosition = Vector3.new():Lerp(Vector3.new(), 1/steps)
StepsTable[i] = LerpedPosition
end
local count = 1
while task.wait(3) do
Part.Position = StepsTable[count]
count += 1
end
or
local InitalPosition = Vector3.new()
local steps = 15
local count = 1
while task.wait(3) do
local LerpedPosition = InitalPosition:Lerp(Vector3.new(), count/steps)
count += 1
if count == steps then
break
end
end
you can also lerp by a specific speed or time
--specific speed
local speed = 5 --assumed to be studs per SECOND
local distance = 15
loacl steps = distance/speed
while task.wait(1) do
--use steps in lerp somewhere below
end
--==============
--==============
--specific time (to reach goal)
local time = 30
local steps = 15
local LoopWaitTime = time/steps
while task.wait(LoopWaitTime) do
--lerp stuff here
end
If I mistyped something just let me know, and hope this helps!
unless you have a part that is going to be continously lerped, I wouldnt recomend it. It is possible though
local InitalPosition = Vector3.new()
local steps = 15
local count = 1
game:GetService("RunService").RenderedStepped:Connect(function())
local LerpedPosition = InitalPosition:Lerp(Vector3.new(), count/steps)
count += 1
if count == steps then
break
end
end)
Generally, use runservice if you have a loop that going to be running for a long time, or something needs to happen before/after a camera/physics update
I encounter issues such as the part doesn’t move to half of the “Lerp journey”
elseif alpha >= 0.5 then -- (basically alpha >= 0.5 and alpha < 1)
part.BrickColor = BrickColor.random()
part.CFrame *= CFrame.new(0, -30, 0)
print("yes")
connection:Disconnect() -- You disconnected the connection. it doesn't loop anymore
end
After the part moves to the targeted parts CFrame, after some time, it starts changing it’s color as well as its CFrame. It basically didn’t stop moving to the targeted parts CFrame even after it has reached its destination.
I don’t know if you removed the connection:Disconnect() line in the elseif alpha >= 0.5 statement but it seems very likely that this happened because the codeblock inside the elseif statement repeated
part.BrickColor = BrickColor.random()
part.CFrame *= CFrame.new(0, -30, 0)
-- Equivalent to part.CFrame = part.CFrame * CFrame.new(0, -30, 0)
-- Therefore it keeps increasing even though it reached your destination
I also checked the video and didn’t find the problems you described in the video, it’d be nice to have a version where there’s an output bar as well.
Alternatively, you can also use TweenService, very easy, fast and convenient rather than lerping
Because you use part.CFrame as the origin, the lerp journey wouldn’t be consistent and instead it’d look like the part is decelerating the farther it goes. (it starts very fast and stops slowly)
To fix this you should make a variable to keep the original CFrame, and it should lerp linearly.