Strange camera behaviour with offset

Hey guys, recently I have been working on a game that needs to have an over the shoulder camera system that lets the mouse move freely.

I tried changing the camera offset of the Humanoid, but this leads to some strange behaviour, such as the camera not following the player properly, as seen in this video:

The player turns and only around 0.5 seconds later the camera starts following again.

Does anyone have a way to fix this problem?

You just need to make a local script that constantly sets UserInputService.MouseBehavior=Enum.MouseBehavior.LockCenter every frame.

Would this not be very performance intensive and inefficient?

It would not. Code that runs every frame is necessary for almost any game, at some point in its development. It is also pretty performant if properly set up. If you’re worried about the performance of the code in which I sent, you can assign variables to the UserInputService service and the desired mouse behavior enumeration.

Now, I recently created some code for a similar problem. In fact, it might be the exact solution to this problem as well. Here’s the code:

local char = script.Parent;

local HumanoidRootPart = char:WaitForChild("HumanoidRootPart");

local Humanoid = char:WaitForChild("Humanoid");

local RunService = game:GetService("RunService");

local CurrentCam = workspace.CurrentCamera;

Humanoid.CameraOffset = Vector3.new(2, 2, 3);
Humanoid.AutoRotate = false;

local XY = Vector3.new(1, 0, 1);

RunService:BindToRenderStep("OTSCam", Enum.RenderPriority.Character.Value, function(dt)
	local Position = HumanoidRootPart.CFrame.Position;
	local CameraLook = CurrentCam.CFrame.LookVector;
	local Direction = CFrame.lookAt(Position, Position + (CameraLook * XY));
	HumanoidRootPart.CFrame = HumanoidRootPart.CFrame:Lerp(Direction, dt * 10);
end)

This will not only set the camera offset, but will also orient the character so that the offset stays the same, while also maintaining a smooth movement system. “OTS” is referred to as “Over the Shoulder”, since this is intended to be a 2nd person, or over the shoulder camera.

This simply orients your character like mouselock was on but does not require the mouse to be locked in the center. I personally recommend this approach so that players can interact with the GUI without their mouse being locked in place.

1 Like

It’s to do with how the offset is applied. The camera system shifts the “focus” cframe relative to the HumanoidRootParts CFrame, so in the case of your video it’s always to the right of the HumanoidRootPart.

Most third person cameras opt to instead position the camera to the right of the character, relative to the camera and not the root part. You can do that by recalculating the value for CameraOffset every frame so it’s offset is relative to the camera.

The solution @SubtotalAnt8185 replied with works great but if you just want to edit the CameraOffset only, try the following in the same RenderStep connection:

	-- rebuild the camera cframe so it's "flat" with no position
	local cameraCF = workspace.CurrentCamera.CFrame
	local cameraLookFlat = cameraCF.LookVector * XY -- XY = 1, 0, 1
	local cameraCFrameFlat = CFrame.new(Vector3.zero, cameraLookFlat)
	
	-- make the offset vector in camera space
	-- then translate it back relative to the root part
	local rootCF = HumanoidRootPart.CFrame
	local offsetGoal = (cameraCFrameFlat + rootCF.Position) * Offset -- (2, 0, 0)
	local newOffset = rootCF:PointToObjectSpace(offsetGoal)
	
	-- apply the new camera-relative offset
	Humanoid.CameraOffset = newOffset
1 Like

Thank you, this actually functions very well! The only problem is that when i move or rotate my camera, it becomes very jittery:

If there any possible way to fix this?

This is similar to what I want, but while this script rotates the character as well, I just want to have a camera offset with no weird movement.
Thank you for replying though!

This is the problem I was facing using my previous solution. Unfortunately, there isn’t a really good way to fix this, not that I know of. However, you could try Humanoid.CameraOffset = Humanoid.CameraOffset:Lerp(newOffset, dt * 10) for a smoother movement.

Sadly this does not work. I find it strange why the jittering even happens in the first place, as the code is being run every frame. I’m sure there’s a logical explanation but I can’t think of it.

It has to do with the camera module’s way of updating frames. I’m not sure how to correctly do this without making a camera system yourself.