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
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.
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.
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.
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.
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
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!
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.