local function m(m)for o=1,#KEY_MAPPINGS[m],1 do if UIS:IsKeyDown(KEY_MAPPINGS[m][o])then return true end end return false end local o do local j=.016666666666667 RS.RenderStepped:Connect(function(m)j=m end)function o()local o=camera.CFrame local h=(m(DIRECTION_RIGHT)and 1 or 0)-(m(DIRECTION_LEFT)and 1 or 0)local F=(m(DIRECTION_UP)and 1 or 0)-(m(DIRECTION_DOWN)and 1 or 0)local y=(m(DIRECTION_BACKWARD)and 1 or 0)-(m(DIRECTION_FORWARD)and 1 or 0)local w=(h*h+F*F)+y*y if w>1e-15 then w=((UIS:IsKeyDown(Enum.KeyCode.LeftShift)or UIS:IsKeyDown(Enum.KeyCode.RightShift))and.25 or 1)/math.sqrt(w)h=h*w F=F*w y=y*w end local b=h+gp_x local u=(F+gp_r1)-gp_l1 local C=y+gp_z velSpring.t=Vector3.new(b,u,C)*SpeedModifier rotSpring.t=panDeltaMouse+panDeltaGamepad fovSpring.t=Clamp(fovSpring.t+(j*rate_fov)*FVEL_GAIN,5,120)local p=fovSpring:Update(j)local n=velSpring:Update(j)*LVEL_GAIN local c=rotSpring:Update(j)*((RVEL_GAIN*math.tan((p*math.pi)/360))*NM_ZOOM)rate_fov=0 panDeltaMouse=Vector2.new()stateRot=stateRot+c stateRot=Vector2.new(Clamp(stateRot.x,-1.5,1.5),stateRot.y)local K=((CFrame.new(o.p)*CFrame.Angles(0,stateRot.y,0))*CFrame.Angles(stateRot.x,0,0))*CFrame.new(n)camera.CFrame=K camera.Focus=K*FOCUS_OFFSET camera.FieldOfView=p end end


local function IsDirectionDown(direction)
	for i = 1, #KEY_MAPPINGS[direction] do
		if UIS:IsKeyDown(KEY_MAPPINGS[direction][i]) then
			return true
		end
	end
	return false
end

local UpdateFreecam do
	local dt = 1/60
	RS.RenderStepped:Connect(function(_dt)
		dt = _dt
	end)

	function UpdateFreecam()
		local camCFrame = camera.CFrame

		local kx = (IsDirectionDown(DIRECTION_RIGHT) and 1 or 0) - (IsDirectionDown(DIRECTION_LEFT) and 1 or 0)
		local ky = (IsDirectionDown(DIRECTION_UP) and 1 or 0) - (IsDirectionDown(DIRECTION_DOWN) and 1 or 0)
		local kz = (IsDirectionDown(DIRECTION_BACKWARD) and 1 or 0) - (IsDirectionDown(DIRECTION_FORWARD) and 1 or 0)
		local km = (kx * kx) + (ky * ky) + (kz * kz)
		if km > 1e-15 then
			km = ((UIS:IsKeyDown(Enum.KeyCode.LeftShift) or UIS:IsKeyDown(Enum.KeyCode.RightShift)) and 1/4 or 1)/math.sqrt(km)
			kx = kx * km
			ky = ky * km
			kz = kz * km
		end

		local dx = kx + gp_x
		local dy = ky + gp_r1 - gp_l1
		local dz = kz + gp_z

		velSpring.t = Vector3.new(dx, dy, dz) * SpeedModifier
		rotSpring.t = panDeltaMouse + panDeltaGamepad
		fovSpring.t = Clamp(fovSpring.t + dt * rate_fov*FVEL_GAIN, 5, 120)

		local fov  = fovSpring:Update(dt)
		local dPos = velSpring:Update(dt) * LVEL_GAIN
		local dRot = rotSpring:Update(dt) * (RVEL_GAIN * math.tan(fov * math.pi/360) * NM_ZOOM)

		rate_fov = 0
		panDeltaMouse = Vector2.new()

		stateRot = stateRot + dRot
		stateRot = Vector2.new(Clamp(stateRot.x, -3/2, 3/2), stateRot.y)

		local c = CFrame.new(camCFrame.p) * CFrame.Angles(0, stateRot.y, 0) * CFrame.Angles(stateRot.x, 0, 0) * CFrame.new(dPos)

		camera.CFrame = c
		camera.Focus = c*FOCUS_OFFSET
		camera.FieldOfView = fov
	end
end
