# Collisions in high speed without unity physic / rigidbody

Hello everyone,

These days i experimented to works without unity physic / rigidbody in order to create a responsive 2D platformer, with importants velocities.
I use transform.Translate(velocity * Time.deltaTime) to apply my movements.

During my first test I managed collisions with :

• Raycasts (i fire 12 raycast, 3 by side, size 1by 1)
• If i collide (my player is inside a collider) i use transform.position to set the correct position of my player

For exemple, to detect the groud :

``````Collider2D colMiddleSouth = FireRay(new Vector3(collider.bounds.min.x + halfWidthSprite, collider.bounds.min.y, 0), Vector3.down, 1);
Vector3 col_v3 = colMiddleSouth.bounds.max;
transform.position = new Vector3(transform.position.x, col_v3.y + halfHeightSprite, 0);
``````

I was not satisfied because it becomes hard to manage complex collisions

So i did a second try, and i managed collisions with :

• Raycast, all the trick is to set the good length of the raycast according to playerâ€™s velocity
• then if i collide at the length of my raycast i set velocity.x or .y to 0

For exemple :

``````        float directionY = Mathf.Sign(velocity.y);
rayLength = Mathf.Abs(velocity.y) * Time.deltaTime ;

RaycastHit2D hit = Physics2D.Raycast(new Vector2(transform.position.x, transform.position.y-halfHeightSprite), Vector2.down, rayLength, collisionMask);
Debug.DrawRay(new Vector2(transform.position.x, transform.position.y - 25), Vector2.down * rayLength, Color.red);

if (hit)
{
velocity.y = 0;
}
``````

This time again i am not satisfied of the result.

Did you know others ways to manage collisions without rigidbody/unity physics?

Try spherecast or overlap sphere at your game objects position each frame it moves. Every fixed update I suppose.

Yes i did come tests with overlap.
But my real problem here is how to manage pixel perfects collisions at high speed.
I wonder there are betters ways to manages collisions.

How high a speed are we talking max velocity? 4000?

because I notice raycast misses from certain angles even with draw ray on objects particular objects which are moving. Why donâ€™t you see if itâ€™s possible to for one frame only set your fixed update speed to be faster than your update speed, or your update speed to be switched off and to try and get two rapid collision checks in row before reverting update cycle.
So hopefully when the first check misses, the second check doesnâ€™t.

The answer might be in time

You say youâ€™re not using 2D physics but youâ€™re using queries therefore obviously colliders. This IS using 2D physics therefore you need to use it correctly so here are some basic rules:

• Donâ€™t ever modify the Transform if using 2D physics components

• If you want a 2D Collider to move then add a Rigidbody2D and use its API to move it; many ways to do this.

• Rigidbody2D donâ€™t make it â€śunresponsiveâ€ť. If you want explicit control then set the body-type to Kinematic; itâ€™s what itâ€™s for.

• When you query, donâ€™t use the Transform position as a reference, itâ€™s not the authority on the pose, thatâ€™s the Rigidbody2D so use its position/rotation properties.

If you donâ€™t use a Rigidbody2D but 2D colliders then youâ€™re implicitly saying Static (non-moving) colliders but then go and change the Transform going against that. Changing the Transform on a GameObject with only a Collider2D is relatively expensive as it requires the Collider2D to be recreated from scratch. Even worse, youâ€™re likely doing so per-frame when physics doesnâ€™t even run per-frame by default unless youâ€™ve selected that. Also, changing a Transform doesnâ€™t even update anything other than the Transform. Renderers only know this when they render. Likewise physics only knows this when it runs which is again, by default, during the fixed-update.

If you change the Transform, nothing in the physics (or any other system) will follow this change. This means that if you then also run a query, itâ€™ll be querying colliders as they were the last simulation step and wonâ€™t be related to the change of Transform.

So from above, adding a Rigidbody2D and setting it to be Kinematic means itâ€™s entirely under your control. Use its API to cause it to move. Use the Rigidbody2D.position/rotation properties to refer to the position. If you want smooth motion then either set the physics to update per-frame or leave it at default and set the Rigidbody2D to use interpolation.

There are loads of queries such as casting a Rigidbody2D or an individual collider. You can even ask the distance which also shows overlap so you can resolve overlap collisions yourself. You can control all this detection and movement.

You just need to stop driving the Transform system as if youâ€™re driving a per-frame renderer.

4 Likes