This script forces the player into shiftlock, however, camera movement is choppy/buggy. Is there any other way to set a camera offset without the humanoid property, or some way to make it look smoother?
local plr = game.Players.LocalPlayer
local val = plr:WaitForChild("PlayerScripts"):WaitForChild("LockCamera")
local playermod = require(plr:WaitForChild("PlayerScripts", math.huge):WaitForChild("PlayerModule"))
local function onRenderStepped(dt)
plr.Character.Humanoid.CameraOffset = Vector3.new(3,0,0) -- the problem
plr.Character.HumanoidRootPart.CFrame = CFrame.lookAt(plr.Character.HumanoidRootPart.Position, plr.Character.HumanoidRootPart.Position + Vector3.new(workspace.CurrentCamera.CFrame.LookVector.X, 0, workspace.CurrentCamera.CFrame.LookVector.Z))
playermod:ToggleShiftLock(false, true, true)
UserSettings():GetService("UserGameSettings").RotationType = Enum.RotationType.CameraRelative
game:GetService("UserInputService").MouseBehavior = Enum.MouseBehavior.LockCenter
end
val:GetPropertyChangedSignal("Value"):Connect(function()
if val.Value == true then
game:GetService("RunService"):BindToRenderStep("ShoulderCamera", Enum.RenderPriority.Camera.Value + 1, onRenderStepped)
elseif val.Value == false then
game:GetService("RunService"):UnbindFromRenderStep("ShoulderCamera")
playermod:ToggleShiftLock(true, true, true)
UserSettings():GetService("UserGameSettings").RotationType = Enum.RotationType.MovementRelative
plr.Character.Humanoid.CameraOffset = Vector3.new(0,0,0)
game:GetService("UserInputService").MouseBehavior = Enum.MouseBehavior.Default
end
end)
It’s likely due to directly setting the Humanoid.CameraOffset property every frame within onRenderStepped. While the CameraOffset property can be used for slight offsets, it often causes jitter when updated frequently in combination with other camera controls.
Consider using Camera.CFrame and Camera.CFrame * Offset to offset the camera manually, rather than relying on the humanoid’s CameraOffset property. This approach gives you more direct control over the camera without conflicting with Roblox’s built-in humanoid properties.
MOREOVER you can perform calculation on a CFRAME to make nice effects later in game.
you need to create a new Cframe Instance instead of just modifying it and to move the camera’s CFrame by a certain offset, you should multiply the current CFrame by the new CFrame created with the offset.
well we didn’t define the orientation, only the position. As you may or may not know Cframe have a Position and an Orientation. to set the orientation I suggest you link it to the HumanoidRootPart Orientation
local player = game.Players.LocalPlayer
local character = player.Character or player.CharacterAdded:Wait()
local humanoidRootPart = character:WaitForChild("HumanoidRootPart")
-- Get the player's right and up direction based on their orientation
local rightVector = humanoidRootPart.CFrame.RightVector
local upVector = humanoidRootPart.CFrame.UpVector
-- Calculate the new camera position: 3 units to the right and 1 unit up from the player's position
local cameraPosition = humanoidRootPart.Position + (rightVector * 3) + (upVector * 1)
-- Update the camera's CFrame to the new position, looking at the player's position
workspace.CurrentCamera.CFrame = CFrame.new(cameraPosition, humanoidRootPart.Position)
Finally solved through days of trial and error, research, and ChatGPT. I won’t share the new script, but I set the camera mode to scriptable, offset an invisible part to the player’s character, and updated the part’s CFrame and the camera’s CFrame to match the part every frame (via :BindToRenderStep), alongside using tweens to try make it move smoother. It’s not perfect, but it’s the best I’ll get.