Scripting Helpers is winding down operations and is now read-only. More info→
Ad
Log in to vote
1

Limb collision system fires while mid-air?

Asked by 1 year ago

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!

0
Is the script a normal script or local script? T3_MasterGamer 2189 — 1y
0
Also you don't need to set the second parameter in WaitForChild unless if you want it to return nil after 3 seconds if child hasn't been found yet. T3_MasterGamer 2189 — 1y
0
I think I may have found the problem. Replace Enum.RaycastFilterType.Blacklist to Enum.RaycastFilterType.Exclude T3_MasterGamer 2189 — 1y
0
It's a normal script. KneeDeepInTheDoot 13 — 1y
View all comments (4 more)
0
Oh, the second parameter. I was using it until I checked to see if the script was still in StarterPlayerScripts to prevent the script from printing errors out of nowehere. KneeDeepInTheDoot 13 — 1y
0
I tried that and it still fires mid-air. Thanking you heavily for you contribution KneeDeepInTheDoot 13 — 1y
0
Idk what you mean by "mid-air" T3_MasterGamer 2189 — 1y
0
Like the limbs falling through empty space and not interacting with any parts. KneeDeepInTheDoot 13 — 1y

1 answer

Log in to vote
0
Answered by 1 year ago
Edited 1 year ago

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 BaseParts, but it didn't specify if it returns nil when there are no BaseParts. 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.

Solution

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.

Final Script

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)
Ad

Answer this question