Parts snap back to original position after moving

Everything besides the GUI and screen to world point is managed on the server, so idk whats wrong.

This looks like the part is being moved by a LocalScript, but the server isn’t being updated with the final position. Unless you tell the server about the new position, any changes made on the client will be overridden by the server’s authoritative state shortly after.

like i said, everything is done on the server besides getting the mouse pos and toggling ui. Heres the code:

Client:

local Mouse = game.Players.LocalPlayer:GetMouse()
local Grab = game.ReplicatedStorage:WaitForChild("Grab")

local LDown = false
local RDown = false


local CurrentLWeld = nil
local CurrentRWeld = nil

local MousePosWorld = nil
local MouseHitPart = nil

local Player = game.Players.LocalPlayer
local Character = Player.Character

local LHand = Character:WaitForChild("LHand")
local RHand = Character:WaitForChild("RHand")

Character.L.Attachment1 = LHand.Attachment
Character.R.Attachment1 = RHand.Attachment

Player.PlayerGui.L.Adornee = LHand
Player.PlayerGui.R.Adornee = RHand


Mouse.Button1Down:Connect(function()
	Grab:FireServer(Character, MousePosWorld, MouseHitPart, "L")
	LDown = true
	--LHand.Position = MousePosWorld
	Player.PlayerGui.L.Enabled = true
	script.Parent.L.Visible = false
	--Character.L.Enabled = true
	--LHand.Grab:Play()
	--CurrentLWeld = Weld(MouseHitPart, LHand)
	--LHand.Anchored = false
end)

Mouse.Button1Up:Connect(function()
	Grab:FireServer(Character, nil, nil, "L")
	LDown = false
	Player.PlayerGui.L.Enabled = false
	script.Parent.L.Visible = true
	--Character.L.Enabled = false
	--LHand.Leggo:Play()
	--CurrentLWeld:Destroy()
	--LHand.Anchored = true
end)


Mouse.Button2Down:Connect(function()
	Grab:FireServer(Character, MousePosWorld, MouseHitPart, "R")
	RDown = true
	--RHand.Position = MousePosWorld
	Player.PlayerGui.R.Enabled = true
	script.Parent.R.Visible = false
	--Character.R.Enabled = true
	--RHand.Grab:Play()
	--CurrentRWeld = Weld(MouseHitPart, RHand)
	--RHand.Anchored = false
end)

Mouse.Button2Up:Connect(function()
	Grab:FireServer(Character, nil, nil, "R")
	RDown = false
	Player.PlayerGui.R.Enabled = false
	script.Parent.R.Visible = true
	--Character.R.Enabled = false
	--RHand.Leggo:Play()
	--CurrentRWeld:Destroy()
	--RHand.Anchored = true
end)








local UserInputService = game:GetService("UserInputService")
local Mouse = game:GetService("Players").LocalPlayer:GetMouse()


Mouse.TargetFilter = Character

while task.wait() do
	--local inputPosition = inputObject.Position
	-- ViewportPointToRay would probably be more accurate to use here
	local mouseUnitRay = workspace.CurrentCamera:ScreenPointToRay(Mouse.X, Mouse.Y)
	-- Long rays are expensive, so I set it to 500
	local mouseRay = Ray.new(mouseUnitRay.Origin, mouseUnitRay.Direction * 500)
	local target, hit = workspace:FindPartOnRay(mouseRay, Mouse.TargetFilter)
	MousePosWorld = hit
	MouseHitPart = target
end

Server:

local Event = game.ReplicatedStorage:WaitForChild("Grab")


local function Weld(Part, Hand)
	local WeldConstraint = Instance.new("WeldConstraint")
	WeldConstraint.Parent = Hand
	WeldConstraint.Part0 = Part
	WeldConstraint.Part1 = Hand

	return WeldConstraint
end


Event.OnServerEvent:Connect(function(Player, Character, WorldPos, HitPart, Hand)
	
	if WorldPos ~= nil then --If its nil then it means ur ungrabbing or whatever\
		Character[Hand.."Hand"].Position = WorldPos
		Character[Hand].Enabled = true
		Weld(HitPart, Character[Hand.."Hand"])
		Character[Hand.."Hand"].Anchored = false
	else
		Character[Hand.."Hand"].WeldConstraint:Destroy()
		Character[Hand].Enabled = false
		Character[Hand.."Hand"].Anchored = true
	end
	
end)

Like i said, nothing movement wise is done on the client.

the easiest way to get around this would be to set the network ownership of the interacted part to client, rather than firing remote events

i’m not very experienced with network ownerships since i never used it, but hopefully you can decipher the docs

Let’s do both. It would be better to SetNetworkOwner anyways.

Version: 3
Server:

local Event = game.ReplicatedStorage:WaitForChild("Grab")

local welds = {}

local function Weld(Part, Hand)
	local WeldConstraint = Instance.new("WeldConstraint")
	WeldConstraint.Parent = Hand
	WeldConstraint.Part0 = Part
	WeldConstraint.Part1 = Hand
	return WeldConstraint
end

Event.OnServerEvent:Connect(function(player, character, worldPos, hitPart, hand)
	local handPart = character[hand.."Hand"]
	if worldPos then
		handPart.Position = worldPos
		character[hand].Enabled = true
		hitPart.Position = worldPos
		hitPart:SetNetworkOwner(nil)
		if not welds[handPart] then
			welds[handPart] = Weld(hitPart, handPart)
		end
		handPart.Anchored = false
	else
		if welds[handPart] then
			welds[handPart]:Destroy()
			welds[handPart] = nil
		end
		character[hand].Enabled = false
		handPart.Anchored = true
		if hitPart then hitPart:SetNetworkOwner(nil) end
	end
end)

issue with this is that other players cnat see you moving parts untill its been let go

i fixed it, forget to make 2 lines of code server sided

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