How can I force shift lock?

What shift lock does is basically lock the mouse in the center of the screen, and move the camera a bit.

I’ve seen people messing with the Camera module.
This seems like a bit of a “tricky solution” for me.
I would just Use RunService.PreRender or RunServer.RenderStepped (Deprecated), UserInputService.MouseBehaviour, and Humanoid.CameraOffset.
For the rotation I use BodyGyro on the HumanoidRootPart.
Example:

--Local script in StarterPlayerCharacter
local plr = game:GetService("Players").LocalPlayer
local mouse = plr:GetMouse()
local char = script.Parent
local hum = char:WaitForChild("Humanoid")
local rotation = Instance.new("BodyGyro") --Create a new body gyro.
rotation.P = 1000000 --Increase the power
rotation.Parent = hum.RootPart --Parent it to the humanoid
local conn -- connection variable
function shiftLock(active) --Toggle shift.lock function
	if active then
		hum.CameraOffset = Vector3.new(1,0.5,0) -- I assume this is about the right camera offset.
		rotation.MaxTorque = Vector3.new(0, math.huge, 0) --Max the power on the Y axis
		conn = game:GetService("RunService").RenderStepped:Connect(function()
			rotation.CFrame = mouse.Origin
			game:GetService("UserInputService").MouseBehavior = Enum.MouseBehavior.LockCenter
		end) --Set the mouse to center every frame.
	else
		hum.CameraOffset = Vector3.new(0,0,0) --Move the camera back to normal.
		rotation.MaxTorque = Vector3.new(0, 0, 0) --Clear the power on the HumanoidRootPart
		if conn then conn:Disconnect() end -- Allow mouse to move freely.
	end
end
hum.Died:Connect(function()
	shiftLock(false) --Stop connection on player death
end)
shiftLock(true) -- Toggle shift lock
wait(10)
shiftLock(false) -- Will disconnect

For some reason, PreRender didn’t work for me although RenderStepped did? Not sure why.
Testing:

3 Likes

Is the mouse locking onto the screen? Also did you use the same code as I’ve written or your own?

1 Like

I’ve used your code. I also open a new file with your code in case any other script was interfering with it. The mouse is locked as you can see in this video

Here’s a file that has the problem shiftlock.rbxl (145.1 KB)

Did you grab the actual player module or did you copy and paste the function into a player module?

Also put shiftLock under StarterPlayerScripts

1 Like

Did you grab the actual player module or did you copy and paste the function into a player module?

I think you meant “and” here. Yes I’ve grabbed the player module while the game was running and copy pasted the function over the previous update function

Also put shiftLock under StarterPlayerScripts

I’ve written local shiftLockOn = game.StarterPlayer.shiftlock, so i don’t think it’s necessary to do that.

I found editing the playerModule kind of tiresome. So I messed around with the scripts from this video SHOULDER CAMERA TUTORIAL - Third Person Shooter Camera - Camera Manipulation (Roblox Studio) - YouTube and found these working for me. Put them in different local scripts inside starterCharacter if you will. Don’t forget to set EnableMouseLockOption to false

local uis = game:GetService("UserInputService")
local rs = game:GetService("RunService")

rs.RenderStepped:Connect(function()
	uis.MouseBehavior = Enum.MouseBehavior.LockCenter--lock mouse to center, pretty self explanatory
	game.Players.LocalPlayer.Character.Humanoid.CameraOffset=Vector3.new(2,0,0)--offsetting the camera
end)

Some might ask why the script above needed to be renderStepped, the playerModule constantly changes these values.

local cam = workspace.CurrentCamera
local plr = game:GetService("Players").LocalPlayer

game:GetService("RunService"):BindToRenderStep("hmm",199, function()--this is because of sync issues
	if plr.Character then
		local rootPart = plr.Character:WaitForChild("HumanoidRootPart")
		if rootPart then
			rootPart = plr.Character:WaitForChild("HumanoidRootPart")
			rootPart.CFrame = CFrame.new(rootPart.CFrame.p, rootPart.CFrame.p + Vector3.new(cam.CFrame.LookVector.X,0,cam.CFrame.LookVector.Z))
		end
	end
end)

Character rotation. No bodyGyros :wink:

3 Likes

That works too, some problems may arise from that if you plan for further camera manipulation though.

1 Like

Yep, especially with the zoom. There’s no easy way to perfectly manipulate the zoom unless you mess around with the ever changing cameraModule or you make your own camera script, which requires you to fiddle around with bindToRenderStep priority values as it desyncs everything running in RenderStepped. I think enough attempts has been taken for the first one in this thread. For the latter one here’s a code from the video if anyone’s interested. No need to offset humanoid camera if you’re using this.

-- LOCALS --

-- Services
local uis = game:GetService("UserInputService")
local rs = game:GetService("RunService")
local context = game:GetService("ContextActionService")

-- Player & Character
local plr = game:GetService("Players").LocalPlayer

-- Other
local Camera = game:GetService("Workspace").CurrentCamera
local mouse = plr:GetMouse()
local cameraDB = false
local zoomDB = false

-- Values

local xAngle = 0
local yAngle = 0
local cameraPos = Vector3.new(2,0,8.5)


-- CAMERA SETTING --

wait(0.01)
Camera.CameraType = Enum.CameraType.Scriptable

-- FUNCTIONS --

context:BindAction("CameraMovement", function(_,_,input)
	xAngle = xAngle - input.Delta.x*0.4
	yAngle = math.clamp(yAngle - input.Delta.y*0.4,-80,80)
end, false, Enum.UserInputType.MouseMovement)

rs.RenderStepped:Connect(function()--use bindToRenderStepped instead with appropriate priority values
	local c = plr.Character or plr.CharacterAdded:Wait()
	local rootPart = c:FindFirstChild("HumanoidRootPart")
	
	if c and rootPart then
		local startCFrame = CFrame.new((rootPart.CFrame.p + Vector3.new(0,2,0)))*CFrame.Angles(0, math.rad(xAngle), 0)*CFrame.Angles(math.rad(yAngle), 0, 0)
		
		local cameraCFrame = startCFrame + startCFrame:VectorToWorldSpace(Vector3.new(cameraPos.X,cameraPos.Y,cameraPos.Z))--the value you'd want to change
		local cameraFocus = startCFrame + startCFrame:VectorToWorldSpace(Vector3.new(cameraPos.X,cameraPos.Y,-50000))
		
		Camera.CFrame = CFrame.new(cameraCFrame.p,cameraFocus.p)
	end
end)
1 Like

I stumbled across this post and would like to bring it back up. I am using the method @skppiy4000 mentioned, yet it is very laggy, to put it.

Any solution to this?

1 Like

Seems like the body rotation is updating slower than the camera update. I faced this too. Whatever is doing the body rotation, if you put it in ** BindToRenderStep(“something”,199, function() enter code here end), it would’ve fixed it.

1 Like

I made another post about this and did that. The main issue I found was that you have to set humanoid.AutoRotate to false, and then manually turn the character by setting the CFrame with a lerp. It is still fairly glitchy with these two methods combined, but it only happens when you rotate, no longer when you jump or in free fall, and with a turn lerp it’s barely noticeable since the character isn’t locked where the camera is facing.

Edit: Here’s the code that I use. It works well but if you think you can fully rid the glitch then feel free to optimize it:

humanoid.AutoRotate = false
runService:BindToRenderStep("Before camera", 199, function()
	local currentTime = tick()
	if camera.CameraType == Enum.CameraType.Follow and humanoid.MoveDirection.Magnitude > 0 and humanoid.WalkSpeed > 0 then
		local swayX = math.cos(currentTime * 15) * 0.3
		local swayY = math.abs(math.sin(currentTime * 15) * 0.3)
		local sway = Vector3.new(swayX + 3.5, swayY, 1)
		humanoid.CameraOffset = humanoid.CameraOffset:lerp(sway, 0.25)
	elseif camera.CameraType ~= Enum.CameraType.Follow or humanoid.MoveDirection.Magnitude == 0 or humanoid.WalkSpeed == 0 then
		local offsetStandard = Vector3.new(3.5, 0, 1)
		humanoid.CameraOffset = humanoid.CameraOffset:Lerp(offsetStandard, 0.25)
	end
	local goalCFrame = CFrame.new(rootPart.Position, rootPart.Position + Vector3.new(camera.CFrame.LookVector.X, 0 , camera.CFrame.LookVector.Z))
	rootPart.CFrame = rootPart.CFrame:Lerp(goalCFrame, 0.5)
end)
2 Likes

I might be wrong here, but lerping isn’t instant right? Even when you set the lerp with smallest possible time, its still supposed to be slower (hence laggier) than directly setting the CFrame of hrp.
rootPart.CFrame = CFrame.new(rootPart.CFrame.p, rootPart.CFrame.p + Vector3.new(cam.CFrame.LookVector.X,0,cam.CFrame.LookVector.Z))

It depends on what you want though, you could do this if you want exactly like shift lock. However if you want slower character rotations, lerping would be the way to go. Idk if changing bindToRenderStep priorities would help in that case. Might have to open up a new thread for that.

1 Like

I think I didn’t articulate myself correctly. I like the lerp because the slight, organic delay of you turning and your character turning helps prevent the character glitching from being obvious. The character has yet to stop glitching entirely but it’s whatever.

1 Like

Hey, I’ve tried the script out and it works great! However, I am unable to disable the shiftlock again. I’ve tried setting them to trues and false’s. None of the combination is working, do you have any idea how I could do it? :thinking:

what are you refferencing gamesettings with?