Adding an event when 2 parts are touched


robloxapp-20220812-1424028.wmv (1.7 MB)
Hi guys, I’m writing a script that is supposed to teleport two players into a arena when both parts are being touched by the players… nothing I do seems to work, does anyone have any idea how I can do this, here is my code and also a vid to give u an idea of what im trying to do. Thanks for any help!

Could you please type the scripts as the forum format?
Such as:

local t = {}

for _,item in pairs(Items) do
    --...
end

So that it’d be easier for us to help you.

1 Like
local start1 = workspace.start1
local start2 = workspace.start2

local isTouched1 = false
local isTouched2 = false

local playGui = game.StarterGui.SwordFightPlay.PlayButton

local team1 = game.Workspace.Team1
local team2 = game.Workspace.Team2

playGui.Visible = false

local start1OriginalColor = start1.BrickColor
local start2OriginalColor = start2.BrickColor

game.ReplicatedStorage.RemoteFunction.OnServerInvoke = function(Player, Task, Action)
	if typeof(Task) ~= "string" then print (" Make sure the first Argument is in Quotation Marks and is a string! It should also be inside the server script tasks i.e: Task == THE FIRST ARGUMENT") return end
	if typeof(Action) ~= "boolean" then print(" Make Sure the Action (Second Argument is either true or false!)") return end

	if Task == "ChangeStart1" then
		if Action == true then
			-- CHANGE START 1 BRICK COLOR HERE
			start1.BrickColor = BrickColor.new("Teal")
			isTouched1 = true
		elseif Action == false then
			-- If you want to change it back or something
			start1.BrickColor = start1OriginalColor
			isTouched1 = false
		end
	elseif Task == "ChangeStart2" then
		if Action == true then
			-- CHANGE START 2 BRICK COLOR HERE
			start2.BrickColor = BrickColor.new("Teal")
			isTouched2 = true

		elseif Action == false then
			-- If you want to change it back or something
			start2.BrickColor = start1OriginalColor
			isTouched2 = false
		end
	end
end

if isTouched1 and isTouched2 == true then
	
end

(thats the server script)

local start1 = workspace.start1
local start2 = workspace.start2

-- Get if it's touched
local isTouched1 = false
local isTouched2 = false

-- if start1 is touched then it sends information to server
start1.Touched:Connect(function()
	-- part is being touched
	isTouched1 = true
	game.ReplicatedStorage.RemoteFunction:InvokeServer("ChangeStart1", isTouched1)
end)

-- start1 touched ended
start1.TouchEnded:Connect(function()
	-- not touching so tells server what to do once touch ends
	isTouched1 = false
	game.ReplicatedStorage.RemoteFunction:InvokeServer("ChangeStart1", isTouched1)
end)

start2.Touched:Connect(function()
	isTouched2 = true
	game.ReplicatedStorage.RemoteFunction:InvokeServer("ChangeStart2", isTouched2)
end)

start2.TouchEnded:Connect(function()
	isTouched2 = false
	game.ReplicatedStorage.RemoteFunction:InvokeServer("ChangeStart2", isTouched2)
end)

(local script inside starterplayerscripts)

There is no need to make a custom RemoteFunction for Part.Touched and Part.TouchEnded as they also fire server-side, (However, even then, It would be good practice to use a RemoteEvent for things that need replication instead of a RemoteFunction, since you don’t seem to do anything with return values in it)
You are also checking if they are both being touched only once (in the beginning of the scripts lifetime) and seem to fail checking if the parts that collide with the boxes are actually even characters.

I would reccomend doing something like this:
(Server Script)

local start1 = workspace.start1
local start2 = workspace.start2

local isTouched1 = false
local isTouched2 = false

local playGui = game.StarterGui.SwordFightPlay.PlayButton

playGui.Visible = false

local start1OriginalColor = start1.BrickColor
local start2OriginalColor = start2.BrickColor

start1.Touched:Connect(function(p)
	if p.Parent and p.Parent:FindFirstChild("Humanoid") ~= nil then
		start1.BrickColor = BrickColor.new("Teal")
		isTouched1 = true
		if isTouched2 then -- no need to check isTouched1 since we already set it to true
			-- do stuff since it appears twice, should replace with a function that does it --
		end
	end
end)
start2.Touched:Connect(function(p)
	if p.Parent and p.Parent:FindFirstChild("Humanoid") ~= nil then
		start2.BrickColor = BrickColor.new("Teal")
		isTouched2 = true
		if isTouched2 then
			-- do stuff since it appears twice, should replace with a function that does it --
		end
	end
end)
start1.TouchEnded:Connect(function(p)
	if p.Parent and p.Parent:FindFirstChild("Humanoid") ~= nil then
		start1.BrickColor = start1OriginalColor
		isTouched1 = false
	end
end)
start2.TouchEnded:Connect(function(p)
	if p.Parent and p.Parent:FindFirstChild("Humanoid") ~= nil then
		start2.BrickColor = start2OriginalColor
		isTouched2 = false
	end
end)
1 Like

Thank you so much, very kind of you, it works perfectly, just to confirm, do I delete everything in that local script then?

Yes, you can delete the localscript and remotes now.

1 Like

Ok, thank you very much, sorry one last question, where it says ‘do stuff twice…’ ,thats where i’m supposed to make the play gui visible right? And what do you mean by ‘should replace with a function’? Sorry for all these questions i’m new to scripting (btw im not asking what a function is, im just asking what i’m replacing). Thanks :slight_smile:

Where it says ‘do stuff twice…’ ,thats where i’m supposed to make the play gui visible right?

Yes.

And what do you mean by ‘should replace with a function’?

I meant, If you are gonna do something more than just make the gui visible, Create a function (for example: BothPartsTouched) and Replace the comment line (prefixed by “–”) with a call to it.
Example:

function BothPartsTouched()
    -- code to make gui visible
end
start1.Touched:Connect(function(p)
	if p.Parent and p.Parent:FindFirstChild("Humanoid") ~= nil then
		start1.BrickColor = BrickColor.new("Teal")
		isTouched1 = true
		if isTouched2 then -- no need to check isTouched1 since we already set it to true
			BothPartsTouched()
		end
	end
end)
start2.Touched:Connect(function(p)
	if p.Parent and p.Parent:FindFirstChild("Humanoid") ~= nil then
		start2.BrickColor = BrickColor.new("Teal")
		isTouched2 = true
		if isTouched2 then
			BothPartsTouched()
		end
	end
end)

If this only needs to happen once i would also reccommend adding a debounce

local visibleDone = false
function BothPartsTouched()
    if visibleDone then return end
    visibleDone = true
    -- code to make gui visible
end

It also seems that your planned method for showing the gui won’t apply until the user resets (aka making the gui in StarterGui visible)

function BothPartsTouched()
    if visibleDone then return end
    visibleDone = true
    for _,v in ipairs(game.Players:GetChildren()) do 
        v.PlayerGui.SwordFightPlay.PlayButton.Visible = true
    end
end

Also, in the code I posted, I overlooked a typo in it, I have now edited and corrected it in the original post.

1 Like

Thank you so much for the help, it’s all working now, the only thing is when I press the ‘exitButton’ to teleport off the pad the ‘play’ gui stays there, but i’m sure i can figure out how to sort it out. Thank you very much :slight_smile: