Upon player landing, I’m trying to achieve a camera “bounce” effect by tilting the camera modeled by the following equation:
The system functions, but not exactly as intended. At the end of the bounce, my intent is to have the camera axis pointed exactly in the direction it began in because the f(t) = 0 at t=0.65 (end of the function). However, in testing, you will notice the final vertical angle of the camera lands at ~ -4.3.
My suspicion is that this line needs to be changed
cam.CFrame *= CFrame.Angles(tiltAngle, 0, 0)
I imagine multiplying by the camera’s current CFrame each Renderstep is causing an unwanted multiplicative effect that distorts the function. I have tried storing the original CFrame, but to no avail, as my changes resulted in absolute camera positioning that was not independent of user mouse movement like it currently is. Any help reworking the CFrame manipulation would be appreciated.
Code:
local Players = game:GetService("Players")
local RunService = game:GetService("RunService")
local cam = workspace.CurrentCamera or workspace:WaitForChild("Camera")
local player = Players.LocalPlayer
local character = player.Character or player.CharacterAdded:Wait()
local humanoid = character.Humanoid or character:WaitForChild("Humanoid")
local duration = 0.65
local bounces = 3
local amplitude = 1.5
local compression = bounces / duration
local E = math.exp(1)
local function f(t) -- the function shown in desmos
if t >= duration then return 0 end
if t <= 0 then return 0 end
local exponent = compression * t + 0.5
return amplitude * math.pow(E, -exponent) * math.cos(math.pi * (compression * t + 0.5))
end
local isLanded = false
local t = 0
local function onHumanoidStateChanged(_oldState, newState)
if newState == Enum.HumanoidStateType.Landed then
isLanded = true
t = 0
end
end
RunService.RenderStepped:Connect(function(dt)
if isLanded then
t += dt
if t <= duration then
local tiltAngle = math.rad(f(t))
cam.CFrame *= CFrame.Angles(tiltAngle, 0, 0)
else
isLanded = false
end
end
end)
humanoid.StateChanged:Connect(onHumanoidStateChanged)