Greetings - I’ve been working and experimenting with different methods of Melee based attacks. Yes I’m aware of the module, I’m still attempting to create my own method.
My issue is as shown below:
I’m trying to get it so that only 1 of the Humanoids are input into the Table as opposed to all 45 that it collides with.
I understand that I can fix this by using break in my pairs, however, I’m looking to damage multiple NPCs rather than the single one when the requirements are met.
Below is a brief example of what I’m attempting to achieve.
As you can see, because of the multiple additions into the tables, the Humanoids gain the 15 Dmg * whatever the parts found were as opposed to my intended - Simple just -15 dmg.
local Part = script.Parent
local _H = {}
local Multi
Multi = game:GetService("RunService").Heartbeat:Connect(function()
_H = {}
local _i = Part:GetTouchingParts()
for _,i in pairs (_i) do
if i.Parent:FindFirstChild("Humanoid") ~= nil then
for _,p in pairs (_H) do
if p == i.Parent["Humanoid"] then
print("Found")
else
table.insert(_H, i.Parent["Humanoid"])
end
end
end
end
Damage()
end)
Damage = function()
for _,i in pairs (_H) do
if i:IsA("Humanoid") then
i:TakeDamage(15)
Multi:Disconnect()
end
end
end
You’ll need to add a sort of some kind to check if the humanoid already exist in the table,
also I don’t suggest running a loop every 1/40th of a second if you can get around it. It’s a little overkill, especially considering normal humans only process 24-48 frames a second as motion.
you can use table.find to search for values in an array, with this you can check if they exist within the H table, also you might want to clean the H table afterwards because tables referencing roblox instances will not be gc’d.
Why not instead of making a list of humanoids to damage, make a hashmap of humanoids. Set to true if they are to be damaged.
Multi = game:GetService("RunService").Heartbeat:Connect(function()
_H = {}
local _i = Part:GetTouchingParts()
for _,i in pairs (_i) do
if i.Parent:FindFirstChild("Humanoid") ~= nil then
for p, _ in pairs (_H) do
if p == i.Parent["Humanoid"] then
print("Found")
else
_H[i.Parent.Humanoid] = true
end
end
end
end
Damage()
end)
Then for damage, you can just flip the key and value identifiers like so:
Damage = function()
for i, _ in pairs (_H) do
if i:IsA("Humanoid") then
i:TakeDamage(15)
Multi:Disconnect()
end
end
end
Now, if I attempt to repeatedly set the same value true, it’ll remain true. It will not flood the table with the same humanoids as the humanoids are the keys, not the value. Also, take Mentsuu and Crowdsource tips as well if you want a full fix.
Extra
Have more descriptive variables names, it helps a lot in parsing through the code and reasoning about it. This is because “BodyParts” has more meaning than “_i”. It’ll not only help other people read your code, but it’ll also help you in the future when you reread it.
Using an example above I was able to create a working function for this: HOWEVER.
local Part = script.Parent
local _H = {}
local Multi
Multi = game:GetService("RunService").Heartbeat:Connect(function()
local _i = Part:GetTouchingParts()
for _,i in pairs (_i) do
if i.Parent:FindFirstChild("Humanoid") ~= nil then
local E = table.find(_H, i.Parent["Humanoid"])
if E then
else
table.insert(_H, i.Parent["Humanoid"])
end
end
end
Damage()
end)
Damage = function()
for _,i in pairs (_H) do
if i:IsA("Humanoid") then
i:TakeDamage(15)
Multi:Disconnect()
end
end
_H = {}
end
When implemented into my Sword, it still restricts to a single Humanoid?
Strike = function()
Debounce = true
local anim = Player.Character:WaitForChild("Humanoid"):LoadAnimation(script.anim)
anim:Play()
_D = game:GetService("RunService").Heartbeat:Connect(function()
local _i = Tool["Hitbox"]:GetTouchingParts()
for _,i in pairs (_i) do
if i.Parent:FindFirstChild("Humanoid") ~= nil then
local E = table.find(_H, i.Parent["Humanoid"])
if E then
else
table.insert(_H, i.Parent["Humanoid"])
end
end
end
Damage()
end)
repeat wait(.75) until anim.IsPlaying == false
Debounce = false
_D:Disconnect()
end
Damage = function()
for _,i in pairs (_H) do
if i:IsA("Humanoid") then
i:TakeDamage(15)
_D:Disconnect()
end
end
_H = {}
end
Can anyone help with this?