Torso.CFrame is incorrect when in first person (in RenderStep)

Hello!

I’m having a little problem with Torso.CFrame in my RunService:BindToRenderStep(...) function.
I’m trying to position a part right in front of the Torso:

local function onRender(dt)
	Camera = workspace.CurrentCamera
	p.CFrame = Torso.CFrame:ToWorldSpace(CFrame.new(0, 0, -5))
end

RunService:BindToRenderStep("onRender", Enum.RenderPriority.Last.Value, onRender)

And this works fine in third person!

But when I go into first person…

I’ve tried Enum.RenderPriority.Camera.Value + 1, Enum.RenderPriority.Character.Value + 1, -1, HeartBeat, RenderStepped, Stepped, nothing works.

2 Likes

I’m sorry, I don’t see the issue here. It appears to be working fine? If you’re annoyed about it being “laggy” try using TweenService instead of just setting the position, RenderStepped is based on FPS and so it can randomly jump from .2 seconds to .5 seconds, for example.

1 Like

My framerate is not laggy, Torso.CFrame is just not smooth, look at the mouse and the part, you will notice that the mouse is not aligned with the part even though both of them should be in the middle of the screen, but in third person it works perfectly fine. (The part is perfectly aligned in front of the Torso)

battattack is right, because RenderStepped is capped at 60 Hz, the part position refresh rate is limited as well. Works perfectly fine in third person, however, in first person, the positional changes on screen are much bigger and quicker. Consider the awkward drawing below as an example. The longer the path, the bigger the segments. When the distance from the torso/root part is 0, 60 Hz update is enough for the human eye not to perceive stutter.

image

Perhaps use welds or weld constraints instead. Roblox physics is updated at 240 Hz (and with adaptive time stepping by default).

local player = game:GetService("Players").LocalPlayer
local character = player.Character or player.CharacterAdded:Wait()
local rootPart = character:WaitForChild("HumanoidRootPart") -- torso in R6

local part = Instance.new("Part")
part.CanCollide, part.Anchored = false, false

local weld = Instance.new("Weld")
weld.Part0 = rootPart
weld.Part1 = part
weld.C0 = CFrame.new(0,0,-5)
weld.Parent = part
part.Parent = workspace

I understand what you mean (and thanks for the effort), but the problem isn’t about unnoticable stutter at all, see this video for yourself.

My intention was to move the arm (which can’t simply use welds), not a part,
I just used a part for demonstration.

1 Like

Just tested the code myself, and everything is working fine for me. Can you explain your problem in more detail? I’m not seeing any errors/difficulties here.

1 Like

Could you show me a video? It just doesn’t work for me.
Also try moving the camera fast enough.

1 Like

Unfortunately I cannot send a video at the moment but I still see no issue other than it stuttering a bit. It is being centred, and I don’t see what you’re complaining about

I’m complaining about my FPS arms stuttering, I think it’s clear why that would be an issue.

1 Like

We’ve already explained some reasonable solutions for you, also try using CFrame:Lerp too if you don’t want to use something like TweenService. Don’t say it’s not what you’re complaining about previously when it is.

1 Like

I cannot use a weld.
Again, I’m trying to move the player’s character’s ARM, it has it’s own Motor6D attachment which I want to keep in order to preserve animations, and basically not delete an organ. (It will probably fall into the void on server)
I have to change the RightShoulder (Motor6D) C0 value to position the arm where I need, and since it’s relative to the Torso, the issue has to happen, unless I update it in the right timing, AFTER the torso updates and BEFORE the game renders the next frame. (Not sure about this timing, but that’s what I came up with)

Now I’m thinking it would be easier to create a separate view model. The arm’s CFrame is still away from the camera, which will always make the stutter appear like the frame rate is lower than 60 Hz. Most first person games, especially shooters, have a view model completely separate from the character everyone else sees. Then the root of the view model can be updated each render cycle to the camera’s CFrame. Because the distance between camera and root is 0, the update is seemingly smoother too. And the rest of the model is connected using Motor6Ds.

I’m talking about what EgoMoose created in this neat FPS tutorial.

Completely agree with @waves5217 here- why are you using the Player’s actual arm? Just use a viewmodel, that’s what most games do.

2 Likes

Thanks, I want to avoid creating a ViewModel to simplify other things though.
I will have to make one if I’m unable to fix this anyways.

But again the problem is not with framerate at all, it’s just that the Torso.CFrame is inconsistent with the camera, although it should be.
In first person, the torso’s direction should always be the same as the camera (on the Y-axis), while in third person it doesn’t have to.
This means that when I rotate the camera in first person, the torso isn’t actually pointing towards the camera’s direction when my onRender function is called.
BUT in third person, even when I rotate the torso while moving the camera, there is no stutter.

1 Like

@waves5217 has already explained this, you keep on repeating the same thing and I don’t quite think you understand. It basically in short is stutter because RenderStepped is capped at 60 Hz, first person mode has larger distances because your mouse moves faster, meaning faster the mouse moves, the less it will keep up. A potential fix is to check if the LocalTransparency of the RightArm is 0 while other parts have it at 1 so that you can check for if the player is in first person, and potentially use Camera.CFrame but that will most likely also have the same issue.

1 Like

You don’t understand me.
If the problem is with larger distances, then moving the camera fast in third person should have the same problem, no?

But hey, guess what:

Very smooth in third person, very jittery in first person.

1 Like

This is because in first person your character model moves/rotates with your camera, and that is where the CFrame is coming from, but when you’re in third person the movement of camera doesn’t affect character movement/rotation… :woman_facepalming:

1 Like

Yet when I rotate the character in third person the arm AND the part still move fine and smoothly.

I found the solution, all I had to do was force rotate the character towards the camera’s direction myself before modifying the arm or the part, thanks for the help though =D

local rx, _, rz = Root.CFrame:ToEulerAnglesYXZ()
local _, cy = Camera.CFrame:ToEulerAnglesYXZ()
Root.CFrame = CFrame.new(Root.Position) * CFrame.fromEulerAnglesYXZ(rx, cy, rz)

Here is a video if you want to feel the sweet victory with me

4 Likes

Oh dear, you beat me in timing. I just actually built a similar view model for the testing and was coming to a similar conclusion that auto rotation might have to be overridden. I’m very happy that you found the solution. Bonne journee!

1 Like