Hello! I’ve recently made a custom camera script, and with it there’s custom turning that allows the player to look around in a small area around themselves. Thing is, with this camera, whenever the character looks in diagonal directions, the camera seems to tilt a bit.
robloxapp-20210908-1707444.wmv (1.4 MB)
[Apologies for the low quality video]
As shown in the video, the camera seems to tilt, and I’d like to see if there’s a way to have it replicate the normal roblox camera a bit more. I’m assuming how I’d fix this would be by adding a math equation to the z coordinate of the CFrame.Angles that would accommodate for both the x and y.
--The line that determines the angle of the camera. As you can see the z coordinate isn't changed.
Camera.CFrame = Camera.CFrame * CFrame.Angles(-DistanceY/TurnConstraint,-DistanceX/TurnConstraint,0)
How would I be able to accomplish this? Any help would be appreciated. Below is the full camera script so you can get a better understanding of how the camera works.
--Variables that you can edit to your liking.
local KeyboardKeybind = Enum.KeyCode.X --Standard keybind stuff. Very simple to change.
local ControllerKeybind = Enum.KeyCode.ButtonX --Refer to previous comment.
local EnableMobileButton = true --You can turn off the mobile button if you wanna make your own custom one.
local AllowRotate = true --Enable/Disable the camera rotation
local TurnConstraint = 2 --Changes how far you can turn your camera (increasing the number decreases the amount it can turn)
local ButtonImage = "rbxassetid://247421264" --Sets the image of the mobile button. If you don't want one leave it as ""
local ButtonTitle = "" --Adds a title to the mobile button. Blank by default but to add one just type in anything between the ""
local ButtonAdjustsWithJumpButton = true --If turned to false, the mobile button will adjust according to it's default position. Changing the ButtonPosition variable would be suggested if setting this to false.
local ButtonPosition = UDim2.new(0,60, 0,0) --You can manually change the position of the default button here, although be warned, it is really wonky.
--Required Variables; Don't edit unless you're reworking camera
local RunService = game:GetService("RunService")
local ContextActionService = game:GetService("ContextActionService")
local UserInputService = game:GetService("UserInputService")
local Player = game.Players.LocalPlayer
local Character = script:FindFirstAncestor(Player.Name)
local Humanoid = Character:WaitForChild("Humanoid")
local Camera = workspace.CurrentCamera
local Mouse = Player:GetMouse()
local LastInput = Enum.UserInputType.MouseMovement
local CDistanceX = 0
local CDistanceY = 0
--Functions
function CalculateDistance()
--Check to see if a controller has returned a value.
if LastInput == Enum.UserInputType.Gamepad1 then
return CDistanceX,-CDistanceY
else
--Get the center of the screen
local CenterX = Mouse.ViewSizeX/2
local CenterY = (Mouse.ViewSizeY)/2
--Make a distance cap
local DistCapX = CenterX*1.25
local DistCapY = CenterY*1.25
--Adjust caps to work with center offset
DistCapX = (CenterX-DistCapX)
DistCapY = (CenterY-DistCapY)
--Calculate the distance of the mouse from the center
local DistanceX = CenterX-Mouse.X
local DistanceY = CenterY-Mouse.Y
--Divide cap from distance to create a -1 to 1 scale.
DistanceX = DistanceX/DistCapX
DistanceY = DistanceY/DistCapY
if DistanceX > 1 and DistanceX > 0 then
DistanceX = 1
elseif DistanceX < -1 and DistanceX < 0 then
DistanceX = -1
end
if DistanceY > 1 and DistanceY > 0 then
DistanceY = 1
elseif DistanceY < -1 and DistanceY < 0 then
DistanceY = -1
end
return DistanceX,DistanceY
end
end
--Controller version of Calculate distance, as manually firing an input changed whilst being fired from renderstep causes MAJOR lag. :(
UserInputService.InputChanged:Connect(function(input)
if input.UserInputType == Enum.UserInputType.Gamepad1 then
LastInput = Enum.UserInputType.Gamepad1
if input.KeyCode == Enum.KeyCode.Thumbstick2 then
CDistanceX = input.Position.X
CDistanceY = input.Position.Y
end
elseif input.UserInputType == Enum.UserInputType.MouseMovement then
LastInput = Enum.UserInputType.MouseMovement
end
end)
function UpdateTransparency(transparency)
for i,v in pairs(Character:GetDescendants()) do
if v:IsA("Part") or v:IsA("MeshPart") then
v.LocalTransparencyModifier = transparency
end
end
end
function AdjustCamera()
local DistanceX, DistanceY = CalculateDistance()
local Head = Character:WaitForChild("Head")
local HRP = Character:WaitForChild("HumanoidRootPart")
Camera.CFrame = HRP.CFrame + Vector3.new(0,(Head.Position.Y-HRP.Position.Y),0)
if AllowRotate then
Camera.CFrame = Camera.CFrame * CFrame.Angles(-DistanceY/TurnConstraint,-DistanceX/TurnConstraint,0)
end
end
local active = false
local manual = false
function ChangeCamera(title,state)
if state == Enum.UserInputState.Begin or manual then
active = not active
if active then
UpdateTransparency(1)
Camera.CameraType = Enum.CameraType.Scriptable
Humanoid.AutoRotate = false
RunService:BindToRenderStep("CameraAdjust",1,AdjustCamera)
else
UpdateTransparency(0)
Camera.CameraType = Enum.CameraType.Custom
RunService:UnbindFromRenderStep("CameraAdjust")
Humanoid.AutoRotate = true
Player.CameraMinZoomDistance = 10
wait(0.1)
Player.CameraMinZoomDistance = 0.5
end
end
end
--Input
ContextActionService:BindAction("ChangeCamera",ChangeCamera,EnableMobileButton,KeyboardKeybind,ControllerKeybind)
--ButtonConfigs
if ButtonAdjustsWithJumpButton and UserInputService.TouchEnabled then
local JumpButton = Player.PlayerGui:WaitForChild("TouchGui").TouchControlFrame:WaitForChild("JumpButton")
ContextActionService:SetPosition("ChangeCamera", JumpButton.Position-ButtonPosition)
else
ContextActionService:SetPosition("ChangeCamera", ButtonPosition)
end
ContextActionService:SetImage("ChangeCamera", ButtonImage)
ContextActionService:SetTitle("ChangeCamera", ButtonTitle)
--Reset
Humanoid.Died:Connect(function()
manual = true
active = true
ChangeCamera()
ContextActionService:UnbindAction("ChangeCamera")
end)

