In a soul eater game I’m developing for, I’m developing a movement system that works and acts smoothly. However, a big problem arises when I attempt to offset the camera in shift lock mode, where the player will lag behind the cursor when running. I’m currently using Humanoid.CameraOffset, but as that’s not working, I’m curious as to how I would go about creating a lagless offset. Here’s my code:
RunService.RenderStepped:Connect(function()
Player.PlayerScripts.PlayerModule.CameraModule.MouseLockController.BoundKeys.Value = "LeftAlt, RightAlt"
Mouse.Icon = "rbxassetid://46537754"
if UserInputService.MouseBehavior == Enum.MouseBehavior.LockCenter then
Player.CameraMinZoomDistance = 10
Player.CameraMaxZoomDistance = 10
Humanoid.CameraOffset = Vector3.new(-1.75, 1.75, 0)
elseif UserInputService.MouseBehavior == Enum.MouseBehavior.Default then
Player.CameraMinZoomDistance = 10
Player.CameraMaxZoomDistance = 32
if not Humanoid.AutoRotate and not Player.InCutscene.Value then
Humanoid.AutoRotate = true
end
if Humanoid.CameraOffset.Magnitude > 0 then
Humanoid.CameraOffset = Vector3.new(0, 0, 0)
end
end
end)
Here’s the script I use in my game. It works by creating 3 number values and using those as the offset of the camera. You can change the values to whatever you need.
-- in a script in StarterPlayerScripts
-- this script is for setting the camera's offset
local plr = game.Players.LocalPlayer
local Camera = workspace.CurrentCamera
local context = game.ContextActionService
local rs = game["Run Service"]
local sensitivity = 0.4
local xAngle = 0
local yAngle = 0
-- adjust these values to change the offset of the camera
local ValX = Instance.new("NumberValue", plr)
ValX.Name = "CameraPosValu1X"
ValX.Value = 2
local ValY = Instance.new("NumberValue", plr)
ValY.Name = "CameraPosValueY"
ValY.Value = 0
local ValZ = Instance.new("NumberValue", plr)
ValZ.Name = "CameraPosValueZ"
ValZ.Value = 8
local cameraPos = Vector3.new(ValX.Value,ValY.Value,ValZ.Value)
wait(0.01)
Camera.CameraType = Enum.CameraType.Scriptable
context:BindAction("CameraMovement", function(_,_,input)
xAngle = xAngle - input.Delta.x*sensitivity
yAngle = math.clamp(yAngle - input.Delta.y*sensitivity,-80,80)
end, false, Enum.UserInputType.MouseMovement)
rs.RenderStepped:Connect(function()
local m = plr:GetMouse()
game.UserInputService.MouseBehavior = Enum.MouseBehavior.LockCenter
local c = plr.Character or plr.CharacterAdded:Wait()
local rootPart = c:FindFirstChild("HumanoidRootPart")
if c and rootPart then
local startCFrame = CFrame.new((rootPart.CFrame.p + Vector3.new(0,2,0)))*CFrame.Angles(0, math.rad(xAngle), 0)*CFrame.Angles(math.rad(yAngle), 0, 0)
cameraPos = Vector3.new(ValX.Value,ValY.Value,ValZ.Value)
local cameraCFrame = startCFrame + startCFrame:VectorToWorldSpace(Vector3.new(cameraPos.X,cameraPos.Y,cameraPos.Z))
local cameraFocus = startCFrame + startCFrame:VectorToWorldSpace(Vector3.new(cameraPos.X,cameraPos.Y,-50000))
Camera.CFrame = CFrame.new(cameraCFrame.p,cameraFocus.p)
end
end)
-- in a local script in StarterCharacterScripts
-- this script locks the player's character and turns it to where their camera is facing
local plr = game.Players.LocalPlayer
local cam = workspace.CurrentCamera
game["Run Service"].RenderStepped:Connect(function()
if plr.Character then
local rootPart = plr.Character:WaitForChild("HumanoidRootPart")
if rootPart then
local lookingCFrame = CFrame.lookAt(rootPart.Position, cam.CFrame:PointToWorldSpace(Vector3.new(0, 0, -100000)))
rootPart.CFrame = CFrame.fromMatrix(rootPart.Position, lookingCFrame.XVector, rootPart.CFrame.YVector)
end
end
end)