I haven’t really thought this through, but, right off the bat, I think you could have an uncollidable part hitbox that’s locked into the player’s character, is slightly larger than the character (so it detects parts in their moving state before actually colliding with the player’s character), and get the magnitude of the AssemblyLinearVelocity Vector3 of every part that triggers the hitbox’s Touched event (to determine how fast it’s moving, as you requested). Don’t make the hitbox too large, though, make it so if a part touches it, you’re sure it’s hitting the character as well (something a bit more refined to add is that could raycast to extrapolate the moving direction of the part to see if it’s really going to collide with the character or not, especially in case you’re using complex custom characters).
char.humanoidrootpart.touched:Connect(function(hit)
if hit.Velocity > (somespeed).Magnitude then
– do desired outcome here
end
end)
this is quite simple what would be better is maybe a shapecast or you could do this touched event to each part in the character, and then if the speed is above a value then take damage. this could also be done on the server when a character is added to prevent exploitation.
Put all the fast-moving parts in their own collision group that doesn’t collide with other parts by default..
And one way using Heartbeat and Region3..
local Players = game:GetService("Players")
local RunService = game:GetService("RunService")
local trackedParts = {}
local damageThreshold = 50
local damageAmount = 20
function trackPart(part)
trackedParts[part] = true
end
function untrackPart(part)
trackedParts[part] = nil
end
workspace.ChildAdded:Connect(function(child)
if child:IsA("Part") and child.Name == "FlyingPart" then
trackPart(child)
end
end)
for _, part in ipairs(workspace:GetDescendants()) do
if part:IsA("Part") and part.Name == "FlyingPart" then
trackPart(part)
end
end
RunService.Heartbeat:Connect(function()
for part in pairs(trackedParts) do
if not part.Parent then untrackPart(part)
elseif part.Velocity.Magnitude >= damageThreshold then
local region = Region3.new(part.Position - part.Size/2, part.Position + part.Size/2)
local overlapping = workspace:FindPartsInRegion3(region, part, 10)
for _, hit in ipairs(overlapping) do
local humanoid = hit.Parent:FindFirstChildWhichIsA("Humanoid")
if humanoid then humanoid:TakeDamage(damageAmount)
end
end
end
end
end)
Kind of guessing here… hope you get how this works or can make it work for you.
Trying to do this within one script.
.Touched shall fire the moment the object has collided with the HumanoidRootPart, and thus the velocity you get would be just after the impact. By getting the velocity just a bit before as explained in my post How to tell if player gets hit by fast moving object? - #2 by safeLast120 , you would accurately get the velocity at which it meets with the character.
Also, perhaps the part collides with the right leg instead of the HumanoidRootPart, and it’s not really efficient to connect Touched for each body part, besides of the point made above.
local RunService = game:GetService("RunService")
local Model = workspace.Model --model containing parts
local Parts = Model:GetChildren()
local PartVelocities = {}
local Speed = 10 --change this to the desired velocity
local function OnHeartbeat(Time)
for _, Part in ipairs(Parts) do
PartVelocities[Part] = Part.AssemblyLinearVelocity.Magnitude
end
end
RunService.Heartbeat:Connect(OnHeartbeat)
for _, Part in ipairs(Parts) do
local function OnTouched(OtherPart)
--check if "OtherPart" belongs to a player's character model
if PartVelocities[Part] or 0 > Speed then
--do some code
end
end
Part.Touched:Connect(OnTouched)
end