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
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?
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