I would like some help in adjusting a shiftlock module. I slightly rescripted this smooth shiftlock module: Custom Shift Lock Module - [New] , to more align with how I want my game. Basically I want the character to face the camera’s direction when they are walking, or when their walkspeed is 16 or bellow, and when it’s above it should allow the character to rotate freely.
So far everything I provided works just fine except for autorotation, the module itself handles if autorotation is on or off so I am not able to figure out a way to to lock the player’s rotation without impacting the module.
I’ve tried just costumly add another rotation attribute to the humanoid and if it’s false then it would do the same thing as when the humanoid’s speed is above 16, but that ends up breaking it. Here is the rescripted module, I rescripted the ToggleShiftLock function:
--!strict
--[[
@ Name: SmoothShiftLock
@ Author: rixtys
@ Version: PlayerModule Pair 0.0.1
@ Desc: Smooth shift lock module that adds smoothness to the Roblox's shift lock
│ @ for this to work, disable the default Roblox's shift lock
│ @ game.StarterPlayer.EnableMouseLockOption = false
│ @ and start the custom shift lock module with
└ @ SmoothShiftLock:Init()
@ Methods = {
SmoothShiftLock:Init()
Initializes the module. (Should be done on client and only once)
SmoothShiftLock:IsEnabled()
Gets ShiftLock's enabled state
}
--]]
local SmoothShiftLock = {}
SmoothShiftLock.__index = SmoothShiftLock;
--// Context action
local CONTEXT_ACTION_NAME = "MouseLockSwitchAction"
local MOUSELOCK_ACTION_PRIORITY = Enum.ContextActionPriority.Medium.Value
--// Services
local Workspace = game:GetService("Workspace");
local Players = game:GetService("Players");
local RunService = game:GetService("RunService");
local ContextActionService = game:GetService("ContextActionService");
local Settings = UserSettings();
local GameSettings = Settings.GameSettings;
--// Requires
local CameraUtils = require(script.Parent:WaitForChild("CameraUtils"));
local Maid = require(script.Parent:WaitForChild("Maid"));
--// Instances
local LocalPlayer = Players.LocalPlayer;
local Camera = Workspace.CurrentCamera;
--// Configuration
local Config = require(script:WaitForChild("Settings"));
--// SmoothShiftLock constructor
function SmoothShiftLock.new()
local self = setmetatable({}, SmoothShiftLock);
self._runtimeMaid = Maid.new();
self.isEnabled = false;
self.isMouseLocked = false;
self.mouseLockToggledEvent = Instance.new("BindableEvent");
--// Check for client setting changes
GameSettings.Changed:Connect(function(property)
if property == "ControlMode" or property == "ComputerMovementMode" then
self:UpdateMouseLockAvailability()
end;
end);
--// Check for MouseLock availability changes
LocalPlayer:GetPropertyChangedSignal("DevEnableMouseLock"):Connect(function()
self:UpdateMouseLockAvailability()
end)
--// Check for ComputerMovementMode changes
LocalPlayer:GetPropertyChangedSignal("DevComputerMovementMode"):Connect(function()
self:UpdateMouseLockAvailability()
end)
if LocalPlayer.Character then
self.Character = LocalPlayer.Character;
self.Humanoid = self.Character:WaitForChild("Humanoid");
self.HumanoidRootPart = self.Character:WaitForChild("HumanoidRootPart");
end
LocalPlayer.CharacterAdded:Connect(function(Character: Model)
self.Character = Character;
self.Humanoid = self.Character:WaitForChild("Humanoid");
self.HumanoidRootPart = self.Character:WaitForChild("HumanoidRootPart");
end);
self:UpdateMouseLockAvailability()
return self
end
-- [[ Functions ]]:
--// Update MouseLock availability
function SmoothShiftLock:UpdateMouseLockAvailability()
local DevAllowsMouseLock = LocalPlayer.DevEnableMouseLock;
local DevMovementModeIsScriptable = LocalPlayer.DevComputerMovementMode == Enum.DevComputerMovementMode.Scriptable;
local UserHasMouseLockModeEnabled = GameSettings.ControlMode == Enum.ControlMode.MouseLockSwitch;
local UserHasClickToMoveEnabled = GameSettings.ComputerMovementMode == Enum.ComputerMovementMode.ClickToMove;
local MouseLockAvailable = DevAllowsMouseLock and UserHasMouseLockModeEnabled and not UserHasClickToMoveEnabled and not DevMovementModeIsScriptable;
if MouseLockAvailable ~= self.isEnabled then
self:EnableMouseLock(MouseLockAvailable);
end;
end;
--// Return bindable toggle event
function SmoothShiftLock:GetBindableToggleEvent()
return self.mouseLockToggledEvent.Event;
end;
--// Enable or disable MouseLock
function SmoothShiftLock:EnableMouseLock(Enable: boolean)
if Enable ~= self.isEnabled then
self.isEnabled = Enable;
if self.isEnabled then
self:BindContextActions();
else
self:UnbindContextActions();
self:ToggleShiftLock(false);
end;
end;
end;
--// MouseLock switch
function SmoothShiftLock:DoMouseLockSwitch(name, state, input)
if state == Enum.UserInputState.Begin then
self:ToggleShiftLock(not self.isMouseLocked);
return Enum.ContextActionResult.Sink;
end;
return Enum.ContextActionResult.Pass;
end;
--// Bind keybinds
function SmoothShiftLock:BindContextActions()
ContextActionService:BindActionAtPriority(CONTEXT_ACTION_NAME, function(name, state, input)
return self:DoMouseLockSwitch(name, state, input)
end, false, MOUSELOCK_ACTION_PRIORITY, unpack(Config.SHIFT_LOCK_KEYBINDS));
end;
--// Unbind keybinds
function SmoothShiftLock:UnbindContextActions()
ContextActionService:UnbindAction(CONTEXT_ACTION_NAME)
end
function SmoothShiftLock:ToggleShiftLock(Toggle: boolean)
self.isMouseLocked = Toggle;
if (self.isMouseLocked) then
CameraUtils.setMouseIconOverride(Config.LOCKED_MOUSE_ICON);
--// Start
if (self.isMouseLocked) and self.Character then
self._runtimeMaid:GiveTask(RunService.RenderStepped:Connect(function(Delta: number)
if not self.Humanoid or not self.HumanoidRootPart then return; end;
-- If WalkSpeed is greater than 16, face the direction of movement smoothly
if self.Humanoid.WalkSpeed > 16 then
local moveDirection = self.HumanoidRootPart.Velocity
if moveDirection.Magnitude > 0 then
-- Make the character face the direction of movement with smoother rotation
local moveCFrame = CFrame.lookAt(self.HumanoidRootPart.Position, self.HumanoidRootPart.Position + moveDirection.Unit)
-- Adjust the lerp factor to make it smoother
self.HumanoidRootPart.CFrame = self.HumanoidRootPart.CFrame:Lerp(moveCFrame, math.min(Delta * 2 * Config.CHARACTER_ROTATION_SPEED, 0.1))
end
return;
end;
-- If WalkSpeed is 16 or below, handle smooth rotation based on camera
self.Humanoid.AutoRotate = not self.isMouseLocked;
if self.Humanoid.Sit then return; end;
local _, y, _ = Camera.CFrame:ToOrientation();
if (Config.CHARACTER_SMOOTH_ROTATION) then
self.HumanoidRootPart.CFrame = self.HumanoidRootPart.CFrame:Lerp(CFrame.new(self.HumanoidRootPart.Position) * CFrame.Angles(0, y, 0), Delta * 3 * Config.CHARACTER_ROTATION_SPEED);
else
self.HumanoidRootPart.CFrame = CFrame.new(self.HumanoidRootPart.Position) * CFrame.Angles(0, y, 0);
end;
end));
end;
else
self._runtimeMaid:Destroy();
if self.Humanoid then
self.Humanoid.AutoRotate = not self.isMouseLocked;
end;
CameraUtils.restoreMouseIcon();
end;
self.mouseLockToggledEvent:Fire();
end;
function SmoothShiftLock:GetIsMouseLocked()
return self.isMouseLocked;
end;
return SmoothShiftLock;