Hey! I have noticed that many programmers have been wishing for a way to apply shift lock easily.
So, I have created a simple Custom Shift Lock Module. The module’s API is straightforward and simple, here is an example of how you would use it:
local shiftLock = (require(script.Parent:WaitForChild("ShiftLock")))
local userInputService = (game:GetService("UserInputService"));
function input_Began(input, gpe)
if (gpe) then return end;
if (input.KeyCode == Enum.KeyCode.LeftShift) then
shiftLock:Lock(not shiftLock:IsLocked())
end;
end;
userInputService.InputBegan:Connect(input_Began)
-- Roblox's shift lock behavior, you press Left Shift, and it locks / unlocks dependent on the current state.
There are also custom settings which you can apply at the beginning of the module:
Grab the module here, you don’t have to credit me:
IMPORTANT NOTE: Place the module in StarterGui, to avoid any bugs.
Make sure to recommend for new settings i.e new APIs, any idea is good! Note: I apologize if any issues occur with the module. I have not updated it in a long time, and it is not currently something I am working on.
This is a crazy good module I love this! Thank you! One suggestion, Allow the player to offset the camera for example in settings maybe add a setting call xoffset and another for yoffset. Just a little thing that will help other people get a better camera.
Thanks for the suggestion, and I apologize for the very-late response.
I will consider adding the feature that you suggested, as I do see it being useful Edit: I have just tested and added this feature, thanks for your suggestion!
I don’t really think that there is a possible solution for this issue, I will try looking into it. And again, I apologize for the delay of my response.
I wasn’t really active at the time that this comment was written, but now I’m active, I managed to fix that issue. If bugs will be reported now, I will most likely solve them the time they are reported. Really big apologies for this inactivity.
umm your module still broken because when the player is respawned because the local character = characteradded:wait() took so long
Edit: here’s my fixed version of the code:
-- Fixed by zBrick20 (@thebrickplanetboy)
local function WaitForChildOfClass(Parent, ClassName)
while not Parent:FindFirstChildOfClass(ClassName) do
Parent.ChildAdded:Wait()
end
return Parent:FindFirstChildOfClass(ClassName)
end
local Players = game:GetService("Players")
local Player = Players.LocalPlayer
if not Player then
Players:GetPropertyChangedSignal("LocalPlayer"):Wait()
Player = Players.LocalPlayer
end
local Mouse = Player:GetMouse()
local Camera = workspace.CurrentCamera
local UserInputService = game:GetService("UserInputService")
local RunService = game:GetService("RunService")
local Character = Player.Character or Player.CharacterAdded:Wait()
local ShiftLockController = {}
ShiftLockController.__index = ShiftLockController
function ShiftLockController.New(Settings)
local self = {
IsShiftLockToggled = false,
Humanoid = WaitForChildOfClass(Character, "Humanoid"),
RootPart = Character:WaitForChild("HumanoidRootPart", math.huge)
}
local function IsInFirstPerson()
if (Camera.Focus.Position - Camera.CFrame.Position).Magnitude < 1 then
return true
else
return false
end
end
local function CharacterAdded(NewCharacter)
self.Humanoid = WaitForChildOfClass(NewCharacter, "Humanoid")
self.RootPart = NewCharacter:WaitForChild("HumanoidRootPart", math.huge)
end
local function InputChanged(Input, GameProcessed)
if GameProcessed or not self.IsShiftLockToggled then return end
if (self.Humanoid.Sit or self.Humanoid:GetState() == Enum.HumanoidStateType.Seated) and self.Humanoid:GetState() == Enum.HumanoidStateType.Swimming and self.Humanoid:GetState() == Enum.HumanoidStateType.Physics and self.Humanoid:GetState() == Enum.HumanoidStateType.Ragdoll and self.Humanoid:GetState() == Enum.HumanoidStateType.Dead then return end
if Input.UserInputType == Enum.UserInputType.MouseMovement or Input.UserInputType == Enum.UserInputType.Touch or Input.UserInputType == Enum.UserInputType.Focus 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
local function RenderStepped(DeltaTime)
UserInputService.MouseBehavior = self.IsShiftLockToggled and Enum.MouseBehavior.LockCenter or UserInputService.MouseBehavior
Mouse.Icon = self.IsShiftLockToggled and Settings.MouseIconOnToggle or ""
if self.Humanoid and self.RootPart then
self.Humanoid.AutoRotate = not self.IsShiftLockToggled
self.Humanoid.CameraOffset = self.IsShiftLockToggled and not IsInFirstPerson() and self.Humanoid.CameraOffset:Lerp(Vector3.new(Settings.CameraOffsetX, Settings.CameraOffsetY), DeltaTime * 3 * Settings.CameraOffsetLerpSpeed) or self.Humanoid.CameraOffset:Lerp(Vector3.new(), DeltaTime * 3 * Settings.CameraOffsetLerpSpeed)
end
if self.IsShiftLockToggled then
if (not self.Humanoid.Sit or self.Humanoid:GetState() ~= Enum.HumanoidStateType.Seated) and self.Humanoid:GetState() ~= Enum.HumanoidStateType.Swimming and self.Humanoid:GetState() ~= Enum.HumanoidStateType.Physics and self.Humanoid:GetState() ~= Enum.HumanoidStateType.Ragdoll and self.Humanoid:GetState() ~= Enum.HumanoidStateType.Dead then
local X, Y, Z = Camera.CFrame:ToOrientation()
self.RootPart.CFrame = self.RootPart.CFrame:Lerp(CFrame.new(self.RootPart.Position) * CFrame.Angles(0, Y, 0), DeltaTime * 5 * Settings.CharacterFacingLerpSpeed)
end
end
end
Player.CharacterAdded:Connect(CharacterAdded)
RunService.RenderStepped:Connect(RenderStepped)
UserInputService.InputChanged:Connect(InputChanged)
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.")
self.IsShiftLockToggled = Boolean
end
return ShiftLockController
I resetted the humanoid and rootpart variables by using characteradded:
local function CharacterAdded(NewCharacter)
self.Humanoid = WaitForChildOfClass(NewCharacter, "Humanoid")
self.RootPart = NewCharacter:WaitForChild("HumanoidRootPart", math.huge)
end
Player.CharacterAdded:Connect(CharacterAdded)
The system itself isn’t locking the mouse on it’s own, you have to call a method that the system provides to lock the mouse. Where did you place the ShiftLock module, where did you place the code that is activating the shift lock, and also send the code that is activating the shift lock.
Sorry for the incredible delay, I haven’t looked at this post for a while now.
You can do this directly through the code, by just removing the line that changes HumanoidRootPart.CFrame (don’t know where it is exactly).
When I will soon get on studio, I will add the requested feature, and edit this comment to update when I will have done that. Thanks for the suggestion and patience.
Edit: RotateCharacter is now a feature which you can disable/enable in the settings.