Camera TweenService Skewing doesn't work properly

Hey there, so I was playing around with camera skewing, (I believe another word for it is Camera Matrix), and I tried using tween service to make a cool effect to my game.

Here is my code:

local Run = game:GetService("RunService")

local Cam = game.Workspace.Camera
local MAGIC_FORMULA = CFrame.new(0, 0, 0, 1, 0.125, 0, 0, 1, 0, 0, 0, 1)
local MAGIC_FORMULA2 = CFrame.new(0, 0, 0, 1, -0.125, 0, 0, 1, 0, 0, 0, 1)
local tweenservice = game:GetService("TweenService")
local movecamera1 = tweenservice:Create(Cam, TweenInfo.new(4, Enum.EasingStyle.Exponential, Enum.EasingDirection.Out),{CFrame = Cam.CFrame * MAGIC_FORMULA})
local movecamera2 = tweenservice:Create(Cam, TweenInfo.new(4, Enum.EasingStyle.Exponential, Enum.EasingDirection.Out),{CFrame = Cam.CFrame * MAGIC_FORMULA2})

--Run.RenderStepped:Connect(function()
--	Cam.CFrame = Cam.CFrame * MAGIC_FORMULA
--end)

while true do
	movecamera1:Play()
	wait(4)
	movecamera2:Play()
	wait(4)
end

For some reason, this doesn’t work, instead it gives me this result:

The result I want would look like this:

Obviously, this wouldn’t be anyway close to how I want it considering I’m dragging a slider to make this happen, but I like the look of the effect using tweenservice (to make it more smooth).

Any way to help me achieve this?

2 Likes

i have tested and played around with those settings and it turns out that

1 you have to set camera type to scriptable to use any Camera CFrames properly
2 you cannot use tweenservice for the matrix to work properly. With tween Service you only rotate the camera instead of skewing it

This means that you have to make your animation from scratch using some formulas to make easing styles

2 Likes

Thank you for your response. I forgot about CameraTypes until you mentioned it.

Sad that matrix doesn’t work properly with TweenService, do you know any way to counter this and allow smooth flowing of the camera matrix using anything other than TweenService? (edit: without using complicated formulas)

1 Like

This will help

The creation of bezier curves is basically the same algorithm used for animations
you have a start point, and end point, and a completion factor (scaled form 0 to 1) also noted as T
all you have to do for the animation to play is change the T variable over time

2 Likes

I’ve heard and used Bezier curves before, so this should be in my understanding, thank you for your response.

2 Likes

i have messed around with the code and made this masterpiece

local Run = game:GetService("RunService")

local Cam = game.Workspace.CurrentCamera
Cam.CameraType = Enum.CameraType.Scriptable
--carefull, as of now you should put here only the difference between EndCFrame and StartCframe
local MAGIC_FORMULA = CFrame.new(0, 0, 0, 0, 0.125, 0, 0, 0, 0, 0, 0, 0)
local MAGIC_FORMULA2 = CFrame.new(0, 0, 0, 0, -0.125, 0, 0, 0, 0, 0, 0, 0)
--End of warning
local tweenservice = game:GetService("TweenService")

local function addCF(CF1, CF2)
	local x1,y1,z1, r001,r011,r021, r101,r111,r121, r201,r211,r221= CF1:GetComponents()
	local CF1 = {x1,y1,z1, r001,r011,r021, r101,r111,r121, r201,r211,r221}
	local x2,y2,z2, r002,r012,r022, r102,r112,r122, r202,r212,r222 = CF2:GetComponents()
	local CF2 = {x2,y2,z2, r002,r012,r022, r102,r112,r122, r202,r212,r222}
	
	local addedCF = {}
	for index, item in ipairs(CF1) do
		table.insert(addedCF,(CF2[index]+item))
	end
	
	local compiledNCF = CFrame.new(
		addedCF[1],
		addedCF[2],
		addedCF[3],

		addedCF[4],
		addedCF[5],
		addedCF[6],

		addedCF[7],
		addedCF[8],
		addedCF[9],

		addedCF[10],
		addedCF[11],
		addedCF[12]

	)
	return compiledNCF
end


local function getFrame(StartCFrame:CFrame, EndCFrame:CFrame, Completion)
	local x1,y1,z1, r001,r011,r021, r101,r111,r121, r201,r211,r221= StartCFrame:GetComponents()
	local CF1 = {x1,y1,z1, r001,r011,r021, r101,r111,r121, r201,r211,r221}
	local x2,y2,z2, r002,r012,r022, r102,r112,r122, r202,r212,r222 = EndCFrame:GetComponents()
	local CF2 = {x2,y2,z2, r002,r012,r022, r102,r112,r122, r202,r212,r222}
	local normalizedCFrame = {}
	for index, item in ipairs(CF1) do
		table.insert(normalizedCFrame,(CF2[index]-item)*Completion)
	end

	local compiledNCF = CFrame.new(
		normalizedCFrame[1]+CF1[1],
		normalizedCFrame[2]+CF1[2],
		normalizedCFrame[3]+CF1[3],
		
		normalizedCFrame[4]+CF1[4],
		normalizedCFrame[5]+CF1[5],
		normalizedCFrame[6]+CF1[6],
		
		normalizedCFrame[7]+CF1[7],
		normalizedCFrame[8]+CF1[8],
		normalizedCFrame[9]+CF1[9],
		
		normalizedCFrame[10]+CF1[10],
		normalizedCFrame[11]+CF1[11],
		normalizedCFrame[12]+CF1[12]
		
	)
	return compiledNCF
end

local tween = function(Target:Camera, CF1:CFrame, CF2:CFrame, Time, timeStep)
	local TIMESTEP = timeStep or 0.05
	local steps = Time/TIMESTEP
	
	for step = 0, steps, 1 do
		local CF = getFrame(CF1, CF2, 1/steps*step)
		print(CF)
		Target.CFrame = CF
		task.wait(TIMESTEP)
	end
end


Cam.CFrame = CFrame.new(0,0,0)


while true do
	tween(Cam, Cam.CFrame, addCF(Cam.CFrame, MAGIC_FORMULA), 4)

	tween(Cam, Cam.CFrame, addCF(Cam.CFrame, MAGIC_FORMULA2), 4)

	print(Cam.CFrame)
end

hope this gives you a headstart

now it’s up to you to implement it into a proper visual effect

1 Like

also use task.wait so that you are up-to-date with the services
(do not use deprecated stuff :slight_smile: )

1 Like

Holy, thanks for this, this should help a lot.

1 Like