Make i,v loop register new parts

  1. What do you want to achieve?
    I have a scent system that makes particles visible. Another script clones the particles every 4 seconds at the torso’s CFrame. I want the loop to register new cloned particles too.

  2. What is the issue?
    Problem now is that if I hold B to activate the scent it works just fine tho if I keep holding it, it doesn’t make newly cloned particles visible only the ones that have existed before holding B.

LocalScript inside the character

--- Scent ---
function Sniff()
	for i,v in ipairs(workspace:GetChildren()) do
		if v.Name == "Meat" then
			local magnitudeA = (v.Position - hrp.Position).Magnitude
			if magnitudeA < 1000 then
				v.Highlight.Enabled = true
			end
		end
		if v.Name == "ScentBlockC" or v.Name == "ScentBlockH" or v.Name == "ScentBlockO" then
			if v.Origin.Value ~= player.Name then
			v.Scent.Enabled = true
			end
		end
	end
end

function StopSniff()
	for i,v in ipairs(workspace:GetChildren()) do
		if v.Name == "Meat" then
			v.Highlight.Enabled = false
		end
		if v.Name == "ScentBlockC" or v.Name == "ScentBlockH" or v.Name == "ScentBlockO" then
			v.Scent.Enabled = false
		end
	end
end

UIS.InputBegan:Connect(function(input, gameProccessed, IsTyping)
	if input.KeyCode == Enum.KeyCode.B and not gameProccessed then
		Sniff()
		darkmode.Visible = true
		player.PlayerGui.BengalTiger:WaitForChild("Settings"):WaitForChild("Scent").Visible = true
	end
end)

UIS.InputEnded:Connect(function(input, gameProccesed, IsTyping)
	if input.KeyCode == Enum.KeyCode.B then
		StopSniff()
		darkmode.Visible = false
		player.PlayerGui.BengalTiger:WaitForChild("Settings"):WaitForChild("Scent").Visible = false
	end	
end)

Any help appreciated :heart_hands:

2 Likes

You should call the Sniff function periodically as long as the B key is held down.

1 Like

You can use something like this that I just made right now
It’s an OOP module, that way if you ever have that problem again you can just use that same module :slight_smile:

It may not be the best so just note that

LikerDLT.lua (2.0 KB)

For those who don’t want to download the module:

local DynamicLT = {}
DynamicLT.__index = DynamicLT;

function DynamicLT.new(ChildSubject: Instance)
	assert(typeof(ChildSubject) == "Instance", "expected ChildSubject to be an instance")
	
	return setmetatable({
		Subject = ChildSubject,
		DynamicTable = {},
		Listeners = {},
		
		IsAdding = false,
	}, DynamicLT)
end

function DynamicLT:AddListener(ScriptSignal: RBXScriptSignal<(Instance)>)
	assert(typeof(ScriptSignal) == "RBXScriptSignal", "expected ScriptSignal to be an RBXScriptSignal")
	assert(not self.Listeners[ScriptSignal], "already listening to the given RBXScriptSignal")
	
	table.insert(self.Listeners, ScriptSignal:Connect(function(Object)
		if self.IsAdding then
			table.insert(self.DynamicTable, Object)
		end
	end))
end

function DynamicLT:RemoveListener(ScriptSignal: RBXScriptSignal)
	assert(typeof(ScriptSignal) == "RBXScriptSignal", "expected ScriptSignal to be an RBXScriptSignal")
	assert(self.Listeners[ScriptSignal], "not listening to the given RBXScriptSignal")

	self.Listeners[ScriptSignal]:Disconnect()
end

function DynamicLT:AddDynamicElement(Element: Instance)
	assert(typeof(Element) == "Instance", "expected Element to be an Instance")
	assert(self.IsAdding, "not currently iterating over a dynamic loop")
	
	table.insert(self.DynamicTable, Element)	
end

function DynamicLT:RemoveDynamicElement(Element: Instance)
	assert(typeof(Element) == "Instance", "expected Element to be an Instance")
	assert(self.IsAdding, "not currently iterating over a dynamic loop")
	
	local Index = table.find(self.DynamicTable, Element)
	assert(Index, "the given element is not inside the dynamic table")
	
	table.remove(self.DynamicTable, Index)	
end

function DynamicLT:Free()
	self.IsAdding = false
	table.clear(self.DynamicTable)
end

function DynamicLT:Retrieve(BaseTable)
	assert(type(BaseTable) == "table", "expected BaseTable to be a table")
	self.IsAdding = true
	
	local _dynTable = self.DynamicTable
	for Index, Value in next, BaseTable do
		_dynTable[Index] = Value
	end
	
	return _dynTable
end

return DynamicLT

An example of iterating through GetChildren would be something like this:

local DynamicLoopTable = require(path.to.dynamic.module)
local PartsFolder = workspace:WaitForChild("Parts")

local MyPartDLT = DynamicLoopTable.new(PartsFolder)
MyPartDLT:AddListener(PartsFolder.ChildAdded) --> GetChildren: ChildAdded; GetDescendants: DescendantAdded, etc

for Index, Value in next, MyPartDLT:Retrieve(PartsFolder:GetChildren()) do --> Retrieves the dynamic table to loop over (In this case, a dynamic GetChildren loop)
	print(`I see {Value.Name}!`)
end

MyPartDLT:Free() --> Always call it after finishing iterating to clean up
1 Like

Do you have a small code example? thank you for your response btw!

1 Like

Oh wow that’s nice thank you! I just have difficulties reading the script and how I could use it in my case

1 Like

As the code snippet your provided in your OP does not provide the following AFAIK:

You could resort to implementing the example that I gave in my reply

Since roblox does not have any reliable way to detect iterating as the __iter metamethod has been disabled, you have to rely on calling functions to determine if you are still iterating or not

1 Like