The engine does not see collisions at very high speeds (SOLVED, but you can help)


If you take 2 objects and let’s say the first object will have a dynamic collision and the second will have a static collision. If you accelerate a dynamic object to a certain speed and higher, then the dynamic object will pass through the static object.
how i can fix it?



What you’re describing is the problem of continuous collision detection. In order to fix objects tunneling through other objects due to high velocities, we usually take the lazy (AKA more productive) way out and implement a max_speed value, then clamp an object’s velocity below max_speed so that tunneling never occurs.

Defold does not provide an out-of-the-box solution to this problem.



Thanks, I just thought of one idea. We find out the direction of movement of the object and create a ray to the point that will be in the next frame, and if something is in the path of the ray, then this means that at this point we have to bounce off the object. Tomorrow I’ll try to implement it, but I don’t quite understand how to implement collision with an object, let’s say if our restitution is 1, then nothing prevents us from simply changing the direction of movement, but what if we have a different value. I don’t really want to write collision physics



If you don’t want to cap the max velocity, rays are the way to go. You don’t need to resolve the collision yourself. Move the body to the ray intersect point and let Box2D handle it.

You may need to read linear_velocity and angular_velocity before and set it after you move it. You may also want to disable the collision object of the dynamic body before you move it and enable it afterwards.






it works, but not always. I set high speed values ​​just for demonstration, in the game this speed will not be

Also on the gif you can see what is not visible on the monitor. The moment when the ball bounces off the snake is not visible on the monitor, for me it was displayed as the ball goes through the snake

with raycast:

without raycast:


local prevX, prevY
local myX, myY
local nextX, nextY;

function update(self, dt)
	myX = go.get_world_position().x
	myY = go.get_world_position().y
	if(prevX ~= nil)then
		local nX = (myX - prevX)
		local nY = (myY - prevY)
		nextX = nX*1.5+myX
		nextY = nY*1.5+myY

		local nextFrPos = vmath.vector3(nX+myX,nY+myY,0)
		local result = physics.raycast(go.get_position(), vmath.vector3(nextX,nextY,0), {hash("default")})"@render:", "draw_line", { start_point = go.get_position(), end_point = vmath.vector3(nextX,nextY,0), color = vmath.vector4(1,0,0,1) })
			if(math.abs(nextFrPos.x - result.position.x)<math.abs(nextX) and math.abs(nextFrPos.y - result.position.y)<math.abs(nextY))then
	prevX = myX
	prevY = myY


guys, I will be grateful for any improvement of the code)