Why is this camera lerp not working?

I’m trying to seamlessly move this camera to move with the character like a 2d game, but it’s not working for some reason. If anyone knows what the problem is, please tell me!

local player = game.Players.LocalPlayer
local camera = workspace.CurrentCamera

player.CharacterAdded:Wait()
player.Character:WaitForChild("HumanoidRootPart")

camera.CameraType = Enum.CameraType.Scriptable


local function onUpdate()
	if player.Character and player.Character:FindFirstChild("HumanoidRootPart") then
		local newSpot = CFrame.new(player.Character.HumanoidRootPart.Position) * CFrame.new(0, 3.456, -20) * CFrame.Angles(0,math.rad(180),0)
		if  newSpot ~= camera.CFrame then
			for i = 0, 1, 0.1 do
				task.wait()
				camera.CFrame = camera.CFrame:Lerp(newSpot, i)
			end	
		end
	end
end
 
while wait(1) do
	onUpdate()
end

robloxapp-20230922-2312227.wmv (271.0 KB)

2 Likes

The issue with your script could be due to the fact that your camera is not properly following the player’s character. In a 2D game, the camera should be locked to the player’s X and Y position, but not the Z position.

Try modifying your onUpdate function as follows:

local function onUpdate()
    if player.Character and player.Character:FindFirstChild("HumanoidRootPart") then
        local charPos = player.Character.HumanoidRootPart.Position
        local newSpot = CFrame.new(charPos.X, charPos.Y, camera.CFrame.Z) * CFrame.Angles(0,math.rad(180),0)
        if  newSpot ~= camera.CFrame then
            for i = 0, 1, 0.1 do
                task.wait()
                camera.CFrame = camera.CFrame:Lerp(newSpot, i)
            end	
        end
    end
end

This script will keep the camera’s Z position constant while following the player’s X and Y position, creating a side-scrolling effect.

It is locked onto the player. I want it to have like a slight delay so it the movement in the camera is smoother. It’s just the lerp that’s not working. Here is the video

robloxapp-20230922-2312227.wmv (271.0 KB)

Ah, i see.

local player = game.Players.LocalPlayer
local camera = workspace.CurrentCamera

player.CharacterAdded:Wait()
player.Character:WaitForChild("HumanoidRootPart")

camera.CameraType = Enum.CameraType.Scriptable

local function onUpdate()
    if player.Character and player.Character:FindFirstChild("HumanoidRootPart") then
        local charPos = player.Character.HumanoidRootPart.Position
        local newSpot = CFrame.new(charPos.X, charPos.Y, camera.CFrame.Z) * CFrame.Angles(0,math.rad(180),0)
        if  newSpot ~= camera.CFrame then
            for i = 0, 1, 0.05 do
                task.wait(0.1) -- adding delay here
                camera.CFrame = camera.CFrame:Lerp(newSpot, i)
            end	
        end
    end
end
 
while wait(1) do
	onUpdate()
end

Just add a delay at function.

That’s what I tried. It still doesn’t work :frowning:

Hmm.

The issue with your script might be due to the way you’re using the Lerp function. The third parameter of the Lerp function is a value between 0 and 1 that represents the progress of the transition. If this value is 0, the Lerp function returns the first position (in this case, the camera’s current position). If it’s 1, the Lerp function returns the second position (the new position). If it’s between 0 and 1, the Lerp function returns a position that’s somewhere in between.

In your script, you’re updating this value from 0 to 1 in increments of 0.05 every 0.1 seconds. This means that the transition should take about 2 seconds in total. However, your while loop is set to repeat every 1 second, which means the transition might be getting interrupted before it’s completed, causing the camera to jump to the new position.

To fix this, you could try increasing the delay in your while loop to give the transition more time to complete:

local player = game.Players.LocalPlayer
local camera = workspace.CurrentCamera

player.CharacterAdded:Wait()
player.Character:WaitForChild("HumanoidRootPart")

camera.CameraType = Enum.CameraType.Scriptable

local function onUpdate()
    if player.Character and player.Character:FindFirstChild("HumanoidRootPart") then
        local charPos = player.Character.HumanoidRootPart.Position
        local newSpot = CFrame.new(charPos.X, charPos.Y, camera.CFrame.Z) * CFrame.Angles(0,math.rad(180),0)
        if  newSpot ~= camera.CFrame then
            for i = 0, 1, 0.05 do
                task.wait(0.2) -- increase delay here
                camera.CFrame = camera.CFrame:Lerp(newSpot, i)
            end	
        end
    end
end
 
while wait(2) do -- increase delay here
	onUpdate()
end

In this modified script, the transition should now take about 4 seconds in total, and the while loop is set to repeat every 2 seconds, giving the transition enough time to complete before the next update.

Hope this works🙏

Closer!
robloxapp-20230922-2330030.wmv (255.4 KB)

Are you being sarcastic or is that how you would actually want it to be like?

No lol. I meant it was starting to get more smoother looking and it was a step to the right direction

So can you restate your goals really quick. So, you want it to be very smooth and have a slight delay?

Yeah. By delay I meant it’s not exactly locked into the player. Kind of like when a minecraft dog is following you. It follows you and then it stops when it’s close enough

1 Like

Here I tried using magnitude. Hope it works.

local player = game.Players.LocalPlayer
local camera = workspace.CurrentCamera

player.CharacterAdded:Wait()
player.Character:WaitForChild("HumanoidRootPart")

camera.CameraType = Enum.CameraType.Scriptable

local function onUpdate()
    if player.Character and player.Character:FindFirstChild("HumanoidRootPart") then
        local charPos = player.Character.HumanoidRootPart.Position
        local newSpot = CFrame.new(charPos.X, charPos.Y, camera.CFrame.Z) * CFrame.Angles(0,math.rad(180),0)
        if (newSpot.p - camera.CFrame.p).Magnitude > 10 then -- change this value to increase or decrease the distance at which the camera starts to follow
            for i = 0, 1, 0.05 do
                task.wait(0.05) -- increase delay here
                camera.CFrame = camera.CFrame:Lerp(newSpot, i)
            end	
        end
    end
end
 
while wait(0.1) do -- increase delay here
	onUpdate()
end