Still have questions? Join our Discord server and get real time help.
Log in to vote

How would i do this specific Shift lock?

Asked by 6 months ago
Edited 6 months ago

For my game, I'm trying to force a shift lock that controls the camera but also only makes the character look at the camera center when right-click is down. How would I do this? I have tried this but this just puts the cursor at the center and makes the Character face 1 particular direction

local players = game.Players.LocalPlayer
local Mouse = players:GetMouse()
local UserInputService = game:GetService("UserInputService")
local Character = players.Character or players.CharacterAdded:Wait()


Character.Humanoid.AutoRotate = false
while Mouse.Button2Down ==true do
Character.HumanoidRootPart.CFrame =,game.Workspace.CurrentCamera.Focus)

Character.Humanoid.AutoRotate = true

Character.Humanoid.AutoRotate = false
while true do game:GetService("RunService").Heartbeat:Wait()
    UserInputService.MouseBehavior = Enum.MouseBehavior.LockCenter

A good example of a game that does this is Warframe. The character only looks at the camera focus when aiming

:I Oblivious_Blitz 1 — 6mo

1 answer

Log in to vote
Answered by 5 months ago

Yea I found what I was looking for. So many views and not even an upvote or a comment. Thx anyways

local workspaceService = game:GetService("Workspace")
local runService = game:GetService("RunService")
local playersService = game:GetService("Players")
local userInputService = game:GetService("UserInputService")

-- config:
local SENSITIVITY = 0.4
local WORLD_OFFSET =, 2, 0)
local LOCAL_OFFSET =, 0, 9.5)

-- variables:
local camera = workspaceService.CurrentCamera
local localPlayer = playersService.LocalPlayer
local xAngle = 0
local yAngle = 0

 -- main:
-- handle camera moving
userInputService.InputChanged:Connect(function(input, isProcessed)
    -- validate input
    if isProcessed then return end
    if input.UserInputType ~= Enum.UserInputType.MouseMovement then return end
    -- get delta
    local delta = input.Delta
    local deltaX = delta.X
    local deltaY = delta.Y
    -- update angles
    xAngle = xAngle - deltaX * SENSITIVITY
    yAngle = math.clamp(yAngle - deltaY * SENSITIVITY, -80, 80)

-- handle camera update
runService:BindToRenderStep("CameraUpdate", Enum.RenderPriority.Camera.Value, function()
    -- get necessary data
    local cameraSubject = camera.CameraSubject
    if not cameraSubject then return end
    local isLocalPlayer = false
    local subject
    local ignoredInstance

-- check camera subject class
    if cameraSubject:IsA("Humanoid") then
        ignoredInstance = cameraSubject.Parent
        if not ignoredInstance:IsA("Model") then return end
        subject = ignoredInstance.PrimaryPart
        if not subject then return end
        if localPlayer.Character == ignoredInstance and cameraSubject.Health > 0 then
            isLocalPlayer = true
    elseif cameraSubject:IsA("BasePart") then
        subject = cameraSubject
        ignoredInstance = cameraSubject
    else return end

-- get positioned, world offset, and rotated cframe
    local xAngleCFrame = CFrame.Angles(0, math.rad(xAngle), 0)
    local anglesCFrame = xAngleCFrame:ToWorldSpace(CFrame.Angles(math.rad(yAngle), 0, 0))
    local cameraPosition = subject.Position + WORLD_OFFSET
    local startCFrame =

 -- get camera focus and local offset cframe
    local cameraCFrame = startCFrame:ToWorldSpace(
    local cameraFocus = cameraCFrame:ToWorldSpace(, 0, -LOCAL_OFFSET.Z))

 -- assign camera properties
    camera.Focus = cameraFocus
    camera.CFrame = cameraCFrame
    camera.CFrame = cameraCFrame:ToWorldSpace(, 0, -camera:GetLargestCutoffDistance({ignoredInstance})))
    -- rotate character
    if isLocalPlayer then
        local primaryPartCFrame = ignoredInstance:GetPrimaryPartCFrame()
        local newCFrame =


-- init
userInputService.MouseBehavior = Enum.MouseBehavior.LockCenter

Answer this question