Now, it functions fine albeit with multiple impacts happening when a cube rattles against the wall in the .rbxl I supplied. I’m stumped on how to detect sliding, but I know it is possible and I just feel like I’m missing improvements that could make it more realistic. I’ll post the code too if you can go without a demonstration or you can paste it in a part of your own.
Steps = 0.1
ImpactThreshold = 50
function Impact()
local CloneSFX = script.Parent["Crash Metal Shatter"]:Clone()
CloneSFX.Parent = script.Parent
CloneSFX:Play()
game:GetService("Debris"):AddItem(CloneSFX, CloneSFX.TimeLength)
end
function Scraping()
local CloneSFX = script.Parent["Metal Scrape"]:Clone()
CloneSFX.Parent = script.Parent
CloneSFX:Play()
game:GetService("Debris"):AddItem(CloneSFX, CloneSFX.TimeLength)
end
function NotScraping()
script.Parent["Metal Scrape"]:Stop()
end
while task.wait(Steps) do
LastVelocity = script.Parent.AssemblyLinearVelocity.Magnitude
if script.Parent.AssemblyLinearVelocity.Magnitude >= ImpactThreshold then
script.Parent.Touched:Connect(function(hit)
if script.Parent.AssemblyLinearVelocity.Magnitude <= LastVelocity / 2 and script.Parent.AssemblyLinearVelocity.Magnitude ~= 0 then
Impact()
LastVelocity = script.Parent.AssemblyLinearVelocity.Magnitude
end
end)
end
end
Sorry for my messy code but here’s a modified version that detects sliding and doesn’t create a ton of connections:
(if you don’t hear the sliding btw up the volume of the sound)
local RunService = game:GetService("RunService")
local IMPACT_THRESHOLD = 10
local IMPACT_CHECK_THRESHOLD = 5
local SLIDING_THRESHOLD = 2
local raycastParams = RaycastParams.new()
raycastParams.FilterDescendantsInstances = {script.Parent}
function Impact()
local CloneSFX = script.Parent["Crash Metal Shatter"]:Clone()
CloneSFX.Parent = script.Parent
CloneSFX:Play()
game:GetService("Debris"):AddItem(CloneSFX, CloneSFX.TimeLength)
end
local scrapingSFX = nil
function Scraping()
if scrapingSFX then
return
end
scrapingSFX = script.Parent["Metal Scrape"]:Clone()
scrapingSFX.Parent = script.Parent
scrapingSFX:Play()
task.wait(scrapingSFX.TimeLength)
scrapingSFX:Destroy()
scrapingSFX = nil
end
function EndScraping()
if scrapingSFX then
scrapingSFX:Stop()
end
end
local previousImpactRaycast = nil
local function impactLogic()
local result: RaycastResult = workspace:Raycast(script.Parent.Position, script.Parent.AssemblyLinearVelocity / IMPACT_CHECK_THRESHOLD, raycastParams)
if not result then
previousImpactRaycast = nil
return
end
local velocityMagnitude = script.Parent.AssemblyLinearVelocity.Magnitude
if not previousImpactRaycast then
if velocityMagnitude >= IMPACT_THRESHOLD then
Impact()
end
end
previousImpactRaycast = result
end
local previousRaycast = nil
local function slidingLogic()
local result: RaycastResult = workspace:Raycast(script.Parent.Position, Vector3.new(0, -5, 0), raycastParams)
if not result then
previousRaycast = nil
return
end
local velocityMagnitude = script.Parent.AssemblyLinearVelocity.Magnitude
if previousRaycast then
if velocityMagnitude < SLIDING_THRESHOLD then
EndScraping()
return
end
Scraping()
end
previousRaycast = result
end
RunService.Heartbeat:Connect(function(deltaTime)
impactLogic()
slidingLogic()
end)