[SOLVED] How would I add in this gradient?

Hello all! Check out this video right here of my interpolative camera.

My goal is to make like red edge gradients appear when you reach the edge of the camera.

How could I do this?

This is my interpolative camera script that is inside of StarterPlayerScripts

local Player = game.Players.LocalPlayer
local Character = Player.Character or Player.CharacterAdded:Wait()
local Camera = workspace.CurrentCamera

-- Set the camera type to Scriptable
Camera.CameraType = Enum.CameraType.Scriptable

-- Get the player's mouse
local Mouse = Player:GetMouse()

-- Function to set the camera to the CameraPart's position and follow the mouse smoothly
local function updateCamera()
	local cameraPart = workspace:WaitForChild("CameraPart") -- Get the CameraPart
	if cameraPart then
		-- Set camera position above the CameraPart
		local targetPosition = cameraPart.Position + Vector3.new(0, 5, 0)

		-- Get mouse direction to adjust camera rotation
		local mouseDirection = Mouse.UnitRay.Direction

		-- Calculate the forward direction based on the character's look direction
		local forwardDirection = Character.HumanoidRootPart.CFrame.LookVector

		-- Calculate the camera's look at position, blending mouse direction with forward direction
		local cameraLookAt = cameraPart.Position + (forwardDirection + mouseDirection).Unit * 10 -- Adjust distance as needed

		-- Smoothly interpolate the camera position and rotation
		Camera.CFrame = Camera.CFrame:Lerp(CFrame.new(targetPosition, cameraLookAt), 0.1)
	end
end

-- Call the function once at the start
updateCamera()

-- Continuous update loop to keep the camera on the CameraPart and follow the mouse
while true do
	updateCamera()
	wait(0.03) -- Adjust the wait time for smoother movement; lower values yield smoother motion
end

And this is my script for the gradient updater that looks like this
sss

local Player = game.Players.LocalPlayer
local Mouse = Player:GetMouse()
local Camera = workspace.CurrentCamera
local GradientFrame = Player.PlayerGui:WaitForChild("GradientGui"):WaitForChild("GradientFrame")
local UIGradient = GradientFrame:WaitForChild("UIGradient")

-- Function to update the gradient transparency based on camera edges
local function updateGradient()
	while true do
		-- Get the size of the screen
		local screenSize = GradientFrame.AbsoluteSize
		local center = Vector2.new(screenSize.X / 2, screenSize.Y / 2)

		-- Get the camera's viewport dimensions
		local viewportSize = Camera.ViewportSize

		-- Calculate the distance from the mouse to the center of the viewport
		local mousePosition = Vector2.new(Mouse.X, Mouse.Y)
		local distanceToCenter = (mousePosition - center).Magnitude

		-- Normalize distance to a value between 0 and 1 based on the screen size
		local maxDistance = math.max(viewportSize.X, viewportSize.Y) * 0.5
		local normalizedDistance = math.clamp(distanceToCenter / maxDistance, 0, 1)

		-- Update UIGradient transparency based on distance
		UIGradient.Transparency = NumberSequence.new({
			NumberSequenceKeypoint.new(0, 0),             -- Fully opaque at the center
			NumberSequenceKeypoint.new(0.5, normalizedDistance), -- Gradually transparent at the midpoint
			NumberSequenceKeypoint.new(1, 1)               -- Fully transparent at the edge
		})

		wait(0.03) -- Update every frame
	end
end

-- Start updating the gradient
updateGradient()


How could I update this to work like I need it to? I’d imagine i’d somehow need to identify the coordinates of the edges somehow.

1 Like

Thank you to all who are currently helping, one of the problems I ran into was attempting to define the edges of the camera, because all of them ended up with me having a buggy and glitchy camera. I think the first step here is to define the edges of the camera somehow and maybe to create a minimum and maximum to make the gradient part of it work together seamlessly.

I can work with you guys to try and find out that.

This is my updated script, but the result is this:

local Player = game.Players.LocalPlayer
local Character = Player.Character or Player.CharacterAdded:Wait()
local Camera = workspace.CurrentCamera

-- Set the camera type to Scriptable
Camera.CameraType = Enum.CameraType.Scriptable

-- Get the player's mouse
local Mouse = Player:GetMouse()

-- Define minimum and maximum distances for camera movement
local minDistance = 5  -- Adjust as needed
local maxDistance = 15 -- Adjust as needed

-- Define rotation limits
local minRotationY = -30  -- Minimum rotation angle
local maxRotationY = 30   -- Maximum rotation angle

-- Function to set the camera to the CameraPart's position and follow the mouse smoothly
local function updateCamera()
	local cameraPart = workspace:WaitForChild("CameraPart") -- Get the CameraPart
	if cameraPart then
		-- Set camera position above the CameraPart
		local targetPosition = cameraPart.Position + Vector3.new(0, 5, 0)

		-- Get mouse direction to adjust camera rotation
		local mouseDirection = Mouse.UnitRay.Direction

		-- Calculate the forward direction based on the character's look direction
		local forwardDirection = Character.HumanoidRootPart.CFrame.LookVector

		-- Calculate the camera's look at position, blending mouse direction with forward direction
		local cameraLookAt = cameraPart.Position + (forwardDirection + mouseDirection).Unit * 10 -- Adjust distance as needed

		-- Calculate the distance from the camera part to the camera
		local cameraDistance = (Camera.CFrame.Position - cameraPart.Position).Magnitude

		-- Clamp the camera distance to the defined min and max distances
		cameraDistance = math.clamp(cameraDistance, minDistance, maxDistance)

		-- Set the camera's new position while keeping it at the defined distance
		local newCameraPosition = cameraPart.Position + (cameraLookAt - cameraPart.Position).Unit * cameraDistance

		-- Clamp the rotation based on the Y-axis limits
		local newCameraLookAt = CFrame.new(newCameraPosition, cameraLookAt)
		local rotationY = math.clamp(newCameraLookAt:ToEulerAnglesYXZ() * (180 / math.pi), math.rad(minRotationY), math.rad(maxRotationY))

		-- Smoothly interpolate the camera position and rotation
		Camera.CFrame = Camera.CFrame:Lerp(CFrame.new(newCameraPosition) * CFrame.Angles(0, rotationY, 0), 0.1)
	end
end

-- Call the function once at the start
updateCamera()

-- Continuous update loop to keep the camera on the CameraPart and follow the mouse
while true do
	updateCamera()
	wait(0.03) -- Adjust the wait time for smoother movement; lower values yield smoother motion
end

What is wrong here?
Let’s focus on finding the coordinates of the rotation, and making a minumum and maximum for that first.

Anybody have any updates? Sorry for the trouble.

Are you looking for something like this?


forgot the video at first

What I did to achieve this was I got the center of the screen using camera.ViewportSize through this vector:

Vector2.new(Camera.ViewportSize.X / 2, Camera.ViewportSize.Y / 2)

After which I grabbed the mouse’s on screen position which I then used magnitude to get the distance from the center:

(Vector2.new(Mouse.X, Mouse.Y) - CenterVector).Magnitude

To make sure I got a value between 0 and 1 to multiply the transparency of the gradient by I also got the maximum distance the cursor could be from the center of the screen through this equation:

(Vector2.new() - CenterVector).Magnitude

The reason we do a blank Vector2 is because this is basically the top left corner of the screen which is as far as the cursor can be from the center of the screen.

After putting everything together you can use a default transparency variable and multiply it by the math we just did.

DefaultTransparency * (MaximumDistance / DistanceFromCenter)

This equation gives us a transparency value based on the distances we just checked!

If this is not your desired effect please let me know and I’ll see what I can do.

This is exactly what I’m looking for, I will talk more next Saturday.

2 Likes

Though there are a few changes to that I’d want to make, 1. I want the only side of which the player is closest to to be showing up red 2. Could you tell me how you made that gradient, it looks nice.

Other than that it looks great, lemme rewrite my scripts on Saturday and we’ll see if it works correctly, thanks for your help, and by the way, don’t do this if you don’t want to, but could you show me the scripts you use for it? That way I won’t have to debug for 2.5 hours like last time. Thank you and have a good week.

I am able to talk for a little bit here @1O10010I10011, so do you think this is possible?

Sorry for the delay, the gradient is a vignette image I used.

For this case, I think you should add a new gradient under a vignette image like the one I made using an ImageLabel. Then, add a UIGradient object under the ImageLabel, which you can use the transparency to alter which side shows. Since this only lets us change left to right, not up and down, we can use the rotation property.

To use this property for this case, you can use some math to get the direction the cursor is from the center of the screen and convert it to 2D rotation. I don’t have the time to find exactly how to calculate this right now, but I’m sure you can find out how.

Afterwards you can simply set the transparency to a NumberSequence and plug the transparency value we found earlier into the sequence.

All of this together should give you your desired effect.

How would I make the gradient effect, I have been trying for a long time, could you show me where you got your vignette image? I cannot figure this out :frowning:

Nevermind, I figured out, I somehow forgot about NumberSequences…

Thanks for your help man! I figured it out using this script, and not editing the other one.

local player = game.Players.LocalPlayer
local camera = workspace.CurrentCamera
local mouse = player:GetMouse()
local RunService = game:GetService("RunService")

-- Vignette frames
local vignetteGui = player.PlayerGui:WaitForChild("Vignette")
local bottomVignette = vignetteGui:WaitForChild("BottomVignette")
local topVignette = vignetteGui:WaitForChild("TopVignette")
local leftVignette = vignetteGui:WaitForChild("LeftVignette")
local rightVignette = vignetteGui:WaitForChild("RightVignette")

-- Set initial transparency to fully transparent
bottomVignette.BackgroundTransparency = 1
topVignette.BackgroundTransparency = 1
leftVignette.BackgroundTransparency = 1
rightVignette.BackgroundTransparency = 1

-- Default transparency and distance threshold
local defaultTransparency = 0.5 -- Set the default transparency level (0 is fully opaque)
local sparkDistance = 100 -- Distance from edge at which the vignette starts to become opaque
local fadeSpeed = 0.1 -- Speed of the fade effect

-- Function to update vignette transparency based on mouse position
local function updateVignetteTransparency()
	local mousePosition = Vector2.new(mouse.X, mouse.Y)
	local screenSize = camera.ViewportSize

	-- Calculate distances from the mouse to each edge of the screen
	local distances = {
		Bottom = screenSize.Y - mousePosition.Y,  -- Distance to the bottom edge
		Top = mousePosition.Y,                      -- Distance to the top edge
		Left = mousePosition.X,                     -- Distance to the left edge
		Right = screenSize.X - mousePosition.X     -- Distance to the right edge
	}

	-- Initialize target transparency values
	local targetTransparency = {
		Bottom = 1,
		Top = 1,
		Left = 1,
		Right = 1
	}

	-- Determine closest edge and calculate transparency based on proximity
	for edge, distance in pairs(distances) do
		if distance <= sparkDistance then
			-- Calculate the target transparency based on distance
			local proximityFactor = distance / sparkDistance
			targetTransparency[edge] = math.clamp(defaultTransparency * proximityFactor, 0, 1)
		else
			targetTransparency[edge] = 1 -- Fully transparent if not within spark distance
		end
	end

	-- Fade in effect
	bottomVignette.BackgroundTransparency = bottomVignette.BackgroundTransparency + (targetTransparency.Bottom - bottomVignette.BackgroundTransparency) * fadeSpeed
	topVignette.BackgroundTransparency = topVignette.BackgroundTransparency + (targetTransparency.Top - topVignette.BackgroundTransparency) * fadeSpeed
	leftVignette.BackgroundTransparency = leftVignette.BackgroundTransparency + (targetTransparency.Left - leftVignette.BackgroundTransparency) * fadeSpeed
	rightVignette.BackgroundTransparency = rightVignette.BackgroundTransparency + (targetTransparency.Right - rightVignette.BackgroundTransparency) * fadeSpeed

	-- Debugging Output
	print("Vignette Transparency - Bottom:", bottomVignette.BackgroundTransparency)
	print("Vignette Transparency - Top:", topVignette.BackgroundTransparency)
	print("Vignette Transparency - Left:", leftVignette.BackgroundTransparency)
	print("Vignette Transparency - Right:", rightVignette.BackgroundTransparency)
end

-- Update loop
RunService.RenderStepped:Connect(updateVignetteTransparency)

Your things up top helped me out so much! Congrats for figuring it out man, you did great!

1 Like

Sorry again for the delay, I don’t check devforum that often anymore. This is the vignette image I used to achieve the effect since Roblox doesn’t have radial gradients for whatever reason.

Thank you so much for your help again, you really helped me out.

1 Like