Smooth Custom Shift Lock

I have tried this:


local player = game.Players.LocalPlayer

local character = player.Character or player.CharacterAdded:Wait()

local rootPart = character:WaitForChild("HumanoidRootPart")

local camera = workspace.CurrentCamera

local runService = game:GetService("RunService")

-- the event
runService.Heartbeat:Connect(function()
	
	character .Humanoid.AutoRotate = false

	local lookVector = camera.CFrame.LookVector 
	
	local rootPos = rootPart.Position; local distance = 900

	rootPart.CFrame = CFrame.new(rootPos, lookVector * Vector3.new(1, 0, 1) * distance) -- getting the root part to look at where the camera is looking on both x and z axis
	
end)
	

The character orientation is aligned with camera orientation which is what i want but it’s delayed,

I have seen a snippet of code before where it gets the camera orientation and apply it to the humanoid root part using some math functions and it does the same work as my script but without the delay which is exactly what i need but I lost it and couldn’t find its source again.

appreciate any help.

5 Likes

Try this

-- the event
runService.Stepped:Connect(function()
	character.Humanoid.AutoRotate = false

	local lookVector = camera.CFrame.LookVector
	local rootPos = rootPart.Position

	rootPart.CFrame = CFrame.lookAt(rootPos, rootPos+Vector3.new(lookVector.X, 0, lookVector))
end)
4 Likes
-- the event
runService.Stepped:Connect(function()
	character.Humanoid.AutoRotate = false

	local lookVector = camera.CFrame.LookVector
	local rootPos = rootPart.Position

	rootPart.CFrame = rootPart.CFrame:Lerp(CFrame.lookAt(rootPos, rootPos+Vector3.new(lookVector.X, 0, lookVector)),0.1) -- tweak the 0.1 value if you wish for smoother or rougher rotation
end)
2 Likes

@kalabgs I have tested the script and tried different values for the lerp function as mentioned in the script but it’s not smooth at all, it’s more of a delayed version of the code I wrote in the question, Thanks anyways.

@Lielmaster Appreciate your answer but it’s not different from the code I wrote since you just did the same functionality but with different syntax, A small note is that the Z value on the second argument for the CFrame.LookAt function should be LookVector.Z not just LookVector.

2 Likes

Can you provide video?
(characters limit)

3 Likes

The lerp function just smoothens the transition form one direction to another.

What I’m trying to achieve is to perfectly align the character orientation with the camera orientation without a transition which is exactly what my script does but its delayed,

It’s very noticeable when you move your mouse fast enough on its X axis [ to change where the camera is looking ] and also noticeable on low fps devices.

1 Like

Try BindToRenderStep with priority after camera.

3 Likes

Not sure if anyone told you that before but you are an absolute genius,

Here is the code after some changes based on your amazing suggestion:

--// Player Info

local player       = game:GetService("Players").LocalPlayer
local character    = player.Character or player.CharacterAdded:Wait()
local rootPart     = character:WaitForChild("HumanoidRootPart")
local camera       = game:GetService("Workspace").CurrentCamera
local runService   = game:GetService("RunService")
local humanoid     = character:WaitForChild("Humanoid")

--// Shift Lock Function
local function shiftLock(toggle)

	local function lock()

		local lookVector = camera.CFrame.LookVector

		local rootPos = rootPart.Position; local distance = 900

		rootPart.CFrame = CFrame.new(rootPos, lookVector * Vector3.new(1, 0, 1) * distance)

	end
	
	if toggle then

		runService:BindToRenderStep("ShiftLock", 200, lock)

	else

		runService:UnbindFromRenderStep("ShiftLock")

	end; humanoid.AutoRotate = not toggle

end

shiftLock(true) -- enabling shift lock

It’s as smooth as the Built-In ShiftLock but without the camera offset.

You can Toggle the shift lock by calling the shift lock function with a true or false parameter indicating enable/disable respectively

10 Likes

Maybe add to this:

local UIS = game:GetService()
humanoid.CameraOffset = Vector3.new(3, 1, 1)
UIS.MouseBehavior = Enum.MouseBehavior.LockCenter

Then it would be really shift-lock

1 Like

I don’t know, but when I use this code in my tool to activate when I equip it, I slowly move backwards…?

I made no changes to the code above.

1 Like

send the code and Ill look on it

It’s exactly the same as above, just made it work simply with script.Parent.Equipped. I didn’t make any changes besides that.

local player       = game:GetService("Players").LocalPlayer
local character    = player.Character or player.CharacterAdded:Wait()
local rootPart     = character:WaitForChild("HumanoidRootPart")
local camera       = game:GetService("Workspace").CurrentCamera
local runService   = game:GetService("RunService")
local humanoid     = character:WaitForChild("Humanoid")

--// Shift Lock Function
local function shiftLock(toggle)

	local function lock()

		local lookVector = camera.CFrame.LookVector

		local rootPos = rootPart.Position; local distance = 900

		rootPart.CFrame = CFrame.new(rootPos, lookVector * Vector3.new(1, 0, 1) * distance)

	end
	
	if toggle then

		runService:BindToRenderStep("ShiftLock", 200, lock)

	else

		runService:UnbindFromRenderStep("ShiftLock")

	end; humanoid.AutoRotate = not toggle

end

script.Parent.Equipped:Connect(shiftLock(true))
script.Parent.Unequipped:Connect(shiftLock(false))

It just slowly moves me backwards.