How could I improve on my realistic physics impact script?

boom crash psheewww.rbxl (50.0 KB)

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
3 Likes

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)
3 Likes

Gonna test this out, hopefully it works since you seem to have put a lot of effort into this script!

Words cannot describe how grateful I am. Thank you so much.

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.