Custom Shift Lock Module - [New]

Yea I’m having the same problem, is there any fix to this?

I still can’t find a fix unfortunately

Fixed it, thank you both for reporting.

1 Like

This Module is so helpful it made thing easier for me
You should also try making OTS - Over The Shoulder Camera
for gun system

1 Like

Thanks for the feedback!
I can make an over the shoulder camera module, but there are so many out there that do it, but thank you for the idea!

How can i prevent them seeing through walls when using shiftlock?

There isn’t a certain answer to this question, due to how ray casting is done. My approach to fix it might be to raycast searching for walls with an offset forwards from the character, therefore it won’t miss out on any walls in the way.

When disabling shift lock, it won’t allow me to rotate the camera anymore. When right click and dragging, it will move just a tiny bit, but mostly doesn’t move.

I don’t really know why this happens, sending a video of the bug will help.

Nevermind, with further testing everything seems to be working fine. I think I was using another shift lock module that was acting up and I got these two mixed up. Sorry for the confusion

Everything seemed to be working fine but I ran into this upon testing just now. Never ran into this problem before, but I can’t move my camera.


Shifting in or out of shift lock doesn’t fix it. In the video I’m moving my mouse around while in and out of shift lock and also trying to right click to drag. I think going in and out of shift lock allows me to move the camera a little bit. My mouse is invisible because my combat system does that.

2 Likes

not yet, but I haven’t really looked into it yet. I’m sure it’s something to do with the script not running when it should be after the character loads

1 Like

I am here with a fix for you both! I was running into the same problem in my MMO-Rpg but the fix is quite simple, you see renderstepped makes a action happen multiple times regardless the situation, in the shiftLockController module there is a renderstepped which constantly changes the mouse’s behaviour causing the mouse to well, glitch like yours does, the fix is quite simple, remove the mouse behaviour from the renderstepped and change it through a UIS.InputBegan.
Before:


After:

I myself moved the mouse behaviour to another one of my module which sets it without using renderstep:
image_2023-04-02_120936942
Enjoy!

3 Likes

Awesome, I just put the problem off lol so it’s nice to see this :smiley: thanks!

1 Like

The script breaks after the player dies…

1 Like

Yeah I have the same issue. I’ve been trying to fix it for the past couple hours.

Fixed the script to fix dying and the issue where you can’t rotate your camera when out of shiftlock

Also I set it up to disable the shiftlock when on death in the handler script. I also removed the assert statement that prevented you from disabling shiftlock while the character is dead, but made you only able to disable the shiftlock and not enable it, to fool proof it. It could still potentially error if you messed with it too much but this should be pretty safe to use.

local players = (game:GetService("Players"));
local playerMouseInstance = (players.LocalPlayer:GetMouse());
local character = (players.LocalPlayer.Character or players.LocalPlayer.CharacterAdded:Wait());
character:WaitForChild("Humanoid")
character:WaitForChild("HumanoidRootPart")
local camera = (workspace.CurrentCamera);
local runService = (game:GetService("RunService"));
local userInputService = (game:GetService("UserInputService"));
local shiftLockController = {}
shiftLockController.__index = shiftLockController

function shiftLockController.new(settings)
	local self = {isShiftLockToggled = (false)};
	local renderSteppedConnection, inputChangedConnection, humanoidDiedConnection, characterAddedConnection;
	local loadedCharacter = (false);
	local functions = {
		-- | RenderStepped | --
		renderStep = function(dt)
			local camera = (workspace.CurrentCamera);
			if character and character.Parent == game.Workspace then
				local humanoid = (character:WaitForChild("Humanoid"));
				local humanoidRootPart = (character:WaitForChild("HumanoidRootPart"));
				if (humanoid) and (humanoidRootPart) then 
					if (settings.RotateCharacter) then
						humanoid.AutoRotate = not self.isShiftLockToggled
					end;
					
					humanoid.CameraOffset = self.isShiftLockToggled and humanoid.CameraOffset:Lerp(Vector3.new(settings.CameraOffsetX, settings.CameraOffsetY), dt * 3 * settings.CameraOffsetLerpSpeed) or humanoid.CameraOffset:Lerp(Vector3.new(), dt * 3 * settings.CameraOffsetLerpSpeed)
				end;
				
				if (self.isShiftLockToggled) then
					if not (character.Humanoid.SeatPart) then
						if (settings.RotateCharacter) then
							local x, y, z = camera.CFrame:ToOrientation();
							humanoidRootPart.CFrame = humanoidRootPart.CFrame:Lerp(CFrame.new(humanoidRootPart.Position) * CFrame.Angles(0, y, 0), dt * 5 * settings.CharacterFacingLerpSpeed)
						end;
					end;
				end;
			else
				character = (players.LocalPlayer.Character or players.LocalPlayer.CharacterAdded:Wait());
				character:WaitForChild("Humanoid")
				character:WaitForChild("HumanoidRootPart")
			end
		end;
		
		-- | InputChanged | --
		inputChanged = function(input, gpe)
			if (gpe) or (not self.isShiftLockToggled) then return end;
			if (character.Humanoid.SeatPart) then return end;
			if (input.UserInputType == Enum.UserInputType.MouseMovement) then
				camera.CFrame = camera.CFrame * CFrame.Angles((input.Delta.X / camera.ViewportSize.X) * userInputService.MouseDeltaSensitivity, 0, 0) * CFrame.Angles(0, (input.Delta.Y / camera.ViewportSize.Y) * userInputService.MouseDeltaSensitivity, 0)
			end;
		end;
		
		-- | Died | --
		died = function()
			players.LocalPlayer.Character:FindFirstChildOfClass("Humanoid").CameraOffset = Vector3.new()
		end;
		
		-- | CharacterAdded | --
		characterAdded = function()
			self.isShiftLockToggled = false
		end,
	};
	
	renderSteppedConnection = runService.RenderStepped:Connect(functions.renderStep)
	inputChangedConnection = userInputService.InputChanged:Connect(functions.inputChanged)
	humanoidDiedConnection = players.LocalPlayer.Character:FindFirstChildOfClass("Humanoid").Died:Connect(functions.died)
	characterAddedConnection = players.LocalPlayer.CharacterAdded:Connect(functions.characterAdded)
	return setmetatable(self, shiftLockController)
end;

function shiftLockController:Lock(boolean)
	assert(not (boolean == nil), "Argument missing or is equal to nil.")
	assert(typeof(boolean) == typeof(false), "Argument is not a valid boolean.")
	userInputService.MouseBehavior = boolean and Enum.MouseBehavior.LockCenter or Enum.MouseBehavior.Default;
	if character:FindFirstChildOfClass("Humanoid").Health > 0 or boolean == false then
		self.isShiftLockToggled = boolean
	end
end;

return shiftLockController

@ComplexMetatable I recommend implementing this fix to the native module (maybe in your own code style though as this might not be the most efficient way of achieve this :P)