Rolling Realistic Camera

So guys i have been trying for really long, to make a roll realistic system.

So what i wanted here its similar to this video, that when it rolls the camera follows the orientation.
And it looks like a real roll that you would see only on real life.

And i really wanted to achieve it.
IF possible please help :slight_smile:

The minute that appears the desired effect that i wanted is 0:25

--// Services
local Players = game:GetService("Players")
local UserInputService = game:GetService("UserInputService")
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local RunService = game:GetService("RunService")
local TweenService = game:GetService("TweenService")
local workspace = game:GetService("Workspace")

--// Player setup
local player = Players.LocalPlayer
local character = player.Character or player.CharacterAdded:Wait()
local humanoid = character:WaitForChild("Humanoid")
local rootPart = character:WaitForChild("HumanoidRootPart")
local head = character:WaitForChild("Head")
local animator = humanoid:WaitForChild("Animator")
local camera = workspace.CurrentCamera
local rolling = script:WaitForChild("rolling") -- BoolValue

--// Combo Manager
local ComboManager = require(ReplicatedStorage:WaitForChild("ComboManager"))

--// Config
local LAND_ANIM_ID = "rbxassetid://83986194549735"
local ANIM_SPEED = 1
local FORWARD_BOOST = 5
local BEFORE_THRESHOLD = 4
local AFTER_THRESHOLD = 1.5
local CAMERA_TWEEN_TIME = 0.5
local CAMERA_FOLLOW_TIME = 1
local ROLL_COOLDOWN = 5 -- seconds
local CAMERA_BLEND_BACK = 1.5 -- how long to blend back to normal
local BASE_FOV = 70
local ROLL_FOV = 85

--// State
local lastRPress = 0
local landingTrack
local cameraFollowing = false
local followTimer = 0
local canRoll = true
local wasFalling = false

--// Animation
local landingAnim = Instance.new("Animation")
landingAnim.AnimationId = LAND_ANIM_ID
landingTrack = animator:LoadAnimation(landingAnim)
landingTrack.Priority = Enum.AnimationPriority.Action4
landingTrack.Looped = false

-- Track R key presses
UserInputService.InputBegan:Connect(function(input, gameProcessed)
	if not gameProcessed and input.KeyCode == Enum.KeyCode.R then
		lastRPress = tick()
	end
end)

-- Landing logic
humanoid.StateChanged:Connect(function(_, newState)
	if newState == Enum.HumanoidStateType.Freefall then
		wasFalling = true
	end

	if newState ~= Enum.HumanoidStateType.Landed or not wasFalling then
		return
	end
	wasFalling = false

	local now = tick()
	local deltaBefore = now - lastRPress

	local function triggerRoll()
		if not canRoll or not rolling.Value then
			print("[LandingRoll] Roll blocked (Cooldown or BoolValue off)")
			return
		end

		canRoll = false
		print("[LandingRoll] Triggered roll")

		if not landingTrack.IsPlaying then
			landingTrack:Play()
			landingTrack:AdjustSpeed(ANIM_SPEED)
		end

		-- Boost forward
		local forward = rootPart.CFrame.LookVector * FORWARD_BOOST
		rootPart.AssemblyLinearVelocity = Vector3.new(forward.X, rootPart.AssemblyLinearVelocity.Y + 3, forward.Z)

		-- Hit combo
		ComboManager:AddHit(player)

		if script:FindFirstChild("Sound") then
			script.Sound:Play()
		end

		--- Camera roll logic using "Cam" part
		cameraFollowing = true
		camera.CameraType = Enum.CameraType.Scriptable

		--// === Camera follow for roll ===
		local camPart = character:WaitForChild("Cam")
		local rollAnim = landingTrack
		local rollDuration = rollAnim.Length
		local rollEnded = false

		camera.CameraType = Enum.CameraType.Scriptable
		TweenService:Create(camera, TweenInfo.new(0.25, Enum.EasingStyle.Sine), { FieldOfView = ROLL_FOV }):Play()

		-- follow Cam in real time
		local connection
		connection = RunService.RenderStepped:Connect(function()
			if rollEnded then
				connection:Disconnect()
				return
			end
			if camPart then
				camera.CFrame = camPart.CFrame
			end
		end)

		-- when animation stops
		rollAnim.Stopped:Connect(function()
			rollEnded = true
			local frozenCFrame = camera.CFrame
			camera.CameraType = Enum.CameraType.Scriptable
			camera.CFrame = frozenCFrame

			-- wait a bit before giving control back
			task.delay(CAMERA_BLEND_BACK, function()
				TweenService:Create(camera, TweenInfo.new(0.4), { FieldOfView = BASE_FOV }):Play()
				camera.CameraType = Enum.CameraType.Custom
			end)
		end)

		-- Roll cooldown
		task.delay(ROLL_COOLDOWN, function()
			canRoll = true
			print("[LandingRoll] Cooldown ended")
		end)
	end

	-- R pressed shortly before landing
	if deltaBefore > 0 and deltaBefore <= BEFORE_THRESHOLD then
		triggerRoll()
		return
	end

	-- Touch support
	if UserInputService.TouchEnabled then
		local DashGui = player:WaitForChild("PlayerGui"):WaitForChild("Dash")
		local Frame = DashGui:WaitForChild("Frame")
		local Btn = Frame:WaitForChild("FrontRoll")

		Btn.MouseButton1Click:Connect(function()
			if humanoid:GetState() == Enum.HumanoidStateType.Landed or humanoid:GetState() == Enum.HumanoidStateType.Running then
				triggerRoll()
			end
		end)
	end

	-- Wait for R press after landing
	local startTime = tick()
	local conn
	conn = UserInputService.InputBegan:Connect(function(input2, gp2)
		if gp2 then
			return
		end
		if input2.KeyCode == Enum.KeyCode.R and tick() - startTime <= AFTER_THRESHOLD then
			triggerRoll()
			if conn then
				conn:Disconnect()
			end
		end
	end)

	task.delay(AFTER_THRESHOLD, function()
		if conn and conn.Connected then
			conn:Disconnect()
		end
	end)
end)

Can you show me how it works for you?

1 Like

Sorry but i already fixed it, thank you so much tho, God bless bro.. sorry again.

2 Likes

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.