I want to be able to simply move my camera in all 4 directions with the Ui buttons but the camera needs to keeps its flat orientation at all times.
No matter what I do, I can never get the orientation of the camera to stay flat at all times.
I have attached a video.
I have already tried multiple different solutions such as having a loop always set the orientation.
I tried fixing this a couple months ago and got no where so I have just come back to it to see if I could fix it with no success.
local player = game.Players.LocalPlayer
local button = script.Parent.View
local Camera = workspace.CurrentCamera
local NextCam = script.Parent.Next
local PrevCam = script.Parent.Prev
local Left = script.Parent.Directional.Left
local Right = script.Parent.Directional.Right
local Up = script.Parent.Directional.Up
local Down = script.Parent.Directional.Down
local UserInputService = game:GetService("UserInputService")
local RunService = game:GetService("RunService")
local cameraCount = 0
local currentCameraIndex = 1
local cameras = {}
local initialOffset = CFrame.Angles(-math.rad(0), 0, 0)
for _, CameraModel in ipairs(game.Workspace.Cameras:GetDescendants()) do
if CameraModel:IsA("Model") and CameraModel.Name == "Camera" then
local cameraPart = CameraModel:FindFirstChild("Camera")
if cameraPart and cameraPart:IsA("BasePart") then
cameraCount = cameraCount + 1
local value = Instance.new("NumberValue")
value.Parent = CameraModel
value.Value = cameraCount
value.Name = "CameraNumber"
cameras[cameraCount] = cameraPart
end
end
end
local function switchToCamera(index)
if cameras[index] then
Camera.CameraType = Enum.CameraType.Scriptable
Camera.CFrame = cameras[index].CFrame * initialOffset
Camera.FieldOfView = 120
print("Switched to Camera " .. index)
else
warn("Camera " .. index .. " not found.")
end
end
local Viewing = false
local function synchronizeCamera()
while Viewing do
if cameras[currentCameraIndex] then
Camera.CFrame = cameras[currentCameraIndex].CFrame
end
wait()
end
end
local function rotateCamera(direction)
local rotationSpeed = math.rad(1)
if cameras[currentCameraIndex] then
local rotation = CFrame.new()
if direction == "Up" then
rotation = CFrame.Angles(-rotationSpeed, 0, 0)
elseif direction == "Down" then
rotation = CFrame.Angles(rotationSpeed, 0, 0)
elseif direction == "Right" then
rotation = CFrame.Angles(0, -rotationSpeed, 0)
elseif direction == "Left" then
rotation = CFrame.Angles(0, rotationSpeed, 0)
end
cameras[currentCameraIndex].CFrame = cameras[currentCameraIndex].CFrame * rotation
end
end
local function startRotate(direction)
local connection
connection = RunService.RenderStepped:Connect(function()
if UserInputService:IsMouseButtonPressed(Enum.UserInputType.MouseButton1) then
rotateCamera(direction)
else
connection:Disconnect()
end
end)
end
Up.MouseButton1Down:Connect(function()
startRotate("Up")
end)
Down.MouseButton1Down:Connect(function()
startRotate("Down")
end)
Right.MouseButton1Down:Connect(function()
startRotate("Right")
end)
Left.MouseButton1Down:Connect(function()
startRotate("Left")
end)
button.MouseButton1Click:Connect(function()
print("Clicked")
if Viewing then
Viewing = false
NextCam.Visible = false
PrevCam.Visible = false
Camera.CameraType = Enum.CameraType.Custom
Camera.FieldOfView = 70
print("Camera changed to Custom")
else
Viewing = true
NextCam.Visible = true
PrevCam.Visible = true
switchToCamera(currentCameraIndex)
synchronizeCamera()
end
end)
NextCam.MouseButton1Click:Connect(function()
if Viewing then
currentCameraIndex = currentCameraIndex % cameraCount + 1
switchToCamera(currentCameraIndex)
end
end)
You can use one of my previous solutions in this case.
This method uses spherical coordinates.
Just put the radius to zero (or omit it entirely).
Theta is left/right and phi is up/down This code is an example so you can understand how it works If you feel lazy (like me) you can also just copy it I don’t mind
local Players = game:GetService("Players")
local RunService = game:GetService("RunService")
local UserInputService = game:GetService("UserInputService")
local currentCamera = workspace.CurrentCamera
currentCamera.CameraType = Enum.CameraType.Scriptable
local subjectPosition = Vector3.new(0, 10, 0)
local sensitivity = 0.5
local radius = 0 -- You can also omit radius from the function but for ease of use it's put to 0
local theta = 0
local phi = 90
function SphericalCoordinate(r: number, theta: number, phi: number)
local Position = Vector3.new(
r * math.sin(phi) * math.cos(theta),
r * math.cos(phi),
r * math.sin(phi) * math.sin(theta)
)
local Hat_r = Vector3.new(
math.sin(phi) * math.cos(theta),
math.cos(phi),
math.sin(phi) * math.sin(theta)
)
local Hat_theta = Vector3.new(
-math.sin(theta),
0,
math.cos(theta)
)
local Hat_phi = Vector3.new(
math.cos(phi) * math.cos(theta),
-math.sin(phi),
math.cos(phi) * math.sin(theta)
)
return {
Position = Position,
UpVector = -Hat_phi,
LeftVector = Hat_theta,
FrontVector = -Hat_r,
DownVector = Hat_phi,
RightVector = -Hat_theta,
BackVector = Hat_r
}
end
UserInputService.InputBegan:Connect(function(input: InputObject, gameProcessedEvent: boolean)
if gameProcessedEvent then return end
if input.UserInputType ~= Enum.UserInputType.MouseButton2 then return end
UserInputService.MouseBehavior = Enum.MouseBehavior.LockCurrentPosition
end)
UserInputService.InputEnded:Connect(function(input: InputObject, gameProcessedEvent: boolean)
if gameProcessedEvent then return end
if input.UserInputType ~= Enum.UserInputType.MouseButton2 then return end
UserInputService.MouseBehavior = Enum.MouseBehavior.Default
end)
RunService.RenderStepped:Connect(function()
for index, value in pairs(UserInputService:GetKeysPressed()) do
if value.KeyCode == Enum.KeyCode.W then
phi = (phi + 2 * sensitivity) % 360
end
if value.KeyCode == Enum.KeyCode.A then
theta = (theta + -2 * sensitivity) % 360
end
if value.KeyCode == Enum.KeyCode.S then
phi = (phi + -2 * sensitivity) % 360
end
if value.KeyCode == Enum.KeyCode.D then
theta = (theta + 2 * sensitivity) % 360
end
end
local sphericalCoordinate = SphericalCoordinate(
radius,
theta * math.pi / 180,
phi * math.pi / 180
)
currentCamera.CFrame = CFrame.fromMatrix(
sphericalCoordinate.Position + subjectPosition,
sphericalCoordinate.RightVector,
sphericalCoordinate.UpVector,
sphericalCoordinate.BackVector
)
end)
Previous posts
Hope this is what you were looking for.
If you have any questions feel free to ask me. Hope you have a good day/night!