Hello, I’m LuaGirlDeveloper and I’ve been working on a Grid based game and I need feedback on my detection code.
And I need feedback on would this lag if I have a grid of 100x100?
local Connection
local FallConnection
--// Detect Hit
Connection = NewPart.Touched:Connect(function(Hit)
local Player = Players:GetPlayerFromCharacter(Hit:FindFirstAncestorOfClass("Model"))
if not Player then return nil end
Connection:Disconnect()
for Index = 1, #Colors do
NewPart.BrickColor = Colors[Index]
task.wait(0.25)
end
local FallTween = TweenService:Create(NewPart, NewPartTweenInfo, {CFrame = NewPart.CFrame * CFrame.new(0, -50, 0)})
FallTween:Play()
FallConnection = FallTween.Completed:Connect(function()
NewPart:Destroy()
FallConnection:Disconnect()
end)
end)
It likely could. It does sorta depend on how big each part of the grid is, the smaller the parts the more extreme performance issues.
The main issues you should try to address is having the code run independent of the 10000 Parts. 10k connections is not exactly… very healthy for the game and i believe a better approach would be for you to instead utilize the player character to detect whenever theire actually touching any of these parts. This would entirely remove the need to create 10k connections and still provide the same result. This would further optimize your code since technically within the scope of the code the player character would be present by default so you will no longer need to manually detect and search for the player character.
For this sort of approach you should be able to use CollectionService to provide every one of those parts with a special tag (said tag can be anything you want) in order to actually determine whenever or not whatever the player is touching/around is one of those 10k parts from the grid.
Another thing to note here is that your code is written in such a way that will force it to stack functions over and over every time one of those parts got touched. This happens due to each .Touched event creating a brand new “thread” and will NOT wait for any previously running code to finish. This “stacking” specifically happens because of that wait function inside the color for loop. During the waiting period, the same code can execute every time each part was touched causing the code to run multiple times over. This of course will result in pretty broken looking visuals along with heavily hurt performance.
What you can do here is create a way to check whenever or not any previously running code finished running or not. This can be as simple as creating a “IsFinished” boolean variable before the event connection and then checking whenever or not its true as the first line of the function. If its true then simply set it to false (meaning that now there IS running code) and set it back to true in that tween’s completed event.
Another simple optimization would be formatting that for loop differently. I believe you have a “Colors” table, yes? Well in that case you can simply instead for loop utilizing that table directly instead of needing to manually index each value.
Here’s the code for that:
for Index, Color in pairs(Colors) do
NewPart.BrickColor = Color
task.wait(0.25)
end
Looping through the table this way would be slightly faster and more cleaner mostly because again, you would not need to manually index through the Colors table.
If all of the 10k parts already exist within studio then you can simply select them, scroll down in the properties tab and take a look at the “Tags” section. You can insert a new tag to all 10k parts right there. If you generate these parts at runtime then you can use CollectionService’s “AddTag” method during the creation of every one of these parts.
As to how you could actually detect them, you could simply utilize the player charater’s left/right foot and check whatever it is touching. You can check whenever or not the object the foot touched is one of the grid parts by utilizing the “HasTag” method (of either CollectionService or that individual instance). If it does have the required tag then youre basically golden.
local CollectionService = game:GetService("CollectionService")
local Connections = {}
local function MakeTile(Part)
local Connection = Part.Touched:Connect(function()
-- Code here
end)
Connections[Part] = Connection
end
for _, Object in pairs(CollectionService:GetTagged("Tile")) do
MakeTile(Object)
end
CollectionService:GetInstanceAddedSignal("Tile"):Connect(function(Object)
MakeTile(Object)
end)
CollectionService:GetInstanceRemovedSignal("Tile"):Connect(function(Object)
if Connections[Object] then
Connections[Object]:Disconnect()
end
end)
Not quite, as ive said, my proposed solution relies on a singular (or two, if you want to use both feet) .Touched event directly coming from the player character’s foot.
local CollectionService = game:GetService("CollectionService")
local Players = game:GetService("Players")
local Connections = {}
local function MainLeg(Part)
local Connection = Part.Touched:Connect(function(Hit)
-- Code here
print(Hit.Name)
end)
Connections[Part] = Connection
end
Players.PlayerAdded:Connect(function(Player)
Player.CharacterAdded:Connect(function(Character)
local LeftLeg = Character:WaitForChild("Left Leg")
local RightLeg = Character:WaitForChild("Right Leg")
if LeftLeg and RightLeg then
CollectionService:AddTag(LeftLeg, "Leg")
CollectionService:AddTag(RightLeg, "Leg")
end
end)
end)
for _, Object in pairs(CollectionService:GetTagged("Leg")) do
MainLeg(Object)
end
CollectionService:GetInstanceAddedSignal("Leg"):Connect(function(Object)
MainLeg(Object)
end)
CollectionService:GetInstanceRemovedSignal("Leg"):Connect(function(Object)
if Connections[Object] then
Connections[Object]:Disconnect()
end
end)
Sure. Though you dont need to create tags for the feet. You only need to create tags for the 10k tile parts. You can basically skip the entire CollectionService process for the legs. You only need CollectionService for the 10k parts. (For detecting them in the MainLeg .Touched event function)
Before you go is this good for checking if the Player is still alive, has character?
local CollectionService = game:GetService("CollectionService")
local Players = game:GetService("Players")
local Connections = {}
local function MainLeg(Part)
local Connection = Part.Touched:Connect(function(Hit)
local IsTouchingPlayer = Players:GetPlayerFromCharacter(Hit:FindFirstAncestorOfClass("Model"))
if IsTouchingPlayer then return nil end
local OurPlayer = Players:GetPlayerFromCharacter(Part.Parent)
if not OurPlayer then return nil end
local Character = OurPlayer.Character
if not Character then return end
local Humanoid = Character:FindFirstChild("Humanoid")
if not Humanoid then return end
if Humanoid.Health < 0 then return end
-- Touched Something
print(Hit.Name)
end)
Connections[Part] = Connection
end
Players.PlayerAdded:Connect(function(Player)
Player.CharacterAdded:Connect(function(Character)
local LeftLeg = Character:WaitForChild("Left Leg")
local RightLeg = Character:WaitForChild("Right Leg")
if LeftLeg and RightLeg then
CollectionService:AddTag(LeftLeg, "Leg")
CollectionService:AddTag(RightLeg, "Leg")
end
end)
end)
for _, Object in pairs(CollectionService:GetTagged("Leg")) do
MainLeg(Object)
end
CollectionService:GetInstanceAddedSignal("Leg"):Connect(function(Object)
MainLeg(Object)
end)
CollectionService:GetInstanceRemovedSignal("Leg"):Connect(function(Object)
if Connections[Object] then
Connections[Object]:Disconnect()
Connections[Object] = nil
print("Disconnect Legs")
end
end)
@XenoDenissboss1 I have a question how can I implement this code into a round system?
local CollectionService = game:GetService("CollectionService")
local Players = game:GetService("Players")
local Connections = {}
local function MainLeg(Part)
local Connection = Part.Touched:Connect(function(Hit)
local IsTouchingPlayer = Players:GetPlayerFromCharacter(Hit:FindFirstAncestorOfClass("Model"))
if IsTouchingPlayer then return nil end
local OurPlayer = Players:GetPlayerFromCharacter(Part.Parent)
if not OurPlayer then return nil end
local Character = OurPlayer.Character
if not Character then return end
local Humanoid = Character:FindFirstChild("Humanoid")
if not Humanoid then return end
if Humanoid.Health > 0 then
if CollectionService:HasTag(Hit, "Tile") then
-- Do stuff here...
end
end
end)
Connections[Part] = Connection
end
Players.PlayerAdded:Connect(function(Player)
Player.CharacterAdded:Connect(function(Character)
local LeftLeg = Character:WaitForChild("Left Leg")
local RightLeg = Character:WaitForChild("Right Leg")
if LeftLeg and RightLeg then
CollectionService:AddTag(LeftLeg, "Leg")
CollectionService:AddTag(RightLeg, "Leg")
end
end)
end)
for _, Object in pairs(CollectionService:GetTagged("Leg")) do
MainLeg(Object)
end
CollectionService:GetInstanceAddedSignal("Leg"):Connect(function(Object)
MainLeg(Object)
end)
CollectionService:GetInstanceRemovedSignal("Leg"):Connect(function(Object)
if Connections[Object] then
Connections[Object]:Disconnect()
Connections[Object] = nil
end
end)
Like should I make a module called TileClass and it handles things like a Table called CurrentTiles and when the player touches a tile it tells the TileClass to remove that tile and play the effect?