Problem with TouchedEvent when the character don't move

Hello here is the problem. I have a script that check if the player is ont a part (cylinder) and if the “engine” is on. If it’s on then the player is push away… The problem here is that when the player don’t move, and the engine is turn off, he can stand in the area, but when the engine turn on again, he problably don’t detect any player (if he don’t move)…

I Hope you will understand.

Here is the code:

-- -- << 	Services >> --
local TweenService = game:GetService("TweenService")
-- << 	Variables >> --
local FansFolder = game.Workspace.Levels.Level1.Traps.Fans
local debounceTraker = {}

local tween_Info = TweenInfo.new(
	1.25,
	Enum.EasingStyle.Linear,		
	Enum.EasingDirection.In,
	3,	
	false,
	0
)

local fans1_Table = {}
local fans2_Table = {}
local fans1_Activated
local fans2_Activated

-- << Functions >> --
local function applyVelocity(character, ActionZone)
	local BodyVelocity = Instance.new("BodyVelocity")
	BodyVelocity.MaxForce = Vector3.new(math.huge,0,0)
	BodyVelocity.P = math.huge
	BodyVelocity.Velocity = (ActionZone.CFrame.RightVector *1)*35		--Change the velocity
	BodyVelocity.Parent = character:FindFirstChild("HumanoidRootPart")
end

local function removeVelocity (character)
	character.HumanoidRootPart.BodyVelocity:Destroy()
end

local function bladesRotation(center)
	local tween_Result = TweenService:Create(center,tween_Info,{CFrame = center.CFrame * CFrame.Angles(0,math.rad(180),0)})
	tween_Result:Play()
end

-- << Connect >> --
for i,v in pairs(FansFolder:GetChildren()) do
	if v.Name == "Fan1" then
		table.insert(fans1_Table,#fans1_Table+1,v)
	elseif v.Name == "Fan2" then
		table.insert(fans2_Table,#fans2_Table+1,v)
	end
end

for i,v in pairs(fans1_Table) do
	v.DetectZone.Touched:Connect(function(hit)
		if debounceTraker[hit.Parent] then
			return
		end
		
		if hit.Parent and hit.Parent:FindFirstChild("Humanoid") and fans1_Activated == true then
			local character = hit.Parent
		
			debounceTraker[character] = true
			applyVelocity(character,v.DetectZone)
		end
	end)
	
	v.DetectZone.TouchEnded:Connect(function(hit)
		if debounceTraker[hit.Parent] then
			debounceTraker[hit.Parent] = nil
			removeVelocity(hit.Parent)
		end
	end)
end

for i,v in pairs(fans2_Table) do
	v.DetectZone.Touched:Connect(function(hit)
		if debounceTraker[hit.Parent] then
			return
		end
		
		if hit.Parent and hit.Parent:FindFirstChild("Humanoid") and fans2_Activated == true then
			local character = hit.Parent
		
			debounceTraker[character] = true
			applyVelocity(character,v.DetectZone)
		end
	end)
	
	v.DetectZone.TouchEnded:Connect(function(hit)
		if debounceTraker[hit.Parent] then
			debounceTraker[hit.Parent] = nil
			removeVelocity(hit.Parent)
		end
	end)
end


while true do
	fans1_Activated = true
	fans2_Activated = false
	local fansbuffer = {}
	
	for i,v in pairs(fans1_Table) do
		-- Rotation System
		local center = v.front.Blades.Center
		bladesRotation(center)
		-- Activate smoke
		v.SmokePart.SmokeEmitter.Enabled =  true
		-- add element to the buffer
		if #fansbuffer == 1 then
			table.insert(fansbuffer,2,v)
		else
			table.insert(fansbuffer,1,v)
		end
	end
	--print("1 - Activated ; 2 - Desactivated")
	wait(5)
	fans1_Activated = false
	fans2_Activated = true
	for i,v in pairs(fans2_Table) do
		-- remove element into the buffer and desactivate them
		if #fansbuffer == 2 then
			fansbuffer[1].SmokePart.SmokeEmitter.Enabled =  false
			fansbuffer[2].SmokePart.SmokeEmitter.Enabled =  false
		end
		-- Rotation System
		local center = v.front.Blades.Center
		bladesRotation(center)
		-- Activate smoke
		v.SmokePart.SmokeEmitter.Enabled = true
		-- add element to the buffer
		if #fansbuffer == 1 then
			table.insert(fansbuffer,2,v)
		else
			table.insert(fansbuffer,1,v)
		end
	end
	wait(5)
	-- remove element into the buffer and desactivate them
	if #fansbuffer >= 2 then
		fansbuffer[1].SmokePart.SmokeEmitter.Enabled =  false
		fansbuffer[2].SmokePart.SmokeEmitter.Enabled =  false
	end
	--print("1 - Desactivated ; 2 - Activated")
end

I’m pretty sure it’s because of the Touched event that doesn’t “refresh” and he don’t detect the character before he move again.
Thanks you very much.

You’re right that it’s because of the Touched event, the player isn’t making a new touch connection when the engine gets turned on.

You should check for existing players already standing on the cylinder upon activating the engine.

  1. You could try FindPartsInRegion3 wiki
local min = part.Position - (0.5 * part.Size)
local max = part.Position + (0.5 * part.Size)
local region = Region3.new(min, max)
local parts = workspace:FindPartsInRegion3(region, part) 
-- loop through parts looking for players
  1. You could make a detection zone (an invisible part) above the cylinder and use GetTouchingParts
-- this is for a part that has CanCollide = false
local function GetTouchingParts(part)
   local connection = part.Touched:Connect(function() end)
   local results = part:GetTouchingParts()
   connection:Disconnect()
   return results
end

local results = GetTouchingParts(workspace.EnginePart)
-- loop through results and look for player parts
2 Likes

I will look about that late, i keep u up. thanks

Hi,

Sorry for this long moment without any response.

If I understand correctly I have 2 “options” to solve my current problem:

  • The first one is to use a Region3 (and the FindPartsInRegion3 method) to get all the parts inside a region every X secondes and with that system i won’t have this type of issue.
  • The next options is to create a dectionZone, and to use it as a “type of region3” but using the Touched event. This second options won’t solve my problem na ? Because it’s also using the .Touched event and we the player stand already in this zone between reactivate the system this will not solve anything ? And also I already have a detection zone which is actualy my cylinder.

Thanks you for ur answer. And sorry again for this delay. (I will be here for ur next answer.

  • The first one is to use a Region3 (and the FindPartsInRegion3 method) to get all the parts inside a region every X secondes and with that system i won’t have this type of issue.

Yeah, once you activate an engine you could search for existing players on top of the cylinder with FindPartsInRegion3

  • The next options is to create a dectionZone, and to use it as a “type of region3” but using the Touched event. This second options won’t solve my problem na ? Because it’s also using the .Touched event and we the player stand already in this zone between reactivate the system this will not solve anything ? And also I already have a detection zone which is actualy my cylinder.

The .Touched event is used because :GetTouchingParts() will return null on a detection zone part that has CanCollide = false. wiki
The cylinder will not work as the detection zone, because players are not intersecting with it, but are standing on top of it (adjacent). The invisible part should be placed above the cylinder so :GetTouchingParts() could return their legs or humanoidRootParts as the result.

For both options, the detection zone should be placed above the cylinder as that is where the players will be standing.

Hello here is a image of my system cuz i don’t really understand why we should use a other part (in region 3 or with gettouchingparts).
Here the cylinder cover all the surface that the player can acces, and every 5 secondes the engine turn on and if the player is in the red zone (the cylinder) then he get a push effet to fall…

I don’t know if it’s me or you who don’t understand, or each other. I’ll do the test tomorrow.

Hi,

So here is the news, i’m a little bit busy these days, I started to update my script to use a Region3 (because i think it’s the simplest way to do this, and also cuz I know a bit more in region3).

Thanks for ur help, I’ll keep you informed.

Hi,

I’m struggling a bit cuz i need the while loop for my program but i need it it also for check constantly for the region3 zone how can i solve my problem ?

-- << 	Services >> --
local TweenService = game:GetService("TweenService")
-- << 	Variables >> --
local FansFolder = game.Workspace.Levels.Level1.Traps.Fans
local debounceTraker = {}

local tween_Info = TweenInfo.new(
	1.25,
	Enum.EasingStyle.Linear,		
	Enum.EasingDirection.In,
	3,	
	false,
	0
)

local region3Zones_fans1_region = {}
local region3Zones_fans1_reference = {}
local region3Zones_fans2_region = {}
local region3Zones_fans2_reference = {}

local fans1_Table = {}
local fans2_Table = {}
local fans1_Activated
local fans2_Activated

-- << Functions >> --
local function applyVelocity(character, ActionZone)
	local BodyVelocity = Instance.new("BodyVelocity")
	BodyVelocity.MaxForce = Vector3.new(math.huge,0,0)
	BodyVelocity.P = math.huge
	BodyVelocity.Velocity = (ActionZone.CFrame.RightVector *1)*35		--Change the velocity
	BodyVelocity.Parent = character:FindFirstChild("HumanoidRootPart")
end

local function removeVelocity (character)
	character.HumanoidRootPart.BodyVelocity:Destroy()
end

local function bladesRotation(center)
	local tween_Result = TweenService:Create(center,tween_Info,{CFrame = center.CFrame * CFrame.Angles(0,math.rad(180),0)})
	tween_Result:Play()
end

-- << Connect >> --
for i,v in pairs(FansFolder:GetChildren()) do
	if v.Name == "Fan1" then
		table.insert(fans1_Table,#fans1_Table+1,v)
	elseif v.Name == "Fan2" then
		table.insert(fans2_Table,#fans2_Table+1,v)
	end
end

for i,v in pairs(fans1_Table) do
	local reference = v.RegionDectectZone
	local minRegion3 = reference.Position - (0.5 * reference.Size)
	local maxRegion3 = reference.Position + (0.5 * reference.Size)
	local region3 = Region3.new(minRegion3,maxRegion3)
	
	table.insert(region3Zones_fans1_region,#region3Zones_fans1_region + 1, region3)
	table.insert(region3Zones_fans1_reference,#region3Zones_fans1_reference + 1, reference)
end

	--[[
	v.DetectZone.Touched:Connect(function(hit)
		if debounceTraker[hit.Parent] then
			return
		end
		
		if hit.Parent and hit.Parent:FindFirstChild("Humanoid") and fans1_Activated == true then
			local character = hit.Parent
		
			debounceTraker[character] = true
			applyVelocity(character,v.DetectZone)
		end
	end)
	
	v.DetectZone.TouchEnded:Connect(function(hit)
		if debounceTraker[hit.Parent] then
			debounceTraker[hit.Parent] = nil
			removeVelocity(hit.Parent)
		end
	end)
	]]--

--[[
for i,v in pairs(fans2_Table) do
	v.DetectZone.Touched:Connect(function(hit)
		if debounceTraker[hit.Parent] then
			return
		end
		
		if hit.Parent and hit.Parent:FindFirstChild("Humanoid") and fans2_Activated == true then
			local character = hit.Parent
		
			debounceTraker[character] = true
			applyVelocity(character,v.DetectZone)
		end
	end)
	
	v.DetectZone.TouchEnded:Connect(function(hit)
		if debounceTraker[hit.Parent] then
			debounceTraker[hit.Parent] = nil
			removeVelocity(hit.Parent)
		end
	end)
end

]]--

while true do
	fans1_Activated = true
	fans2_Activated = false
	local fansbuffer = {}

	for i,v in pairs(fans1_Table) do
		-- Rotation System
		local center = v.front.Blades.Center
		bladesRotation(center)
		-- Activate smoke
		v.SmokePart.SmokeEmitter.Enabled =  true
		-- add element to the buffer
		if #fansbuffer == 1 then
			table.insert(fansbuffer,2,v)
		else
			table.insert(fansbuffer,1,v)
		end
	end
	for i, v in pairs(region3Zones_fans1_region) do
		local currRegion = v
		local currReference = region3Zones_fans1_reference[i]
		
		local result = workspace:FindPartsInRegion3WithIgnoreList(currRegion, {currReference}, math.huge)
		for i,v in ipairs(result) do
			local char = v.Parent
			if debounceTraker[char] then
				return
			end
			if char and char:FindFirstChild("Humanoid") and fans1_Activated == true then
				debounceTraker[char] = true
				applyVelocity(char,currReference)
			end
		end
	end
	--print("1 - Activated ; 2 - Desactivated")
	fans1_Activated = false
	fans2_Activated = true
	for i,v in pairs(fans2_Table) do
		-- remove element into the buffer and desactivate them
		if #fansbuffer == 2 then
			fansbuffer[1].SmokePart.SmokeEmitter.Enabled =  false
			fansbuffer[2].SmokePart.SmokeEmitter.Enabled =  false
		end
		-- Rotation System
		local center = v.front.Blades.Center
		bladesRotation(center)
		-- Activate smoke
		v.SmokePart.SmokeEmitter.Enabled = true
		-- add element to the buffer
		if #fansbuffer == 1 then
			table.insert(fansbuffer,2,v)
		else
			table.insert(fansbuffer,1,v)
		end
	end
	wait(5)
	-- remove element into the buffer and desactivate them
	if #fansbuffer >= 2 then
		fansbuffer[1].SmokePart.SmokeEmitter.Enabled =  false
		fansbuffer[2].SmokePart.SmokeEmitter.Enabled =  false
	end
	--print("1 - Desactivated ; 2 - Activated")
end

Huge thanks

EDIT

I created another topic because it was a bit far from the basic idea of this one. (https://devforum.roblox.com/t/blocked-to-use-a-while-loop-for-region-detection-and-for-other-things/1206061)