RunService.Stepped fires unacurralty

Hello!

I was experimenting with the RenderService.Stepped event as I was trying to find a way to detect collisions without a signifiant delay ( .Touched ). Stepped runs prior to the physic simulation but sometimes when I checked for touching parts it didn’t detect any making unable to properly detect collisions.

Would someone know how to fix this? I’m suspecting the update rate to be the cause as prior to it being simulated it is not actually touching and after the simulation it has already bounced of a bit.

local RunService = game:GetService("RunService")

local Part = script.Parent
local Connection

local Params = OverlapParams.new()

wait(10)

Part.Anchored = false

Connection = RunService.Stepped:Connect(function()
	local TouchingParts = workspace:GetPartsInPart(Part, Params)
	
	if #TouchingParts > 0 then
		Part.Anchored = true
		Connection:Disconnect()
	end
end)

Thanks!

No idea why, but there are some things that you haven’t mentioned you tried heartbeat, maybe you need to get both stepped and heartbeat.

According to task scheduler article only after stepped, the part contacts are updated, maybe that’s why?

Stepped — The RunService.Stepped event is fired.
Internal Physics Step
Relative positions of parts joined by Motor6D are updated.
Part contacts and constraints are updated/solved. This can happen multiple times per frame, since physics will update at 240 Hz.

Also this

In contrast, gameplay logic that relies on or reacts to the physics state should be handled in Heartbeat, such as reading the Position of parts to detect when they enter defined zones.

Touching parts should be a reaction and not a cause.

What I’m thinking is the problem is that as I’m using GetPartsInPart() it only detects the touching parts on the go so when .Stepped fires, the part may be not touching anything and when .Heartbeat fires, the part may already have bounced of the touched part which makes it unable to detect anything.

My current solution, is to calculate the velocity difference between Stepped and Heartbeat and use that with the delta to estimate the position where the part touched something.

This honestly sounds like it would be better to use raycasting.

1 Like

It works fairly well but, it would miss some spots and it would not be accurate on meshes. Tough, I use them to get the normal of the touched surface.

You could do both and see which one detects a hit first. I hate using Touched with a passion, but based on this

I think it makes sense that Touched has a chance of firing every 4 milliseconds, vs 16 milliseconds for Stepped or Heartbeat. I assume you’ve tried Touched already, was it better in any way?

1 Like

Kinda but, not really. Touched works almost always which is a great benefit but there is always a delay which cant’t be fixed so if you want to know where both part touched or something in that field is impossible.

Heartbeat and stepped hovewer work rarely ( which can be fixed with math ) but when they do, the part is always touching the other parts which means that there is almost no “delay”. So for finding surface normals ( what I’m doing ) and doing some crazy hit detect it is certainly RunService.

I’m trying to figure out how to find the hit position with these parameters in mind :
Position ( before simulation )
Velocity ( before simulation )
Delta
Position ( after simulation )
Velocity ( after simulation )

We know the overrall time it took for these changes to happen but not how much exactly after the touch and before.

I don’t believe Position and velocity is enough, you will also need delta time to know the end position of the parts.

End position = Position + velocity *deltaTime

Then you can trace the hitbox from initial position to end position. Similar to the source engine but they have access to physics collision there.

Or maybe you can make a line with the position and velocity and see where they intersect for before and after.

You should save the list of parts and stick to that list if it is needed mid-frame or etc. So for example, you can set a refresh rate if you just use the provided parameters that RunService.Stepped passes which is distributed game time (vararg #1) and delta time (vararg #2) and with these arguments (or even just argument #2 and tick) you can just have a frame limiter and then have one table where the parts are stored and another that is used to update the first table based on wether or not a certain amount of time has passed or if your framerate is below the target framerate.

I did mention delta in the post but whatever.
Tough, wouldn’t that be laggy? Checking for colliding part just once already bumped up the proccess usage to 1%. And for the line method, do you mean a line that start at “position” with a direction of “velocity”?