My car health script is not working

I tried this code below but it just kept going down to much when I hit a wall:

local terry = workspace.Terry
local speedLimit = 50 -- Example threshold for high-speed collision
local health = 100 -- Example health variable



-- Iterate through all parts in the Terry model
for _, part in pairs(terry:GetDescendants()) do
	if part:IsA("Part") then
		part.Touched:Connect(function(hit)
			
			local seat = terry:FindFirstChildOfClass("VehicleSeat") or terry:FindFirstChildOfClass("Seat")
			
			if seat and seat.AssemblyLinearVelocity.Magnitude > speedLimit then
				if hit:IsDescendantOf(workspace.Danger) then
					health = health - 10 -- Example health reduction

					print("Collision at high speed:", seat.AssemblyLinearVelocity.Magnitude)
					print("Health:", health)

				end
				
				-- Reduce health or take necessary action here
			end
		end)
	end
end

If anyone can help me that would make me happy
Thanks in advanced

2 Likes

Try using health:TakeDamage() instead :
Using takedamage will prevent the health from being inferior to 0

health:TakeDamage(10)
3 Likes

I should have added more information but this is a car and I tried so If it hit a wall at a fast speed the car health would go down

1 Like

Can you put a screenshot/video ?
I am not sure that I understand the issue correctly

3 Likes

I only hit the part once and my health goas down to 80 when its only meant to go down 10 (SEE IN SCREENSHOT)

1 Like

Try to add a wait() statement

part.Touched:Connect(function(hit)
			
			local seat = terry:FindFirstChildOfClass("VehicleSeat") or terry:FindFirstChildOfClass("Seat")
			
			if seat and seat.AssemblyLinearVelocity.Magnitude > speedLimit then
				if hit:IsDescendantOf(workspace.Danger) then
					health = health - 10 -- Example health reduction

					print("Collision at high speed:", seat.AssemblyLinearVelocity.Magnitude)
					print("Health:", health)

				end
				
				-- Reduce health or take necessary action here
			end
		end)
wait()
1 Like

Touched will fire a lot during collisions. My guess is that during the collision, seat.AssemblyLinearVelocity will still meet the criteria of being above your speed limit for a couple of frames, which is enough for multiple .Touched collisions to fire. Adding a simple debounce/damage cooldown should suffice.

--debounce variables that keeps track of the last valid damage tick, and when it happened
local debounce = nil
local DAMAGE_COOLDOWN = 1 -- seconds

-- Iterate through all parts in the Terry model
for _, part in pairs(terry:GetDescendants()) do
	if part:IsA("Part") then
		part.Touched:Connect(function(hit)

			local seat = terry:FindFirstChildOfClass("VehicleSeat") or terry:FindFirstChildOfClass("Seat")

			if seat and seat.AssemblyLinearVelocity.Magnitude > speedLimit then
				if hit:IsDescendantOf(workspace.Danger) then
					
					--debounce logic
					--first checks if there is a debounce time set, if not, set it
					--if there already is a debounce time set, check if its less than DAMAGE_COOLDOWN, if it is, damage is on cooldown
					--if its off cooldown (greater than DAMAGE_COOLDOWN), set a new debounce time and continue on with the damage
					if debounce and time() - debounce < DAMAGE_COOLDOWN then
						return
					end
					debounce = time()

						health = health - 10 -- Example health reduction

						print("Collision at high speed:", seat.AssemblyLinearVelocity.Magnitude)
						print("Health:", health)

				end

					-- Reduce health or take necessary action here
			end
		end)
		
	end
end

A debounce essentially stops something from occurring more than once in a given timeframe (or sometimes just not letting it happen ever again).

There are probably better ways to handle a debounce like this, this is just an example.

2 Likes

Yes, that’s why I added the wait() as sometimes the engine would take a few additional frames to update some properties.
I guess a debounce works too

1 Like

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