How can I force shift lock?

Yeah, it is a bad idea usually, but if you use a true/false variable, you can make it set up the connections only once.

1 Like

As I said anything you can do to improve is good, just from my own testing when I used it i never had any major issues regarding the update function, as long as you didn’t put like something that eats power for breakfast, of course now my pc is a bit more up to date, I don’t run into those issues as much so it would be hard to test with more strenuous code on my part as my computer can do more calculations.

1 Like

Hi @skppiy4000, sorry for asking for help in a really old post, but I have no idea on how to disable shift lock after forcing it, I tried using Mystifine s solution but it only had the enabling option working.

Unfortunately alot of this stuff relied on old functionality of the camera, I did not test on the newer camera, knowing this, if you scroll up a bit I put a old version of the camera that would work, you just need to modify it to your needs so you can turn it on and off when needed, or scan through it and yoink what you need.

If you mean how to turn off toggling it once its on, I believe if you flick this, this should stop shift lock from being able to be activated. image

Hi again skppiy, thanks for the reply, turns out that the only thing I needed to do was make a function so that a variable which stores the current state of the players shift lock could be changed

I’ve found a solution to make the shift lock togglable and it seems to actually be working pretty good for me.

Here’s what I did:
For starters I wanted the shiftlock to toggle whenever I set a certain boolean to true, so I created a folder in StarterPlayerScripts with the boolean inside
image

After this I needed to make it actually do something, so I created a local script inside of StarterCharacterScripts and set it up so that on every frame it checks to see if the boolean is set to true or not, and sets a customized offset. I decided to do it like this because I needed to be able to adjust it later on and give myself more customization.

Here is an edited version of that script with the basic premise of it (I have since far edited it with more parts to it, I’m only here to show how to make the shift lock)

--[[SERVICES]]--
local runService = game:GetService("RunService")
local players = game:GetService("Players")

--[[VARIABLES]]--
--Player Variables--
local player = players.LocalPlayer
local humanoid = player.Character.Humanoid

--Camera Variables--
local originalCameraOffset = Vector3.new(0,0,0) --The original camera offset we want
local cameraOffset = Vector3.new(2,0,0) --Offset we want the camera to be set at when shift locked

--Shiftlock Variables--
local valueFolder = player.PlayerScripts.Values
local shiftLockOn = valueFolder.ShiftLock

local function shiftLockSetup()
	if shiftLockOn.Value == true then
		humanoid.CameraOffset = cameraOffset
	else shiftLockOn.Value == false  then
		humanoid.CameraOffset = originalCameraOffset
	end
end

runService.RenderStepped:Connect(shiftLockSetup)

Awesome, we have our offset working. The problem we have now is locking the mouse to the camera.
There are other ways to do this, but I chose to directly modify the Camera Module to lock the mouse to the character whenever the boolean is turned on, specifically line 469 in the CameraModule:Update() function. Here is the code snippet I used to replace the previous one.

function CameraModule:Update(dt)
	if self.activeCameraController then
		if shiftLockBool.Value == true then --Edited code, simple if-else statement
			self.activeCameraController:SetIsMouseLocked(true) --locks mouse to player
		else
			self.activeCameraController:SetIsMouseLocked(false)
		end
		if FFlagUserCameraToggle then
			self.activeCameraController:UpdateMouseBehavior()
		end

		local newCameraCFrame, newCameraFocus = self.activeCameraController:Update(dt)
		self.activeCameraController:ApplyVRTransform()
		if self.activeOcclusionModule then
			newCameraCFrame, newCameraFocus = self.activeOcclusionModule:Update(dt, newCameraCFrame, newCameraFocus)
		end

		-- Here is where the new CFrame and Focus are set for this render frame
		game.Workspace.CurrentCamera.CFrame = newCameraCFrame
		game.Workspace.CurrentCamera.Focus = newCameraFocus

		-- Update to character local transparency as needed based on camera-to-subject distance
		if self.activeTransparencyController then
			self.activeTransparencyController:Update()
		end
	end
end

I defined the shiftLockBool at the beginning of the module script.

Now, what this is doing is every time the camera is updated now if that boolean is set to true it will automatically lock the mouse, with the best part being the character will now move with the mouse.

When the these two scripts are put together now, the boolean will toggle shiftlock.

Best part about this is you don’t need to rescript an entire complicated thing for rotating the character around with the camera or write any complicated scripts, Roblox has already done half of it for you. On top of this this will always work, even if the toggle shiftlock option is turned off in game, allowing you complete control over shiftlocking the camera, and even on top of that this works on all platforms.

Hope this helped, there are likely better solutions but I’ve found this method has worked the best for me.

2 Likes

This locks the mouse at the center, but unfortunately it doesn’t give the full-on feeling of shift lock. It doesn’t rotate the whole character onto where the camera is facing.

1 Like

It is indeed a very nice working method, but I’m experiencing some issues with it. The camera is constantly rotating in the direction where the mouse last moved to. Any Idea of what could be causing this?

What do you mean by it’s constantly rotating to where the mouse last moved to? Can you send a video of it?

1 Like

Sorry for resurrecting this thread but here’s a video of what’s happening. There’s like a permanent mouse acceleration kind of thing going on

2 Likes

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