In my code, I have it so every .Heartbeat, the game checks if a limb is intersecting with another part, which would not function without 0.8 x 0.8 x 1.8 limb colliders. This works just fine except for one thing. It somehow fires in mid-air even though I blacklisted all of the character parts. I even debugged it with the print function, and it returns “{}” in the console but with no dropdown list. I don’t know why my code is doing this. Here is my code:
if script:FindFirstAncestor("StarterPlayer") ~= nil then return end local RS = game:GetService("RunService") RS.Heartbeat:Connect(function() local OverlapParamss = OverlapParams.new() OverlapParamss.FilterType = Enum.RaycastFilterType.Blacklist OverlapParamss.FilterDescendantsInstances = {script.Parent} local Head = script.Parent:WaitForChild("Head", 3) local Torso = script.Parent:WaitForChild("Torso", 3) local LArm = script.Parent:WaitForChild("Left Arm", 3) local RArm = script.Parent:WaitForChild("Right Arm", 3) local LLeg = script.Parent:WaitForChild("Left Leg", 3) local RLeg = script.Parent:WaitForChild("Right Leg", 3) local HParts = workspace:GetPartsInPart(Head, OverlapParamss) --local TParts = workspace:GetPartsInPart(Torso, OverlapParamss) --local LAParts = LArm:GetPartsInPart() --local RAParts = RArm:GetPartsInPart() --local LLParts = LLeg:GetPartsInPart() --local RLParts = RLeg:GetPartsInPart() if HParts ~= nil and Head.Velocity.Magnitude > 75 then script.Parent.Humanoid:TakeDamage(1) print(HParts) end end)
Any help is immensely appreciated! Thank you!
Okay, I found the problem. You see, in the Roblox Creator Documentation, it says that Workspace:GetPartsInPart()
returns an array (table in which the "key" is and should be a number and therefore called "index" and its "value" is any
; e.g., {"hi", 2, 5, "six"}
or {[1] = "hi", [2] = 2, [3] = 5, [4] = "six"}
) of BasePart
s, but it didn't specify if it returns nil when there are no BasePart
s. That could be why it still damages your character. Workspace:GetPartsInPart()
returns an empty table when mid-air, and your script checks if it exists (not nil
), and an empty table DOES EXIST.
To fix this, you will check if it's an empty table by getting the number of elements stored in it using the #
operator. You can also use table.getn()
if you want to be nostalgic or keep the legacy, but it's EXTREMELY DEPRECATED and the #
operator is much more efficient and faster and easy to use.
Also you don't need to get every limb of the player and define it in a variable, you can just iterate every child of the character and check if it's a BasePart
using Instance:IsA()
.
Also checking if script is still a descendant of StarterPlayer
is EXTREMELY UNNECESSARY since the scripts inside it won't run until it is moved in either PlayerScripts
inside the Player
, or inside Player.Character
.
Tip: You can replace RunService.Heartbeat
with task.wait()
since it does the same thing. To loop it, use a while true do
loop.
local Character = script.Parent local Humanoid = Character:FindFirstChildOfClass("Humanoid") while true do local Params = OverlapParams.new() Params.FilterType = Enum.RaycastFilterType.Exclude -- Enum.RaycastFilterType.Blacklist Params.FilterDescendantsInstances = {Character} for _, Child in ipairs(Character:GetChildren()) do task.spawn(function() -- we will use task.spawn() to avoid delays if Child:IsA("BasePart") then -- if Child is a limb local Parts: {BasePart} if (Child.Name == "Head") or (Child.Name == "HumanoidRootPart") then -- if limb is the head or the torso Parts = workspace:GetPartsInPart(Child, Params) else Parts = workspace:GetPartsInPart(Child) end if Parts ~= nil then and Character.Head.AssemblyLinearVelocity.Magnitude > 75 then if #Parts > 0 then Humanoid:TakeDamage(1) print(Child.Name, Parts) end end end end) end task.wait() end)