Hello, i’m having problems with a custom shiftlock system i’m trying to make.
local RS = game:GetService("RunService")
local UIS = game:GetService("UserInputService")
local ShiftLock = false
local Camera = workspace.CurrentCamera
local Player = game.Players.LocalPlayer
local Character = Player.Character or Player.CharacterAdded:Wait()
local Zoom = 5
local RY = 0
local RX = 0
RS.RenderStepped:Connect(function()
if ShiftLock then
local delta = UIS:GetMouseDelta()
local X,Y,Z = Camera.CFrame:ToEulerAnglesXYZ()
local YDeg = math.deg(Y)
local CX,CY,CZ = Character.PrimaryPart.CFrame:ToEulerAnglesXYZ()
Character:SetPrimaryPartCFrame(CFrame.new(Character.PrimaryPart.Position) * CFrame.Angles(CX,Y,CZ))
local Y1 = delta.Y
local X1 = delta.X
RY += Y1
RX += X1
print(Zoom)
local CF = (Character.PrimaryPart.CFrame * CFrame.Angles(math.rad(RY),math.rad(RX),0)) * CFrame.new(-Character.PrimaryPart.CFrame.LookVector*Zoom)
Camera.CFrame = CF
end
end)
UIS.InputBegan:Connect(function(key)
if key.KeyCode == Enum.KeyCode.LeftShift then
ShiftLock = not ShiftLock
if ShiftLock then
Camera.CameraType = Enum.CameraType.Scriptable
UIS.MouseBehavior = Enum.MouseBehavior.LockCenter
else
Camera.CameraType = Enum.CameraType.Custom
UIS.MouseBehavior = Enum.MouseBehavior.Default
end
end
end)
UIS.InputChanged:Connect(function(inp)
if inp.UserInputType == Enum.UserInputType.MouseWheel then
if inp.Position.Z == 1 then
Zoom = math.clamp(Zoom + 5,5,100)
else
Zoom = math.clamp(Zoom - 5,5,100)
end
end
end)
CFrame * CFrame results in a CFrame that is the first one, transformed by the second one, relative to the first one. So if the second one is a rotation, the result will be the first one rotated relative to the first one. You get that result because you’re rotating the camera on it’s local Y axis. “normal” fps cameras generally rotate on the world-space Y axis.
To get the correct result you’ll have to pitch (rotate on X axis) relative to the camera and yaw (rotate on Y axis) relative to the world. You can convert from the world-space Y axis to the camera’s current object space coordinates using VectorToObjectSpace and then create a rotation CFrame using fromAxisAngle.
Here’s an example script showing exactly how to do it:
local InputS = game:GetService("UserInputService")
local cam = game.Workspace.CurrentCamera
cam:GetPropertyChangedSignal("CameraType"):Connect(function()
if cam.CameraType ~= Enum.CameraType.Scriptable then
--Needed because there's a bug with the Roblox engine or some built-in script causing CameraType to be reset after LocalScripts run
cam.CameraType = Enum.CameraType.Scriptable
print(":D")
end
end)
cam.CameraType = Enum.CameraType.Scriptable
InputS:GetPropertyChangedSignal("MouseBehavior"):Connect(function()
if InputS.MouseBehavior ~= Enum.MouseBehavior.LockCenter then
--Needed because there's a bug with the Roblox engine or some built-in script causing MouseBehavior to be reset after LocalScripts run
InputS.MouseBehavior = Enum.MouseBehavior.LockCenter
print(":3")
end
end)
InputS.MouseBehavior = Enum.MouseBehavior.LockCenter
cam.CFrame = CFrame.new(0, 20, 0)
InputS.InputChanged:Connect(function(input)
cam.CFrame *= CFrame.Angles(-input.Delta.Y * 0.01, 0, 0)
cam.CFrame *= CFrame.fromAxisAngle( cam.CFrame:VectorToObjectSpace(Vector3.yAxis), -input.Delta.X * 0.01 )
end)