How could I possibly make a dizzy screen effect?

I want to have a dizzy screen effect for my game (Camera warping and distortion)
I have been using CFrame matrix in order to distort the frame, however I have been unable to make it transition gradually between each warp. Most attempts have resulted in the camera moving to 0,0,0. I have also tried tweening but that doesn’t seem to work.
If anyone could tell me how to transition between camera warps using the CFrame matrix that would be fantastic.

2 Likes

To clarify, I am relatively new to scripting.

1 Like

If you want to gradually progress something, you can use linear interpolation (lerp). Linear interpolation - Wikipedia

Also, realize there’s a difference between global space and local space when doing stuff with coordinates.

1 Like

Is this u want?


Put this in StarterPlayerScripts:

local CameraShaker = require(game.ReplicatedStorage.CameraShaker) -- Unneccessary, but u can remove it.

local TweenService = game:GetService("TweenService")
local RunService = game:GetService("RunService")
local Players = game:GetService("Players")

local camera = workspace.CurrentCamera
local player = Players.LocalPlayer

local character = player.Character or player.CharacterAdded:Wait()
local rootPart = character:WaitForChild("HumanoidRootPart")

local spinRadius = 10
local distortionIntensity = 0.2 
local duration = 3

local camShake = CameraShaker.new(Enum.RenderPriority.Camera.Value + 1, function(shakeCFrame)
	camera.CFrame = camera.CFrame * shakeCFrame
end)
camShake:Start()
camShake:ShakeSustain(CameraShaker.Presets.BadTrip)

local tweenInfo = TweenInfo.new(duration, Enum.EasingStyle.Linear, Enum.EasingDirection.InOut, -1, false)

local function updateCamera()
	if not rootPart then return end

	local targetPosition = rootPart.Position
	local startCFrame = CFrame.new(targetPosition + Vector3.new(spinRadius, 2, 0), targetPosition)

	local spinTween = TweenService:Create(
		camera,
		tweenInfo,
		{CFrame = startCFrame * CFrame.Angles(0, math.rad(360), 0)}
	)
	spinTween:Play()
end

RunService.RenderStepped:Connect(function()
	if not rootPart then return end

	updateCamera()

	local distortionFactor = math.sin(workspace.DistributedGameTime * math.pi / duration) * distortionIntensity
	local distortionMatrix = CFrame.new(
		0, 0, 0,
		1, distortionFactor, 0,
		distortionFactor, 1, 0,
		0, 0, 1   
	)

	camera.CFrame = camera.CFrame * distortionMatrix
end)

player.CharacterAdded:Connect(function(newCharacter)
	character = newCharacter
	rootPart = character:WaitForChild("HumanoidRootPart")
	updateCamera()
end)