Struggling to edit camera's ROTATION while allowing camera movement

i have a really cool recoil system that’s supposed to tilt the camera, and then recover
both of these actions are lerped

this is what the final product is supposed to look like
(i’m setting the cframe directly in the video, so camera movement is entirely blocked)


in order to allow mouse movement while lerping the camera, i need to do:
camera.CFrame *= offset, NOT camera.CFrame = CFrame.new(camera.CFrame.Position) * offset, because the second option is setting the cframe directly, which blocks camera movement

i’m actually struggling to get this to work, because i can’t just multiply Rotation of CFrame, since it’s read-only, and multiplying the CFrame by the offset directly just does this:


i very much need help, yes i very much tried using ai

local function ApplyRecoil(recoilStrength: CFrame)
	local recoilTweak: NumberValue = utility.GetGameplayValue('recoilTweak')	
	local tiltDuration = 0.15
	local recoveryDuration = 0.25

	local elapsed = 0
	local applying = true
-- totally not ai generated code
	local axis, angle = recoilStrength:ToAxisAngle()
	angle = angle / recoilTweak.Value

	local initialRotation = camera.CFrame - camera.CFrame.Position
	local targetRotation = initialRotation * CFrame.fromAxisAngle(axis, angle)

	rService:BindToRenderStep('Recoil', Enum.RenderPriority.Camera.Value, function(deltaTime)
		elapsed += deltaTime

		local alpha
		local currentRotation

		if applying then
			alpha = math.clamp(elapsed / tiltDuration, 0, 1)
			currentRotation = initialRotation:Lerp(targetRotation, alpha)

			if alpha >= 1 then
				applying = false
				elapsed = 0
			end
		else
			alpha = math.clamp(elapsed / recoveryDuration, 0, 1)
			currentRotation = targetRotation:Lerp(initialRotation, alpha)

			if alpha >= 1 then
				rService:UnbindFromRenderStep('Recoil')
			end
		end

		camera.CFrame *= CFrame.Angles(math.rad(15), 0, 0) -- pretend  currentRotation is here
	end)
end

i am open to literally everything

1 Like

wont even lie i pasted your code to chatgpt heres what it said to do for
camera.CFrame setting

camera.CFrame = currentRotation + camera.CFrame.Position

i forgot i made this topic lol
i fixed it

local function ApplyDeltaRotation(currentX, currentY, currentZ, lastX, lastY, lastZ)
	local deltaX = currentX - lastX
	local deltaY = currentY - lastY
	local deltaZ = currentZ - lastZ

	local deltaRotation = CFrame.Angles(deltaX, deltaY, deltaZ)
	camera.CFrame *= deltaRotation

	return currentX, currentY, currentZ
end

local function ApplyRecoil(recoilStrength: CFrame)
	local recoilTweak: NumberValue = utility.GetGameplayValue('recoilTweak')	
	local tiltDuration = 0.15
	local recoveryDuration = 0.25

	local elapsed = 0
	local applying = true
	local renderStepped: RBXScriptConnection = nil
	local lastX, lastY, lastZ = 0, 0, 0
	
	if renderStepped then
		renderStepped:Disconnect()
	end
	
	local x, y, z = recoilStrength:ToEulerAnglesXYZ()
	x /= recoilTweak.Value
	y /= recoilTweak.Value
	z /= recoilTweak.Value
	
	renderStepped = rService.RenderStepped:Connect(function(deltaTime)
		local alpha

		if applying then
			alpha = math.clamp(elapsed / tiltDuration, 0, 1)

			if alpha >= 1 then
				applying = false
				elapsed = 0
			end
		else
			alpha = 1 - math.clamp(elapsed / recoveryDuration, 0, 1)

			if alpha <= 0 then
				local removeX = -lastX
				local removeY = -lastY
				local removeZ = -lastZ
				local removeRotation = CFrame.Angles(removeX, removeY, removeZ)
				
				camera.CFrame *= removeRotation
				renderStepped:Disconnect()
				return
			end
		end
		
		local currentX = x * alpha
		local currentY = y * alpha
		local currentZ = z * alpha
		
		local currentX = x * alpha
		local currentY = y * alpha
		local currentZ = z * alpha

		lastX, lastY, lastZ = ApplyDeltaRotation(currentX, currentY, currentZ, lastX, lastY, lastZ)
		elapsed += deltaTime
	end)
end
2 Likes

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