Can I get both parts that initiated .Touched at the time of the event?

I want to get both parts that initiated a .Touched event at the time the event was fired. For example:

local function Touched(PartB)
    print(PartB.Position)
end

PartA.Touched:Connect(Touched)

But if PartB moves fast enough (e.g., teleporting), I’ve noticed it’s possible for PartB.Position to no longer be near PartA.

I’ve tried cloning the part as the event occurred:

local function Touched(PartB)
    print(PartB.Position)
end

PartA.Touched:Connect(function(PartB)
    Touched(PartB:Clone())
end)

But this still isn’t fast enough, as PartB can teleport instantly.

Is there any way to get the part that touched it, at the exact moment .Touched was fired?


Before you ask: Yes I know .Touched() isn’t ideal, but I need to use because of legacy compatibility issues.

Bumping this because no responses :frowning:

What are you trying to do? Are you trying to get part B postilion away from part A before the touched event fires or are you just gather the information of the two parts?

.Touched is not deprecated, feel free to use it.

This is very confusing and needs more explanation. Please provide your code and or provide less psuedo code for it to be understood more.

@thegreatdabb @yewfor Basically, my problem stems from referencing the part that a .Touched event is listening to. Referencing it directly after, inside of the .Touched, references the part before the server updates it. My working hypothesis is that this stems from .Touched being fired directly from the client, which results in the server running code before the parts have updated on the server.

I’ve made an example game to demonstrate: example - Roblox
Here’s the file:
ex.rbxl (41.8 KB)

It’s simply a part with a script that detects when it’s touched, and then clones the part that touched it.
Most of the time, the cloned part won’t even be anywhere near the part itself, despite the event firing:


I’m looking for a way to get the part that touched it, at the exact moment .Touched fired. I.e., a way to clone the part and always have it be cloned shown touching the part.

I’ve messaged the Bug_Support team as I believe this is an issue with the Task Scheduler. According to it, .Touched is supposed to be one of the last things handled, after part positions are replicated to the server. From my testing, it’s pretty clear this doesn’t happen.

I won’t be closing this just yet though as I could be wrong, or someone might come up with a clever solution around this.

I’d recommend changing the cloned part’s CFrame to the part a’s CFrame to ensure that the cloned part is correctly placed where part a is supposed to be.

You can do this by storing part a’s CFrame as an argument for the Touched function and them use PivotTo:(Insert_CFrame_Variable_Here) to move the new part

the touch event has a delay which you cannot fix, You could check if it’s touching again

local function IsInPart(Part1, Part2)
	return table.find(workspace:GetPartsInPart(Part1), Part2)
end

script.Parent.Touched:Connect(function(Touch)
	if Touch:IsA("Part") and Touch.Name ~= "HumanoidRootPart" then
		local IsTouching = IsInPart(script.Parent, Touch)
		
		if not IsTouching then
			return
		end
		
		local NewTouch = Touch:Clone()
		NewTouch.BrickColor = BrickColor.new("Really blue")
		NewTouch.Anchored = true
		NewTouch.CanTouch = false
		NewTouch.CanCollide = false
		NewTouch.Massless = true
		NewTouch.Transparency = 0.5
		NewTouch:ClearAllChildren()
		NewTouch.Parent = workspace
	end
end)