So as the title suggests, i am trying to make a little nigthmares inspired camera system, the correct term for it would “Camera Rail.” I have the script for it, and it works, Kind of…
Whats the problem?
See the script follows the rail for a short while, and works just as intended, but then, it stops when its not even near the end! I have tried everything and nothing on the dev forum has helped, i even used chatgpt and it didnt work!
Here’s my script:
local player = game.Players.LocalPlayer
local character = player.Character or player.CharacterAdded:Wait()
local camera = game.Workspace.CurrentCamera
local rail = workspace:FindFirstChild("CameraRail")
local railPoints = {}
for _, part in ipairs(rail:GetChildren()) do
table.insert(railPoints, part.Position)
end
table.sort(railPoints, function(a, b)
return a.Z < b.Z
end)
local TweenService = game:GetService("TweenService")
local tweenInfo = TweenInfo.new(1, Enum.EasingStyle.Sine, Enum.EasingDirection.Out)
local function followRail()
local closestPoint = railPoints[1]
local characterPosition = character.PrimaryPart.Position
for _, point in ipairs(railPoints) do
if (characterPosition - point).Magnitude < (characterPosition - closestPoint).Magnitude then
closestPoint = point
end
end
if closestPoint then
camera.CameraType = Enum.CameraType.Scriptable
local goalCFrame = CFrame.new(closestPoint + Vector3.new(0, 5, 0), characterPosition)
local tween = TweenService:Create(camera, tweenInfo, {CFrame = goalCFrame})
tween:Play()
else
warn("No closest point found on the rail!")
end
end
game:GetService("RunService").RenderStepped:Connect(followRail)
A smooth transition between parts without skipping or snapping backwards.
To stop only while it’s at the end part and not at some random part.
To follow the rail as is, because some parts in my rail go up and down, front and back, and i want it to follow the whole rail.
*Keep following the player no matter what, as in keep looking at the player as it moves along the rail.
How can i achieve it?
That’s where you guys come in! I don’t want full fledged scripts, i simply would like some advice or some Assitance on it, i don’t have much robux so i cannot hire anybody, but please help! Thanks in advance.
if you have anymore questions about the game my discord is dizzytwisted
I think the issue is you move the camera to the nearest part once, then after the tween ends, nothing else happens. Try to do it in a repeated function instead, where it moves the camera every time the tween ends:
local function moveCamera()
for _, point in ipairs(railPoints) do
if (characterPosition - point).Magnitude < (characterPosition - closestPoint).Magnitude then
closestPoint = point
end
end
if closestPoint then
camera.CameraType = Enum.CameraType.Scriptable
local goalCFrame = CFrame.new(closestPoint + Vector3.new(0, 5, 0), characterPosition)
local tween = TweenService:Create(camera, tweenInfo, {CFrame = goalCFrame})
tween:Play()
tween.Completed:Wait()
else
warn("No closest point found on the rail!")
end
end
for i, point in ipairs(railPoints) do
if i ~= #rail:GetChildren() then
moveCamera()
end
end
I’ve applied your script to mine and it still seems to stop at a certain point. Let me show you what it’s doing"
(Ignore the first bit, Im trying to get it to work properly)
But as you can see it’s still stopping at some random point that isn’t the end, when there more rail to move to… im so confused because it doesn’t give me any sort of error or warning.
--LocalScript in StarterPlayerScripts
local player = game.Players.LocalPlayer
local character = player.Character or player.CharacterAdded:Wait()
local TweenService = game:GetService("TweenService")
local rail = workspace:WaitForChild("CameraRail")
local camera = workspace.CurrentCamera
local tweenInfo = TweenInfo.new(1, Enum.EasingStyle.Sine, Enum.EasingDirection.Out, 0, false, 0)
local railPoints = {}
for i = 1, #rail:GetChildren() do
local part = rail:FindFirstChild("Part" .. string.format("%02d", i))
if part then table.insert(railPoints, part.Position) end
end
local function moveCamera()
for _, point in ipairs(railPoints) do
camera.CameraType = Enum.CameraType.Scriptable
local goalCFrame = CFrame.new(point + Vector3.new(0, 5, 0), point + Vector3.new(0, 0, 90)) --facing direction
local tween = TweenService:Create(camera, tweenInfo, {CFrame = goalCFrame})
tween:Play() task.wait(0.3) --play around with this for smoothness
end
end
moveCamera()
--points are named Part01 Part02 Part03 exc.. No "guessing" where to go next.
--Part001 Part002 would be; part=rail:FindFirstChild("Part"..string.format("%03d",i))
Yes, However! There will be instances where i want to deactivate the script, right, would it still go to the nearest part the chartacter is near once the script reactivates or will it stop working?
odd … works fine for me. It isn’t following the player however. path.wmv (583.1 KB)
I guess I missed “*Keep following the player no matter what.”
What do you mean by “follow the player” keep looking at them?
You may have to work with it a bit …
script
local player = game.Players.LocalPlayer
local character = player.Character or player.CharacterAdded:Wait()
local TweenService = game:GetService("TweenService")
local rail = workspace:WaitForChild("CameraRail")
local camera = workspace.CurrentCamera
local tweenInfo = TweenInfo.new(1, Enum.EasingStyle.Sine, Enum.EasingDirection.Out, 0, false, 0)
local railPoints = {}
for i = 1, #rail:GetChildren() do
local part = rail:FindFirstChild("Part" .. string.format("%02d", i))
if part then table.insert(railPoints, part.Position) end
end
local function moveCamera()
for _, point in ipairs(railPoints) do
if not character.PrimaryPart then return end
camera.CameraType = Enum.CameraType.Scriptable
local goalCFrame = CFrame.new(point + Vector3.new(0, 5, 0), character.PrimaryPart.Position)
local tween = TweenService:Create(camera, tweenInfo, {CFrame = goalCFrame})
tween:Play()
task.wait(0.33)
end
end
moveCamera()
No reason this shouldn’t be working as it is on my screen … It just follows the path of blocks size 1,1,1 spaced 10 studs apart. Now it keep looking at the player.
Possibly create your block in order … it sure isn’t going to read them in the order you see them, unless you made them that way or placed them in that way. Why I went for something with an order to it.
Here is a test showing what I was talking about, good luck.
task.wait(1)
local folder = game.Workspace:WaitForChild("CameraRail")
local children = folder:GetChildren()
table.sort(children, function(a, b) return a.Name < b.Name end)
for _, child in ipairs(children) do
print(child.Name)
end
My bad it will pull them out of order but this should fix that … like you were using.