If part hits humanoid at certain velocity/speed, it hurts humanoid

Let’s say I have a car, and I also have an invisible part attached to the front of the car. There’s a script inside the part which checks if the part is going at a certain velocity/speed, if it hits something at that velocity/speed (a humanoid) is hurts or potentially kills it. How would I do this? I’m not asking for an entire script, you can just tell me what I need to know in order to make the script, but if you really insist leaving a script, that’s ok. Thank you!

:grin:

2 Likes

Not really sure about this approach. I would just make a hit box around the character and make it a like huge box covering every single body part. You can use the touched event to see if the part that hit the hit box has a velocity of greater than the amount you want.

print(THEPARTGOESHERE.Velocity.Magnitude) - - This is the speed of the part that is hitting the invisible part.

The reason this checks the velocity of two frames is because I thought that the touch might cause the speed to drop to a low value or 0, which would give a wrong result. However, I’m not sure if that happens.

local RunService = game:GetService("RunService")

local DAMAGE_SPEED = -- speed great enough for damaging here
local DAMAGE = -- damage here
local DEBOUNCE_TIME = -- cooldown before than touches with the same character can.be detected again.

local detectionPart = -- the invisible part

local debounces = {}
local latestVelocity, currentVelocity = 0, 0

part.Touched:Connect(function(hit)
    local hum = hit.Parent:FindFirstChild("Humanoid")
    if hum then
        if debounces[hum] then
            return
        end
        debounces[hum] = true
        delay(DEBOUNCE_TIME, function()
            debounces[hum] = nil
        end)
        if hum.Heath > 0 and (currentVelocity.Magnitude >= DAMAGE_SPEED or latestVelocity.Magnitude >= DAMAGE_SPEED) then
            hum:TakeDamage(DAMAGE)
        end
    end
end

RunService.HeartBeat:Connect(function()
    latestVelocity = currentVelocity
    currentVelocity = detectionPart.Velocity
end

Edit: I fixed a mistake in the function connected to hearbeat. I also added a debounce. Thanks, @xxIamInevitable, for mentioning it.

3 Likes

This should work properly as it should, but in order to make sure, you should probably add in a debounce or disconnect the .Touched event after the humanoid takes damage.

A easy way would be to first check if a part is at that certain speed and use a Touched event.

Demonstration:

local part = workspace.Part
local  required_Speed_To_Damage = 50

if part.Velocity.Mangitude >= required_Speed_To_Damage then
       part.Touched:Connect(function(hit)
             if hit.Parent:FindFirstChild("Humanoid") then
                  hit.Parent.Humanoid:TakeDamage(40)
            end
      end)
end

Making the humanoid take damage like 40 from a high-speed/medium-speed car would seem a bit too empty (at least for me) or unrealistic

Though I don’t really have much of a better solution making the humanoid randomly take 40 damage wouldn’t really be appealing

That is just a demonstration of how OP could accomplish it.

@SilentsReplacement’s idea of only having the touched connection when the speed is great enough is actually better than my idea. To make it work, the speed needs to be checked every frame and the connections to touched should be created and disconnected when necessary.

local RunService = game:GetService("RunService")

local DAMAGE_SPEED = -- speed great enough for damaging here
local DAMAGE = -- damage here
local DEBOUNCE_TIME = -- cooldown before than touches with the same character can.be detected again.

local detectionPart = -- the invisible part

local debounces = {}

local function onTouched(hit)
    local hum = hit.Parent:FindFirstChild("Humanoid")
    if hum and not debounces[hum] then
        debounces[hum] = true
        delay(DEBOUNCE_TIME, function()
            debounces[hum] = nil
        end)
        if hum.Health > 0 then
            hum:TakeDamage(DAMAGE)
        end
    end
end

local touchedConn
RunService.HeartBeat:Connect(function()
    local speed = detectionPart.Velocity.Magnitude
    if speed >= DAMAGE_SPEED and not touchedConn then
        touchedConn = detectionPart.Touched:Connect(onTouched)
    elseif speed < DAMAGE_SPEED and touchedConn then
        touchedConn:Disconnect()
        touchedConn = nil
    end
end
1 Like

The connection should be disconnected when it isn’t needed and the speed should be checked very Stepped if the part is unanchored but Heartbeat is also fine. As I previously stated, it was just a simple demonstration.

1 Like

where would i put the script?..

It could be in ServerScriptService or in the car, for example.