Motor6D replication issues. Server is overwriting client

I recently created this script that makes the character look up or down by modifying the Motor’s C0. This works but since its client sided only i decided to replicate the code into a server script and get the client to just send the current viewAngle.

Client side code:

local function MouseInputLoop()
	local sensitivity = settingFolder.Sensitivity.Value
	y += mouse.Value.X * BASE_SENSITIVITY * sensitivity
	x = Clamp(x + mouse.Value.Y * BASE_SENSITIVITY * sensitivity, -MAX_LOOK_ANGLE, MAX_LOOK_ANGLE)
	aimRemote:FireServer(x)
end

local function MotorLoop()
	local moveVelocity = char.Humanoid:GetMoveVelocity()
	local speed = moveVelocity.Magnitude

	local roll =  not char:GetAttribute("Aiming") and Clamp(charParts.RootPart.CFrame:VectorToObjectSpace(moveVelocity).X / char.Humanoid.WalkSpeed, -1, 1) * Rad(10) or 0
	local pitch = speed > 0 and Clamp(charParts.RootPart.CFrame:VectorToObjectSpace(moveVelocity).Z / char.Humanoid.WalkSpeed, -1, 1) * Rad(10) or 0
	leanSpring.Target = pitch
	rollSpring.Target = roll
	
	--Updates rootPart per frame to point with camera
	local cf = CFrame.new(charParts.RootPart.CFrame.Position)
	charParts.RootPart.CFrame = cf * CFrame.Angles(0, -y, 0)

	local waistAngle = -x/2

	--Makes torso move up and down based on camera
	motors.Waist.C0 *= CFrame.Angles(waistAngle, 0, -rollSpring.Position)
	--char.UpperTorso.Waist.Transform *= CFrame.Angles(-x, 0, 0)
	motors.Neck.C0 *= CFrame.Angles(-x + x/2, 0, 0)
	motors.Root.C0 *= CFrame.Angles(leanSpring.Position, 0, 0)

	--moves camera to camera part
	local camOffset = char:GetAttribute("CameraOffset")
	local armAngle = x/2 - leanSpring.Position

	motors.RightShoulder.C0 *= CFrame.Angles(-x + armAngle, 0, 0)
	motors.LeftShoulder.C0 *= CFrame.Angles(-x + armAngle, 0, 0)
	
	motors.Eyes.C0 = CFrame.new(charParts.Head.CFrame:ToObjectSpace(charParts.RootPart.CFrame):Inverse().Position) * camOffset * CFrame.Angles(-x, 0, -rollSpring.Position/2)
end

local function CameraLoop()		
	cam.CFrame = charParts.CamPart.CFrame
	char.Head.LocalTransparencyModifier = 1
end

--Runs first, Reset motors from previous frame
runService:BindToRenderStep("ResetMotors", Enum.RenderPriority.Input.Value, function()
	ResetMotors()
	MouseInputLoop()
end)

--Runs second, modifies the motors depending on movement and where the player is looking
runService:BindToRenderStep("UpdateMotors", Enum.RenderPriority.Camera.Value, MotorLoop)

--Updates the camera after all motors were updated, including modifications done by the recoil profile
runService:BindToRenderStep("Render", Enum.RenderPriority.Last.Value, CameraLoop)

Server Side:

local aimConnection = game["Run Service"].Stepped:Connect(function()
			smoothSpring.Target = char:GetAttribute("VerticalAngle")
			
			local moveVelocity = char.Humanoid:GetMoveVelocity()
			local speed = moveVelocity.Magnitude

			local roll =  not char:GetAttribute("Aiming") and math.clamp(char.HumanoidRootPart.CFrame:VectorToObjectSpace(moveVelocity).X / char.Humanoid.WalkSpeed, -1, 1) * math.rad(10) or 0
			local pitch = speed > 0 and math.clamp(char.HumanoidRootPart.CFrame:VectorToObjectSpace(moveVelocity).Z / 20, -1, 1) * math.rad(10) or 0
			leanSpring.Target = pitch
			rollSpring.Target = roll
			
			char.LowerTorso.Root.C0 = CFrame.new(char.LowerTorso.Root.C0.Position) * CFrame.Angles(leanSpring.Position, 0, 0)
			
			local current = Vector3.new(char.UpperTorso.Waist.C0:ToOrientation())
			char.UpperTorso.Waist.C0 = CFrame.new(char.UpperTorso.Waist.C0.Position) * CFrame.Angles(-smoothSpring.Position/2, current.Y, -rollSpring.Position)
			char.Head.Neck.C0 = CFrame.new(char.Head.Neck.C0.Position) * CFrame.Angles(-smoothSpring.Position + smoothSpring.Position/2, 0, 0)
			
			char.RightUpperArm.RightShoulder.C0 = CFrame.new(0.926, 0.548, 0.043) * CFrame.Angles(-smoothSpring.Position + smoothSpring.Position/2 - leanSpring.Position, 0, 0)
			char.LeftUpperArm.LeftShoulder.C0 = CFrame.new(-0.926, 0.548, 0.043) * CFrame.Angles(-smoothSpring.Position + smoothSpring.Position/2 - leanSpring.Position, 0, 0)
		end)

It replicates properly, but my issue is that the server’s motors are trying to overwrite the client’s, because of both sides fighting for the motors, it causes the gun to stutter between the server and client’s positions.

video:

In the video the arms dont look like theyre stuttering but you can see from the crosshair that it is, so when i fire the weapon it has a random chance of either firing from the client’s position or the server’s position.

Is there a way to stop the server from trying to overwrite the client? I need the server to replicate it because the weapon’s validation code requires the position of the muzzle, and if it didnt replicate, the server’s muzzle will always not closely match with the client’s.

I simply resorted to creating a server clone for every character, which copies the animations and motor offsets using the look angle, and using that strictly for validation.

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.