Viewmodel problems when using RunService

I know there are a few posts about the same issue on here, but neither of them have a solution AFAIK.

The viewmodel seems to not update properly on each .RenderStepped. I’m using the function :BindToRenderStep() for this and none of the render priorities make a difference.

I’ve simplified my code so it only sets the CFrame for the viewmodel to the Camera CFrame without any other add-ons such as walk wobble, sway etc.

Current code where I bind the :UpdateViewModel function to the RunService:

s.RunService:BindToRenderStep("ViewModel", Enum.RenderPriority.Camera.Value - 1, function(deltaTime)
	WeaponModule:UpdateViewModel(deltaTime)
end)

Video:

2 Likes

did you try RunService.RenderStepped:connect()?

2 Likes

Yes. Though, :BindToRenderStep() is pretty much equivalent to .RenderStepped just with more “control”, I’d say.

Problems like this are usually due to the wrong render priority.
You should run the viewport update code after the camera has moved, or it will appear to lag 1 frame behind the camera. Just change the renderpriority to Camera + 1, instead of Camera -1.

Hope this helps!

1 Like

Yeah, I’ve tried that. As I said, “none of the render priorities make a difference”. Thanks for your input though.

2 Likes

Ah sorry, I didn’t read all the way through the post. I just assumed it was that, because I’ve made that mistake many times myself.

If it’s not an issue with RenderPriority it might be something more subtle. Are you sure there are no issues in your :UpdateViewport function?
I’d say to test it with just a part updating to the Camera.CFrame with some offset, and see if the jittering persists.

If it does then there is some underlying issue, if not then you have some small issue in your UpdateViewport function.

2 Likes

The function is as simple as this right now (without all the add-ons) and some code after that, but should not affect it considering I apply the CFrame at once:

v.Object.PrimaryPart.CFrame = Camera.CFrame
2 Likes

If possible, could you tell us what you’re doing in this part, specifically the function you’re calling from your module?

WeaponModule:UpdateViewModel(deltaTime)

It may be because you are doing something wrong on the Updating view part. If you really want to try, try lerping the cframe, may or may not help :man_shrugging:.

1 Like

Please read the above reply where I explained what the function was.

1 Like

Then try lerping the cframe and see if that fixes it somewhat.

v.Object.PrimaryPart.CFrame = CFrame.new:Lerp(Camera.CFrame, 0.7)

I might’ve done something wrong but I believe this works?

I can already tell that lerping it will make it appear even more delayed. Lerping is essentially just smoothly transitioning a CFrame from start to the goal.

EDIT: posted accidentally before I finished writing lol

You’d be surprised how often issues like this are just caused by a small oversight. Could you just quickly try it with a part by itself? When I do it works perfectly for me.

local part = Instance.new("Part",workspace)

game["Run Service"]:BindToRenderStep("test",Enum.RenderPriority.Camera.Value + 1,function()
    part.CFrame = workspace.CurrentCamera.CFrame*CFrame.new(2,0,-5)
end)

Here is Camera.Value + 1:

Here is Camera.Value - 1:

Admittedly the jerkiness you’re getting doesn’t look exactly like this, but I’d say still worth trying quickly.

If the issue is still persisting with a single part (and assuming you aren’t moving the camera in any other script that might interfere) then you might want to post a bug report.

Maybe try running that code I posted in a completely empty place to see if the issue is with your client or something subtly wrong in your code.

2 Likes

You can make the time at the end:

v.Object.PrimaryPart.CFrame = CFrame.new:Lerp(Camera.CFrame, 0.7)

Change it’s speed, the higher the value (max is 1) the faster it goes to reach, the lower it is, the slower it is, if you want it fast and smooth, do 0.9.

Actually, I’ve somehow just noticed from your code, you’re setting the primary part very often. This is highly not recommended, overtime, the parts can slowly move away from their original positions on the models if you aren’t careful. Welding it to the primary part and cframing only the primary part is an option that works though :man_shrugging:. Or using motor6d/etc.

Tried it with a part. Still happens. Though, I’ve noticed it all comes down to where the script which is binding the function to .RenderStepped is “located” or parented to. I don’t understand why this is the case as it’s way more efficient for the workflow to have this script parented to the weapon model itself.

There must be a way to work around this without having to change which script binds it etc…

This sounds like an engine issue then. If you’re sure that’s the case I’d say to post a bug report.

As a workaround (or just to investigate more) you could experiment with modulescripts or bindableevents placed in different locations.
The location of a localscript in the datamodel should not affect how it behaves at all though, so this is very strange.

It looks like it’s skipping some frames, is it possible that the weapon is moved to a container in which localscrips can’t run briefly, or something like that?

I can confirm that this is due to where the script which binds the function to .RenderStepped is located.

Sounds like #platform-feedback:engine-bugs time, if you’re sure.

I tried with a bindableevent as well where I fired it with a script parented to the character on .RenderStepped. However, the problem still persists.

If you run that code in an empty place, does it still happen? I just tried with the script inserted into a Tool object and it was working fine.
If you have any other machines you could test on those as well.

It seems like it’s because the script I fire the function from seems to be delayed or frame capped? Because even replacing :BindToRenderStep() with BindableEvent.Event made no difference.

1 Like