I’ve been playing this game Called North hills, awesome game, And i looked it had this wonderful camera effect that tilts your camera to a side if you are looking very below, my guess is that it uses the mouse delta, But How Exactly?
Video >
This inmmersive effect is also seen on other games like The Rake Classic edition :
Game itself :
As for the code that i am using, is this, which includes only the viewbobbing :
--!strict
task.wait(.15)
-- SERVICES --
local RunS = game:GetService("RunService")
local TweenS = game:GetService("TweenService")
local UIS = game:GetService("UserInputService")
-- VARIABLES --
local Player = game.Players.LocalPlayer
local StarterPlayer = game:WaitForChild("StarterPlayer")
local Char = Player.Character or Player.CharacterAdded:Wait()
local Hum = Char:WaitForChild("Humanoid")
local RootPart = Char:WaitForChild("HumanoidRootPart")
local Camera = workspace.CurrentCamera
local Head = Char:WaitForChild("Head")
Camera.CameraType = Enum.CameraType.Scriptable
--
local DriftSettings = script:WaitForChild("DriftSettings")
local TiltIntensity_Folder = script:WaitForChild("TiltIntensity")
local TiltSpeed_Folder = script:WaitForChild("TiltSpeed")
local BobbingIntensity_Folder = script:WaitForChild("BobbingIntensity")
local BobbingSpeed_Folder = script:WaitForChild("BobbingSpeed")
local SwayFolder = script:WaitForChild("Sway")
--
local bobbing = nil
local tiltSideSpeed : number = TiltSpeed_Folder.SideSpeed.Value -- Default: 0.05
local tiltSpeed : number = TiltSpeed_Folder.Speed.Value -- Default: 0.08
local tiltIntensity : number = TiltIntensity_Folder.Walking.Value -- Default: 1.5
local bobbingSpeed : number = BobbingSpeed_Folder.Speed.Value -- Default: 0.155
local bobbingIntensityWalking : number = BobbingIntensity_Folder.Walking.Value -- Default: 0.008
local bobbingIntensitySprinting : number = BobbingIntensity_Folder.Sprinting.Value -- Default: 0.02
local BaseMult = script:WaitForChild("BaseMult")
local BaseRot = script:WaitForChild("BaseRot")
local SetRot = script:WaitForChild("SetRot")
local BaseSway = SwayFolder:WaitForChild("BaseSway")
local SetSway = SwayFolder:WaitForChild("SetSway")
local SwayStrenght = SwayFolder:WaitForChild("SwayStrenght")
local CustomSwayZVal = SwayFolder:WaitForChild("CustomSwayZVal")
local DriftMin = DriftSettings:WaitForChild("DriftMin")
local DriftMax = DriftSettings:WaitForChild("DriftMax")
_G.ThirdPerson = false
--
local tilt : number = 0
local tiltValue : number = 0
local sinValue : number = 0
--
local head_side = 0.1
local previousSineX : number = 0
local previousSineY : number = 0
local previousTilt : number = 0
local Rotation = CFrame.new()
local sway : CFrame
local MouseDelta : Vector2
local Vel,t,x,y : number
local CurrentVel = 0
local Drift = 0
local Limiter = 0
local sin = math.sin
local cos = math.cos
local rad = math.rad
local abs = math.abs
local sqrt = math.sqrt
local clamp = math.clamp
local round = math.round
local clock = os.clock
-- SETTINGS --
local TARGET_FPS : number = 60 -- What FPS to aim for
-- FUNCTIONS --
function lerp(a : number, b : number, t : number) : number
return a + (b - a) * t
end
function calculateSine(speed : number, intensity : number) : CFrame
sinValue += speed
if sinValue > (math.pi * 2) then sinValue = 0 end
local sineY : number = intensity * math.sin(2 * sinValue)
local sineX : number = intensity * math.sin(sinValue)
local sineCFrame : CFrame = CFrame.new(sineX, sineY, 0)
return sineCFrame
end
function calculateTilt(speed : number, intensity : number) : CFrame
tiltValue += speed
if tiltValue > (math.pi * 2) then
tiltValue = 0
end
local sineY : number = intensity * math.sin(2 * tiltValue)
local sineX : number = intensity * math.sin(tiltValue)
local sineCFrame : CFrame = CFrame.new(sineX, sineY, 0)
return sineCFrame
end
function GetVelMag() : number
return round(Vector3.new(RootPart.AssemblyLinearVelocity.X, RootPart.AssemblyLinearVelocity.Y, RootPart.AssemblyLinearVelocity.Z).Magnitude)
end
function NumLerp(num1: number, num2: number, rate: number) : number
return num1 + (num2-num1)*rate
end
function GetMouseDrift(Drift : number, MouseDelta : Vector2, dt : number) : number
return NumLerp(Drift, clamp(MouseDelta.X, DriftMin.Value, DriftMax.Value), (BaseMult.Value * dt))
end
function GetSwayVal(x:number, y:number) : CFrame
return CFrame.new(Vector3.new(x, y, 0), Vector3.new(x*.95, y*.95, CustomSwayZVal.Value)) + Camera.CFrame.Position
end
function CalculateCurve(Base : number, Set : number) : number
return sin(clock() * Base) * Set
end
task.wait(.25)
-- Camera sway loop
bobbing = RunS:BindToRenderStep("CameraViewbobbingx", Enum.RenderPriority.Camera.Value+1, function(dt : number)
-- Check if the humanoid is dead
if not Hum then return end
if Hum.Health <= 0 then
RunS:UnbindFromRenderStep("CameraViewbobbingx") -- Disconnect view bobbing when dead
return
end
UIS.MouseBehavior = Enum.MouseBehavior.LockCenter
t = clock()
MouseDelta = UIS:GetMouseDelta()
Vel = NumLerp(CurrentVel, GetVelMag(), 0.1)
CurrentVel = Vel
bobbingIntensitySprinting = script.BobbingIntensity.Sprinting.Value
tiltSpeed = script.TiltSpeed.Speed.Value
tiltSideSpeed = script.TiltSpeed.SideSpeed.Value
bobbingSpeed = script.BobbingSpeed.Speed.Value
local adjustFPS = TARGET_FPS / (1 / dt)
local movementVector : Vector3 = Camera.CFrame:VectorToObjectSpace(RootPart.AssemblyLinearVelocity / math.max(Hum.WalkSpeed, 0.01) * tiltIntensity)
local speedModifier : number = (Hum.WalkSpeed / 16)
tilt = math.clamp(lerp(tilt, movementVector.X * tiltSideSpeed, 0.1 * adjustFPS), -0.25, 0.1)
x = cos(t * BaseSway.Value) * SetSway.Value
y = sin(t * BaseSway.Value) * SetSway.Value
sway = GetSwayVal(x,y)
Drift = GetMouseDrift(Drift, MouseDelta, dt)
local sineCFrame : CFrame = calculateSine(bobbingSpeed * speedModifier * adjustFPS, movementVector.Magnitude * 1)
local tiltCFrame : CFrame = calculateTilt(tiltSpeed * 1.15 * adjustFPS, movementVector.Magnitude * 1.05)
local lerpedSineX : number
local lerpedSineY : number
if speedModifier <= 1 then
lerpedSineX = lerp(previousSineX, sineCFrame.X, bobbingIntensityWalking * speedModifier * adjustFPS)
lerpedSineY = lerp(previousSineY, sineCFrame.Y, (bobbingIntensityWalking - 0.001) * speedModifier * adjustFPS) -- Don't move much on Y-axis
tiltIntensity = TiltIntensity_Folder.Walking.Value
else
lerpedSineX = lerp(previousSineX, sineCFrame.X, bobbingIntensitySprinting * (speedModifier * 1.2) * adjustFPS)
lerpedSineY = lerp(previousSineY, sineCFrame.Y, (bobbingIntensitySprinting - 0.001) * (speedModifier * 1.2) * adjustFPS) -- Don't move much on Y-axis
tiltIntensity = TiltIntensity_Folder.Sprinting.Value
end
local lerpedTilt : number = lerp(previousTilt, tiltCFrame.Y, 0.001 * adjustFPS)
if _G.ThirdPerson then
Player.CameraMode = Enum.CameraMode.Classic
Player.CameraMaxZoomDistance = 4
Player.CameraMinZoomDistance = 4
Camera.CFrame = Camera.CFrame * CFrame.Angles(0, 0, -tilt + lerpedTilt + rad(Drift)) --* CFrame.new(lerpedSineX, lerpedSineY, 0)
Hum.CameraOffset = Vector3.new(lerpedSineX + 2.35, lerpedSineY + 0.51, -head_side)
previousSineX = lerpedSineX
previousSineY = lerpedSineY
previousTilt = lerpedTilt
else
Player.CameraMode = Enum.CameraMode.LockFirstPerson
Player.CameraMaxZoomDistance = 0
Player.CameraMinZoomDistance = 0
Camera.CFrame = Camera.CFrame * CFrame.Angles(0, 0, -tilt + lerpedTilt + rad(Drift)) --* CFrame.new(lerpedSineX, lerpedSineY, 0)
Hum.CameraOffset = Vector3.new(lerpedSineX, lerpedSineY + 0.51, -head_side)
previousSineX = lerpedSineX
previousSineY = lerpedSineY
previousTilt = lerpedTilt
end
end)
UIS.InputBegan:Connect(function(input, proccesed)
if proccesed then return end
if input.KeyCode == Enum.KeyCode.Q then
_G.ThirdPerson = not _G.ThirdPerson
end
end)