Help with .TouchEnded event

Hello Developers! I am having trouble with .Touched and .TouchEnded.

So, I scripted this so a Gui would pop up when you touch a part, and go down when you get off the part. It worked on the first playtest, until it randomly stopped and stayed popped up even though I was off the platform, and then every other playtest it didn’t work at all. I didn’t change anything. Here is the script. I think it is .TouchEnded that isn’t working.

local part = script.Parent
local players = game:GetService("Players")
local starterGui = game:GetService("StarterGui")
local screengui = starterGui:FindFirstChild("ScreenGui")
local frame = screengui.Frame
frame.Position = UDim2.new(0, 0,1.2, 0)
local talking = false

part.Touched:Connect(function(hit)
	if hit.Parent:FindFirstChild("Humanoid") and talking == false then
		local character = hit.Parent
		local player = players:GetPlayerFromCharacter(character)
		local playerGui = player:WaitForChild("PlayerGui")
		local screenGui = playerGui:WaitForChild("ScreenGui")
		local frame = screenGui:WaitForChild("Frame")
		local nextframe = frame:WaitForChild("NextFrame")
		local nextbutton = nextframe:WaitForChild("NextButton")
		local talktext = frame:FindFirstChild("TalkText")
		frame:TweenPosition(UDim2.new(0, 0,0.73, 0), "Out", "Back")
	end	
end)

part.TouchEnded:Connect(function(hit)
	if hit.Parent:FindFirstChild("Humanoid") and talking == false then
		local character = hit.Parent
		local player = players:GetPlayerFromCharacter(character)
		local playerGui = player:WaitForChild("PlayerGui")
		local screenGui = playerGui:WaitForChild("ScreenGui")
		local frame = screenGui:WaitForChild("Frame")
		local nextframe = frame:WaitForChild("NextFrame")
		local nextbutton = nextframe:WaitForChild("NextButton")
		local talktext = frame:FindFirstChild("TalkText")
		frame:TweenPosition(UDim2.new(0, 0,1.2, 0), "Out", "Back")
	end
end)

Try replacing this section with this one shown below, and see if it changes anything. You could have just forgotten to replace talking == false with talking == true.

part.TouchEnded:Connect(function(hit)
	if hit.Parent:FindFirstChild("Humanoid") and talking == true then
2 Likes

It’s nothing to do with talking. That is supposed to be false.

The popup says “Press E to talk” and then basically they can’t leave while their talking to the NPC. I haven’t got onto that bit you though.

I remember using TouchEnded for a store gui, the problem is that when the character walks, the animation moves a part of the character away from the ground, making it no longer detect it, why dont you test magnitude?

Distance = 15

while wait()do 
	for i,v in pairs(workspace:GetChildren()) do 
		if game.Players:FindFirstChild(v.Name) then 
			if(v.PrimaryPart.Position - script.Parent.Position).magnitude <= Distance then 
				-- Show Gui
			else 
				-- Hide Gui
			end 
		end 
	end 
end
2 Likes

Hey there! Thanks for your reply. If I put this, where do I put and talking == true then

See my script.

It is no longer necessary to place “hit” since the player has already been detected, where it says “Show Gui” you put your part touched code and in “Hide Gui” part touchended

local Distance = 15
local talking = false

while wait()do 
	for i,v in pairs(workspace:GetChildren()) do 
		if game.Players:FindFirstChild(v.Name) then 
			if(v.PrimaryPart.Position - script.Parent.Position).magnitude <= Distance then 
				if talking == false then
					-- Show Gui
				end
			else 
				if talking == true then
					-- Hide Gui
				end
			end 
		end 
	end 
end

Is distance measured in studs?

@mari230899,
Do I just get rid of local char = hit.parent line?

Those are small details, if you want an exact amount just place a “part” and lengthen it, in the properties of the part you go to Size and see it. Im not really sure if they are exactly studs but I think so

and about the character = hit.Parent, replace only with “v”
local character = v

1 Like

Do I need to keep this bit at the top?

local part = script.Parent
local players = game:GetService("Players")
local starterGui = game:GetService("StarterGui")
local screengui = starterGui:FindFirstChild("ScreenGui")
local frame = screengui.Frame
frame.Position = UDim2.new(0, 0,1.2, 0)
local talking = false

Yes, you need it as I said before keep that and paste your own script from:

local player = players:GetPlayerFromCharacter(character)
local playerGui = player:WaitForChild("PlayerGui")
local screenGui = playerGui:WaitForChild("ScreenGui")
local frame = screenGui:WaitForChild("Frame")
local nextframe = frame:WaitForChild("NextFrame")
local nextbutton = nextframe:WaitForChild("NextButton")
local talktext = frame:FindFirstChild("TalkText")
frame:TweenPosition(UDim2.new(0, 0,0.73, 0), "Out", "Back")

Use your same script replacing “Show Gui” and Hide Gui "

1 Like

So, Unfortunately, I have run into an issue. When I join the game, there is no popup (Good.) When I step on the platform, the popup comes up. (Good.)

When I step off, it stays on the screen. (Bad.)

I have found out myself, at first you dont change the value of talking at any time
The script should look like this:

local Distance = 15
local talking = false
local players = game:GetService("Players")
local starterGui = game:GetService("StarterGui")
local screengui = starterGui:FindFirstChild("ScreenGui")
local frame = screengui.Frame
frame.Position = UDim2.new(0, 0,1.2, 0)

while wait()do 
	for i,v in pairs(workspace:GetChildren()) do 
		if game.Players:FindFirstChild(v.Name) then 
			if(v.PrimaryPart.Position - script.Parent.Position).magnitude <= Distance then 
				if talking == false then
					local character = v
					local player = players:GetPlayerFromCharacter(character)
					local playerGui = player:WaitForChild("PlayerGui")
					local screenGui = playerGui:WaitForChild("ScreenGui")
					local frame = screenGui:WaitForChild("Frame")
					local nextframe = frame:WaitForChild("NextFrame")
					local nextbutton = nextframe:WaitForChild("NextButton")
					local talktext = frame:FindFirstChild("TalkText")
					talking = true
					frame:TweenPosition(UDim2.new(0, 0,0.73, 0), "Out", "Back")
				end
			else 
				if talking == true then
					local character = v
					local player = players:GetPlayerFromCharacter(character)
					local playerGui = player:WaitForChild("PlayerGui")
					local screenGui = playerGui:WaitForChild("ScreenGui")
					local frame = screenGui:WaitForChild("Frame")
					local nextframe = frame:WaitForChild("NextFrame")
					local nextbutton = nextframe:WaitForChild("NextButton")
					local talktext = frame:FindFirstChild("TalkText")
					frame:TweenPosition(UDim2.new(0, 0,1.2, 0), "Out", "Back")
					talking = false
				end
			end 
		end 
	end 
end

It works?

1 Like

Wt i wud recommend is using Region3 or any other module like Zone+ by @ForeverHD.

I don’t actually want to change talking at all. I will do that later in the script.

And it doesn’t work…

Oh… so if you dont want to change “talking” at least for now, then where it says if talking == true, you change it to false and remove the lines of code where the variable is changed

To shorten the conversation, you should test magnitude like character.Humanoid.Health = 0 and things like that

1 Like

Use this code to check if plr is inside prt. Code by @blokav

-- Script inside the part

local players = game:GetService("Players")

local function isInsideBrick(position, brick)
	local v3 = brick.CFrame:PointToObjectSpace(position)
	return (math.abs(v3.X) <= brick.Size.X / 2)
		and (math.abs(v3.Y) <= brick.Size.Y / 2)
		and (math.abs(v3.Z) <= brick.Size.Z / 2)
end

local insideBlock = {}

local function check()
	for _, player in ipairs(players:GetPlayers()) do
		if (player.Character and player.Character:FindFirstChild("HumanoidRootPart")) then
			if (isInsideBrick(player.Character.HumanoidRootPart.Position)) then
				if (not insideBlock[player]) then
					insideBlock[player] = true
					
				end
			else
				if (insideBlock[player]) then
					insideBlock[player] = false
					
				end
			end
		end
	end
end

game:GetService("RunService").Heartbeat:Connect(check)

Now juz fire a remotevent to client whenever to all the clients and run ur code.

OR

function getIfPlrInPart(HumanoidRootPart, Part)
    local c = HumanoidRootPart.Touched:Connect(function() end) 
    local parts = HumanoidRootPart:GetTouchingParts()
    c:Disconnect()
    
    for i, v in ipairs(parts) do
        if v == part then
            return true
        end
    end
    
    return false
end

I removed those lines of code. Still popup is staying when you leave the part.

Sorry for late reply I had homework.

I have tried with frame.Visible = false and it works, I think the problem is the TweenPosition, it should work if you replace TweenPosition [when pulling out the frame] with frame.Visible = false

1 Like

Okay, it kinda works now
I got rid of the tween when it was going down and now it works but the only thing is that you need to step quite far off the part to go away. It should be as soon as you step off it. It doesn’t do this with stepping on it, like the distance has been increased when you try to step off. I set the distance to 12, as that worked more for stepping on.