I want to smoothly and responsively move a model in front of the player based on the player’s camera look vector, updating its position every heartbeat. The movement should feel stable and low-latency, without jitter.
The model’s CFrame is updated on the client based on data replicated from the server. I currently send the camera’s LookVector from the client to the server every heartbeat, then the server fires this back out to all clients to update the model’s position.
I’ve tried two movement approaches:
Tweening: Looks smoother but feels delayed and still jittery under fast camera movement.
Directly setting CFrame: More responsive, but jitter is significantly worse.
I need the server involved since the camera direction is only available on the client, but this back-and-forth seems to introduce lag and jitter, especially under unstable frame rates or network conditions.
Here is the code im using to move the model.
--CalculateCFrame
local radius = 10
local forwardVector = Parameters[3]
local targetPosition = RootPart.Position + forwardVector * radius
targetPosition = Vector3.new(targetPosition.X, RootPart.Position.Y, targetPosition.Z)
local directionToCharacter = (RootPart.Position - targetPosition).unit
targetPosition = RootPart.Position - directionToCharacter * radius
local C = (CFrame.lookAt(targetPosition, RootPart.Position) * CFrame.new(0,1.7,0)) * CFrame.Angles(math.rad(270),0,math.rad(180))
--Tween Method
-- TweenService:Create(HexaWall.PrimaryPart,TweenInfo.new(0.1,Enum.EasingStyle.Linear,Enum.EasingDirection.InOut),{CFrame = C}):Play()
--Directly Setting CFrame
HexaWall.PrimaryPart.CFrame = C
How can I smoothly move a model every frame, syncing with the camera’s look direction, without introducing jitter? Is there a better client-server hybrid method, or do I need to interpolate smarter?
I am using heartbeat, and the players camera lookvector is being sent to the server and then is replicated to all the clients where the script above is executed.
I’m not exactly sure what you’re making here, but I think the most common pattern for this is not try to manually sync a bunch of local copies by custom replication, but rather to create the model on the server and give the controlling player network ownership of it, letting replication handle it for everyone else.
If you do want to keep it all local parts, there is no reason you need it to lag for the controlling player. That is, they should not be waiting for their own camera lookVector to go to the server and back before upding their copy, just do it immediately on RenderStepped or similar, in step with their camera so it isn’t always lagging behind.
I am making an ability that moves based on a players camera and character position while holding the shift button. Here is a visual representation of the ability as well as the jitters if you look closely.
–Setting the CFrame Directly
Thats what I originally thought as well but when I just made it on the server the delay from the Characters RootPart Cframe being sent to the server caused spacing issues with the actual shield.
Players’ avatars have replication and update priority over all other parts that are updating on the server, so that’s not too surprising. The only way to force them to replicate in sync is to actually have the shield inside your character Model and possibly even constrainted to the character’s root part or something like that. Otherwise, yeah, on other clients it could lag behind due to its CFrame updates being deferred.