Загрузка данных


-- DOORS-style Camera Bob + Sprint FOV
-- LocalScript -> StarterPlayer -> StarterPlayerScripts

local Players = game:GetService("Players")
local RunService = game:GetService("RunService")

local player = Players.LocalPlayer

local RUN_SPEED = 24

local WALK_BOB_SPEED = 8
local RUN_BOB_SPEED = 12

local WALK_BOB_AMOUNT = 0.08
local RUN_BOB_AMOUNT = 0.14

local SIDE_AMOUNT = 0.035
local TILT_AMOUNT = 0.025

local SMOOTHNESS = 10

-- FOV settings
local NORMAL_FOV = 70
local SPRINT_FOV = 76
local FOV_SMOOTHNESS = 6

local character
local humanoid

local currentBob = Vector3.zero
local currentTilt = 0
local time = 0

local function setupCharacter(char)
	character = char
	humanoid = char:WaitForChild("Humanoid")
end

if player.Character then
	setupCharacter(player.Character)
end

player.CharacterAdded:Connect(setupCharacter)

RunService:BindToRenderStep(
	"DoorsCameraEffects",
	Enum.RenderPriority.Camera.Value + 1,
	function(deltaTime)

		local camera = workspace.CurrentCamera

		if not character or not humanoid or humanoid.Health <= 0 then
			return
		end

		local velocity = humanoid.RootPart
			and Vector3.new(
				humanoid.RootPart.AssemblyLinearVelocity.X,
				0,
				humanoid.RootPart.AssemblyLinearVelocity.Z
			).Magnitude
			or 0

		local moving = velocity > 1
		local sprinting = velocity >= RUN_SPEED - 2

		local bobSpeed
		local bobAmount

		if sprinting then
			bobSpeed = RUN_BOB_SPEED
			bobAmount = RUN_BOB_AMOUNT
		else
			bobSpeed = WALK_BOB_SPEED
			bobAmount = WALK_BOB_AMOUNT
		end

		-- Camera bob
		if moving then
			time += deltaTime * bobSpeed

			local y = math.sin(time * 2) * bobAmount
			local x = math.cos(time) * SIDE_AMOUNT
			local tilt = math.sin(time) * TILT_AMOUNT

			local targetBob = Vector3.new(x, y, 0)

			currentBob = currentBob:Lerp(
				targetBob,
				math.clamp(deltaTime * SMOOTHNESS, 0, 1)
			)

			currentTilt += (tilt - currentTilt)
				* math.clamp(deltaTime * SMOOTHNESS, 0, 1)
		else
			currentBob = currentBob:Lerp(
				Vector3.zero,
				math.clamp(deltaTime * SMOOTHNESS, 0, 1)
			)

			currentTilt += (0 - currentTilt)
				* math.clamp(deltaTime * SMOOTHNESS, 0, 1)
		end

		-- Sprint FOV
		local targetFOV = sprinting and SPRINT_FOV or NORMAL_FOV

		camera.FieldOfView +=
			(targetFOV - camera.FieldOfView)
			* math.clamp(deltaTime * FOV_SMOOTHNESS, 0, 1)

		camera.CFrame =
			camera.CFrame
			* CFrame.new(currentBob)
			* CFrame.Angles(0, 0, currentTilt)
	end
)