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.
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.
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
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.