I’ve made a script that connects player1’s (senders) and player2’s (receivers) hands (bottom attachments on arms) with RopeConstraint. Another thing I did is disable Motor6D connecting the shoulders for both players and connected them with RodConstraint so they the arms would be jiggly instead of being anchored to the player. This does work fine but the receiver player receives extreme input lag and choppiness when trying to move around. I’ve already tried using BasePart:SetNetworkOwner() but it didn’t fully fix the problem, as the input lag and mild choppiness was still present. Do I have to write my own system instead of using Constraints? If so, how should I implement it?
Make sure each player controls their own character’s parts. Use SetNetworkOwner() to give control of Player1’s arm to Player1, and Player2’s arm to Player2. This helps reduce lag.
Simplify Constraints: Try using fewer constraints, like just a RopeConstraint or HingeConstraint. Having too many constraints (like RodConstraint) can slow things down.
-- network ownership on both players arms
local senderArm = senderChr["Left Arm"]
local receiverArm = receiverChr["Right Arm"]
-- set the network ownership to the respective players
senderArm:SetNetworkOwner(sender)
receiverArm:SetNetworkOwner(receiver)
Using SetNetworkOwner() doesn’t fix the issue entirely. It does make the player a little less laggy, but the input delay still persists. As for simplifying constraints, how can I then make the arm attached to the player and be affected by physics?
-- Example, set arm's network ownership to the local player
arm:SetNetworkOwner(player)
--
Use a WeldConstraint to attach the arm to the player: The WeldConstraint can be used to physically connect the arm to the player’s body part , while still allowing the physics engine to affect the arm’s movements.
local player = game.Players.LocalPlayer
local character = player.Character or player.CharacterAdded:Wait()
-- Create a new Part (arm)
local arm = Instance.new("Part")
arm.Size = Vector3.new(1, 2, 1) -- Example size of an arm
arm.Position = character.Torso.Position + Vector3.new(1, 0, 0) -- Attach near torso
arm.Parent = workspace
-- Create a WeldConstraint to attach the arm to the torso
local weld = Instance.new("WeldConstraint")
weld.Part0 = arm
weld.Part1 = character.Torso -- Assuming the torso is the base part
weld.Parent = arm
If you want the arm to have rotation (like a ragdoll), you can use a BallSocketConstraint to attach the arm with some flexibility then:
local ballSocket = Instance.new("BallSocketConstraint")
ballSocket.Parent = arm
ballSocket.Attachment0 = armAttachment -- Create an attachment on the arm
ballSocket.Attachment1 = torsoAttachment -- Create an attachment on the torso
ballSocket.LimitsEnabled = true
ballSocket.TwistLimitsEnabled = true
ballSocket.TwistLowerAngle = -45
ballSocket.TwistUpperAngle = 45
ballSocket.Parent = arm
-- Let me know if you have any problems! :)
I rewrote your script, and I see a few issues, like: having both a RopeConstraint and RodConstraint applied at once on the players’ arms is unnecessary.
PromptResponse.OnServerEvent:Connect(function(_, receiver:Player, sender:Player, response)
local receiverChr = receiver.Character
local senderChr = sender.Character
if not response then
receiverChr.IsPaired.Value = false
senderChr.IsPaired.Value = false
receiverChr.ProximityPrompt.Enabled = true
senderChr.ProximityPrompt.Enabled = true
PromptSender:FireClient(sender, true)
return
end
PromptSender:FireClient(sender, "accepted")
local attachmentS = Instance.new("Attachment", senderChr["Left Arm"])
attachmentS.Name = "AttachmentS"
attachmentS.Position = Vector3.new(0, -1, 0)
local attachmentR = attachmentS:Clone()
attachmentR.Name = "AttachmentR"
attachmentR.Parent = receiverChr["Right Arm"]
local rope = Instance.new("RopeConstraint", senderChr["Left Arm"])
rope.Length = 0.3
rope.Attachment0 = senderChr["Left Arm"].AttachmentS
rope.Attachment1 = receiverChr["Right Arm"].AttachmentR
senderChr.Torso["Left Shoulder"].Enabled = false
receiverChr.Torso["Right Shoulder"].Enabled = false
local senderArm = senderChr["Left Arm"]
local receiverArm = receiverChr["Right Arm"]
senderArm:SetNetworkOwner(sender)
receiverArm:SetNetworkOwner(receiver)
end)
-- Let me know if this works! :)