Hi,
I need help with tilting my camera while wall running. I am trying to lerp the camera when the player tries to wall run. But my result was not very smooth.
Code:
Update = RunService.RenderStepped:Connect(function(DeltaTime)
--TODO: Camera Tilt while wallrunning.
local CameraRotation = 60
local Result = LeftWallCheck() or RightWallCheck()
if Result then
Wallrunning = true
local RotationCFrame = CFrame.Angles(0, 0, 0)
local WallNormal = Result.Normal
local FowardDirection = WallNormal:Cross(Vector3.new(0, 1, 0))
local Dot = Root.CFrame.LookVector:Dot(FowardDirection)
local LookDirection = Dot < 0 and -FowardDirection.Magnitude or FowardDirection.Magnitude
local CurrentRotation = Camera.CFrame * CFrame.Angles(0, 0, math.rad(LookDirection * CameraRotation))
local rx, ry, rz = CurrentRotation:ToOrientation()
local RotClamp = math.clamp(math.deg(rz), -CameraRotation, CameraRotation)
local NewCFrame = CFrame.fromOrientation(rx, ry, math.rad(RotClamp))
local _, _, z = RotationCFrame:ToOrientation()
RotationCFrame = CFrame.fromEulerAnglesYXZ(rx, ry, z)
RotationCFrame = RotationCFrame:Lerp(NewCFrame, math.min(2 * DeltaTime, 1))
Camera.CFrame = CFrame.new(Camera.CFrame.Position) * RotationCFrame
Updated the script a little more but now it just snaps:
function Wallrun()
local LeftResult = LeftWallCheck()
local RightResult = RightWallCheck()
if not LeftResult and not RightResult then return end -- needs to go through these casts first.
local Speed = Character:WaitForChild("Humanoid").WalkSpeed -- only works because of movement module
--if Speed >= 0 then -- testing purps
--end
if DEBUG_MODE then
if LeftResult then
DebugAttatchment(LeftResult.Position)
elseif RightResult then
DebugAttatchment(RightResult.Position)
end
end
Update = nil
Update = RunService.RenderStepped:Connect(function(DeltaTime)
--TODO: Camera Tilt while wallrunning.
local Speed = 5
local CameraRotation = 60
local Result = LeftWallCheck() or RightWallCheck()
if Result then
Wallrunning = true
local RotationCFrame = CFrame.Angles(0, 0, 0)
local WallNormal = Result.Normal
local FowardDirection = WallNormal:Cross(Vector3.new(0, 1, 0))
local Dot = Root.CFrame.LookVector:Dot(FowardDirection)
local LookDirection = Dot < 0 and -FowardDirection.Magnitude or FowardDirection.Magnitude
local CurrentRotation = Camera.CFrame * CFrame.Angles(0, 0, math.rad(LookDirection * CameraRotation))
local rx, ry, rz = CurrentRotation:ToOrientation()
local RotClamp = math.clamp(math.deg(rz), -CameraRotation, CameraRotation)
local NewCFrame = CFrame.fromOrientation(rx, ry, math.rad(RotClamp))
local _, _, z = RotationCFrame:ToOrientation()
RotationCFrame = CFrame.fromEulerAnglesYXZ(rx, ry, z)
--RotationCFrame = RotationCFrame:Lerp(NewCFrame, math.min(Speed * DeltaTime, 1))
RotationCFrame = RotationCFrame:Lerp(NewCFrame, 0.1)
Camera.CFrame = CFrame.new(Camera.CFrame.Position) * RotationCFrame
--print("ALPHA: "..math.min(Speed * DeltaTime, 1).." | DELTA: "..DeltaTime)
else
Wallrunning = false
print("Disconnected Wallrun")
Update:Disconnect()
end
end)
end
This time I decided to give the whole function. Now that it snaps, how do I change it to become smooth instead?
To make the wallrun function smooth instead of snapping, you can use interpolation (lerp) to gradually transition the camera rotation from the current rotation to the desired rotation. Currently, the line RotationCFrame = RotationCFrame:Lerp(NewCFrame, 0.1)
performs a linear interpolation with a factor of 0.1, which means it transitions 10% of the way towards the new rotation every frame.
local LeftResult = LeftWallCheck()
local RightResult = RightWallCheck()
if not LeftResult and not RightResult then return end -- needs to go through these casts first.
local Speed = Character:WaitForChild("Humanoid").WalkSpeed -- only works because of movement module
if DEBUG_MODE then
if LeftResult then
DebugAttatchment(LeftResult.Position)
elseif RightResult then
DebugAttatchment(RightResult.Position)
end
end
Update = nil
Update = RunService.RenderStepped:Connect(function(DeltaTime)
--TODO: Camera Tilt while wallrunning.
local Speed = 5
local CameraRotation = 60
local Result = LeftWallCheck() or RightWallCheck()
if Result then
Wallrunning = true
local RotationCFrame = CFrame.Angles(0, 0, 0)
local WallNormal = Result.Normal
local FowardDirection = WallNormal:Cross(Vector3.new(0, 1, 0))
local Dot = Root.CFrame.LookVector:Dot(FowardDirection)
local LookDirection = Dot < 0 and -FowardDirection.Magnitude or FowardDirection.Magnitude
local CurrentRotation = Camera.CFrame * CFrame.Angles(0, 0, math.rad(LookDirection * CameraRotation))
local rx, ry, rz = CurrentRotation:ToOrientation()
local RotClamp = math.clamp(math.deg(rz), -CameraRotation, CameraRotation)
local NewCFrame = CFrame.fromOrientation(rx, ry, math.rad(RotClamp))
local _, _, z = RotationCFrame:ToOrientation()
RotationCFrame = CFrame.fromEulerAnglesYXZ(rx, ry, z)
local lerpFactor = math.min(Speed * DeltaTime, 1) -- Calculate the lerp factor based on elapsed time
RotationCFrame = RotationCFrame:Lerp(NewCFrame, lerpFactor)
Camera.CFrame = CFrame.new(Camera.CFrame.Position) * RotationCFrame
--print("ALPHA: "..lerpFactor.." | DELTA: "..DeltaTime)
else
Wallrunning = false
print("Disconnected Wallrun")
Update:Disconnect()
end
end)
end
1 Like
I had this the first time but it just bugs out like the video shown:
If you’re experiencing issues with the camera movement when using RotationCFrame:Lerp(NewCFrame, math.min(2 * DeltaTime, 1))
, you can try adjusting the lerp factor to achieve a smoother result. Here’s an alternative approach using an easing function to gradually interpolate the rotation
local LeftResult = LeftWallCheck()
local RightResult = RightWallCheck()
if not LeftResult and not RightResult then return end -- needs to go through these casts first.
local Speed = Character:WaitForChild("Humanoid").WalkSpeed -- only works because of movement module
if DEBUG_MODE then
if LeftResult then
DebugAttatchment(LeftResult.Position)
elseif RightResult then
DebugAttatchment(RightResult.Position)
end
end
Update = nil
Update = RunService.RenderStepped:Connect(function(DeltaTime)
--TODO: Camera Tilt while wallrunning.
local Speed = 5
local CameraRotation = 60
local Result = LeftWallCheck() or RightWallCheck()
if Result then
Wallrunning = true
local RotationCFrame = CFrame.Angles(0, 0, 0)
local WallNormal = Result.Normal
local FowardDirection = WallNormal:Cross(Vector3.new(0, 1, 0))
local Dot = Root.CFrame.LookVector:Dot(FowardDirection)
local LookDirection = Dot < 0 and -FowardDirection.Magnitude or FowardDirection.Magnitude
local CurrentRotation = Camera.CFrame * CFrame.Angles(0, 0, math.rad(LookDirection * CameraRotation))
local rx, ry, rz = CurrentRotation:ToOrientation()
local RotClamp = math.clamp(math.deg(rz), -CameraRotation, CameraRotation)
local NewCFrame = CFrame.fromOrientation(rx, ry, math.rad(RotClamp))
local _, _, z = RotationCFrame:ToOrientation()
RotationCFrame = CFrame.fromEulerAnglesYXZ(rx, ry, z)
local lerpFactor = 1 - math.exp(-2 * DeltaTime) -- Exponential easing function
RotationCFrame = RotationCFrame:Lerp(NewCFrame, lerpFactor)
Camera.CFrame = CFrame.new(Camera.CFrame.Position) * RotationCFrame
--print("ALPHA: "..lerpFactor.." | DELTA: "..DeltaTime)
else
Wallrunning = false
print("Disconnected Wallrun")
Update:Disconnect()
end
end)
end
I’ve replaced the linear interpolation with an exponential easing function to achieve a smoother transition. The easing function lerpFactor = 1 - math.exp(-2 * DeltaTime)
gradually increases the lerp factor over time, creating a smoother and more natural motion. You can adjust the value 2
in lerpFactor = 1 - math.exp(-2 * DeltaTime)
to control the speed of the easing. Smaller values will result in a slower transition, while larger values will make it faster.
1 Like
Ok, I tried this script and here are the results:
As you can see from the video it still kind of shakes a lot
I apologize for the shaking issue you’re experiencing with the camera movement. To address the shaking, you can try a couple of modifications:
- Increase the value used for the easing function: Instead of using
2
in lerpFactor = 1 - math.exp(-2 * DeltaTime)
, you can try increasing it to 5
or even higher. This will make the camera movement smoother and reduce the shaking effect.
local easingFactor = 5 -- Adjust this value for smoother camera movement
local lerpFactor = 1 - math.exp(-easingFactor * DeltaTime)
- Apply a dampening effect: Instead of using a pure exponential easing function, you can combine it with a dampening effect to gradually reduce the rotation speed as it approaches the target rotation. This can help further reduce shaking. Here’s an example of how you can modify the code to include a dampening effect:
local easingFactor = 5 -- Adjust this value for smoother camera movement
local dampeningFactor = 10 -- Adjust this value for a stronger dampening effect
local lerpFactor = 1 - (1 - math.exp(-easingFactor * DeltaTime)) / dampeningFactor
By applying a dampening factor, the rotation speed will decrease gradually as it gets closer to the target rotation, resulting in smoother camera movement.
Feel free to adjust the values of easingFactor
and dampeningFactor
to achieve the desired smoothness in the camera movement.
I hope this works !
1 Like
It still snaps for some reason. Even though it is lerping, it still snaps really fast.
If the camera movement is still snapping even with the modifications, there may be other factors affecting the smoothness of the movement. Here are a few additional suggestions to troubleshoot the issue:
-
Frame Rate Independence: Ensure that the camera movement calculations are frame rate independent. The
DeltaTime
value used in the code snippet should represent the time elapsed since the last frame. Verify that it’s accurately capturing the time between frames to ensure smooth movement regardless of the frame rate.
-
Update Frequency: Consider adjusting the frequency at which the camera movement is updated. Instead of relying on
RunService.RenderStepped
, which triggers on every rendered frame, you can try using a lower frequency update, such as RunService.Heartbeat
, which triggers once per physics update. This can help smooth out the movement by reducing the number of interpolation steps per second.
-
Interpolation Range: Experiment with the range of interpolation. Instead of interpolating from the current rotation directly to the target rotation, you can try adding some additional intermediary rotations. For example, you can divide the interpolation into smaller steps and gradually move towards the target rotation over multiple frames. This can help alleviate any sudden jumps in rotation.
-
Debugging: Check for any potential conflicts or inconsistencies in other parts of the code that may affect the camera movement. Make sure there aren’t any other camera-related scripts interfering with the smooth interpolation.
By carefully examining these aspects and making adjustments as needed, you should be able to achieve smoother camera movement.
1 Like