CFrame not applying to CurrentCamera

So I’m trying to make a camera tilt system so that whenever you move right, your camera tilts right and vice versa. I have all of my tweens set up and I assigned the Part to “CurrentCamera” for each, but it moves the camera to the center of the world when the tween plays. I assume the problem is that it plays relative to the world instead of relative to where the current camera is but I haven’t a clue on how to change what a CFrame is relative to. If anyone can help it would be greatly appreciated :slight_smile:

local CC = workspace.CurrentCamera
local tiltTweenInfo = TweenInfo.new(0.3, Enum.EasingStyle.Linear, Enum.EasingDirection.Out)
local AtiltTweenBegin = TweenService:Create(CC, tiltTweenInfo, {CFrame = CC.CFrame * CFrame.Angles(0,0,math.rad(5))})
local DtiltTweenBegin = TweenService:Create(CC, tiltTweenInfo, {CFrame = CC.CFrame * CFrame.Angles(0,0,math.rad(-5))})
local tiltTweenEnd = TweenService:Create(CC, tiltTweenInfo, {CFrame = CC.CFrame * CFrame.Angles(0,0,0)})

I don’t see anything wrong here. You setting the CameraType to Scriptable? If not, try that first. If it doesn’t work, could you show your full script, especially the part that plays the tweens?

Edit: actually, you’re making the tween when the camera’s at the origin probably, so as soon as you’re creating the tween it becomes relative to the CFrame when the tween is created.

So I moved each tween inside of their respective functions, but now the camera freezes in place until it completes the tween. I looked up if this could be done with CameraOffset but sadly it can’t. Do you know if there’s a way to make the camera follow the player while the tween plays, or maybe rotate the camera using vector3?

Late response, sorry.

If you’re just looking to update the camera’s CFrame on a single rotation axis, I think you’d have to interpolate it manually which isn’t as hard as it sounds, this can be done with easing styles as well using TweenService:GetValue(). I’m not 100% sure what you’re looking for but based on your code I’ll make you a demo.

It’s a bit messy but (I think) it does what you want:

local runService = game:GetService('RunService')
local tweenService = game:GetService('TweenService')

local camera = workspace.CurrentCamera

local timeToTween = 0.3 -- time the camera takes to move from the start to the end position
local easingStyle = Enum.EasingStyle.Linear -- easing style
local easingDirection = Enum.EasingDirection.InOut -- easing direction

local currentTime = 0 -- we need this to know how much we should interpolate the camera by, it's just the time since the script has started

local lowerBoundOrientation = CFrame.Angles(0, 0, math.rad(-5)) -- lower camera boundary
local upperBoundOrientation = CFrame.Angles(0, 0, math.rad(5)) -- upper camera boundary

runService:BindToRenderStep('CameraTilt', Enum.RenderPriority.Camera.Value + 1, function(delta)
	currentTime += delta -- now, this will add the time between the last RenderStep and the current RenderStep to the currentTime
	local difference = (currentTime % (timeToTween * 2)) / timeToTween -- * 2 to account for both directions, and basically the % of completion of movement I guess
	local shouldMoveBack = math.floor(difference) % timeToTween == 0 -- if its 0 then it should move back from the upper to the lower, else move from lower to upper
	local alpha = difference % 1 -- value to provide to the interpolation function
	alpha = tweenService:GetValue(shouldMoveBack and alpha or math.abs(1 - alpha), easingStyle, easingDirection) -- this is the actual alpha to provide to CF:Lerp
	camera.CFrame *= lowerBoundOrientation:Lerp(upperBoundOrientation, alpha) -- and finally our final CFrame
end)

Isn’t this just because you’re creating the tweens at the top (thus making the CFrame target predeterimined)? Try creating them when you need them instead.

this is the exact effect i’m trying to achieve, thank you so much. quick question, can this be done without the function being connected to RenderStepped? I’m trying to do this but it only plays once when you strafe left or right. Thx

Yeah you should be able to, you’d have to use a RunService event that is fired after the camera is updated though, think Heartbeat works.