Unity physics 2d crack between colliders.


I have a ball and multiple of alligned blocks.
When the ball moves on the blocks, sometimes the ball collides with one of the blocks as you see in the picture.
The ball was moving left to right and when at the joint of two blocks it sometimes bumps.
As if there was a height difference, like a little crack.
This does not happen with all of the joints. It occurs randomly.
The blocks were created and alligned by code so I don’t see why it has a difference in height.
Only thing that I could think of is somewhere in floating points??

Below is the code from the “Block Manager” gameObject where it creates all the blocks.
I would really like to know why this is happening for sure, and a solution would be even greater.

using UnityEngine;
using System.Collections;

public class BlockManagerScript : MonoBehaviour {

	public GameObject block;

	// Use this for initialization
	void Start () {
		for (int i = 0; i < 200; i++) {
			GameObject blockCopy = Instantiate (block);
			blockCopy.transform.SetParent (transform);
			Vector3 position = block.transform.position;
			position.x += block.GetComponent<SpriteRenderer> ().bounds.size.x * (i + 1);
			blockCopy.transform.position = position;
		}
	}
	
	// Update is called once per frame
	void Update () {
	
	}
}

First ill start off by saying you should probably have a CircleCollider on the ball rather than a BoxColldier. The sharp edges are getting caught in between the blocks. If that still doesn’t work then do this:

Keep a reference to the first block you make (You should probably hand place this one in the scene so that you can easily reference it). From there, whenever you create a new block, you’d just increase the size of the first blocks collider rather than just making a new one every time. This would make one large collider with no gaps and everything should be smooth.

The problem you are seeing comes from the fact that a physics engine in a game doesn’t see the world like we do :slight_smile:

You and I can see a set of boxes next to each other, perfectly aligned, with an object moving along the surface. We therefore conclude that it should never bounce up, as it moving along something flat.

To the physics engine however, each of those boxes that make up the floor are entirely independent objects with which the sliding object can collide. Each frame it works out which ones the sliding object might collide with, and attempts to approximate what the correct physical reaction would be if it did. What you are seeing is an inconsistency when your sliding box is sitting on the surface of 1 box, but touching the corner of another. If the engine processes the surface first, it’ll probably work fine, but if it happens to process the corner collision first, you’ll see a blip!

This problem is made worse by the ‘discontinuity’ in your box-box collision. As your surface object is a box, the results from:

  • its lower edge hitting the edge of the box below it
  • its bottom right corner hitting the top right corner of the next box

Are substantially different - the first simply holds the box up, the 2nd would apply some force up and to the left.

Using a circle collider will certainly help. Technically the physics engine still has the same problem (it doesn’t know which box you hit), but there is only 1 point in time at which a circle is potentially hitting 2 boxes - when it is directly above both their corners. In this situation, both boxes would agree that the correct collision response was simple to push the circle upwards, so you wouldn’t see a blip. This might break down as you get to high speeds (as it’s all approximations), but at suitably low velocities it’d probably be perfectly stable.

If you must use a box for your surface object, then you will either need to:

  • Use 1 large box collider, instead of lots of small ones for the floor
  • If you can’t represent the floor with 1 box collider, you’ll need to generate an edge collider for it

Note that an edge collider has ‘connectivity’ information (each edge knows about other edges), so it can handle the situation in which an object could hit multiple edges more elegantly.

-Chris

Hmm… Maybe your player object is being rotated when you move. It looks like your player is at a slight angle in the screenshot, so this may be a square wheel situation. Every time a corner of the square hits the ground, it bumps up do to an uneven rotation. If this were the case, it would probably still make the player object bob up and down, even when using a circle collider. This could be fixed by freezing your player’s z-axis during movement.

If that’s not it, i’ll have to keep thinking man.

You could also try overlapping your block objects a little when you position them. This isn’t really best practice as far as I know, but it may tell us if gaps between blocks are even the issue here.

// Overlaps blocks by 1%
position.x += (block.GetComponent<SpriteRenderer> ().bounds.size.x * 0.99f) * (i + 1);


Okay I think I found a way to do this. I couldn’t do it the way you guys described because of my game design (1. The blocks are only at the same height for test purpose and in the real game it will be randomly determined. 2. At the end of the platform I need it to sperate like its breaking, so I couldn’t use one collider for all multiple blocks).

Anyways the way I handled it was, at BallScript’s awake method, I made code to add four sperate edge colliders for each of sides in box colliders with little shorter length and to disable box collider at runtime . I call this cutting the corners. (corner cut).

Below is the Awake method in BallScript.

void Awake () {
		rb = GetComponent<Rigidbody2D> ();

		//get Boxcollider2D points
		BoxCollider2D bc = GetComponent<BoxCollider2D> ();
		Vector2[] points = new Vector2[4];

		//Clockwise starting from left top
		points [0] = Vector2.zero;
		points [0].x -= bc.size.x / 2;
		points [0].y += bc.size.y / 2;

		points [1] = Vector2.zero;
		points [1].x += bc.size.x / 2;
		points [1].y += bc.size.y / 2;

		points [2] = Vector2.zero;
		points [2].x += bc.size.x / 2;
		points [2].y -= bc.size.y / 2;

		points [3] = Vector2.zero;
		points [3].x -= bc.size.x / 2;
		points [3].y -= bc.size.y / 2;

		//add EdgeCollider
		edges = new EdgeCollider2D[4];
		Vector2 pointA;
		Vector2 pointB;
		//Clockwise starting from top
		edges [0] = gameObject.AddComponent<EdgeCollider2D> ();
		edges [0].points = new Vector2[]{new Vector2(points[0].x + colliderCornerCut, points[0].y), new Vector2(points[1].x - colliderCornerCut, points[1].y)};

		edges [1] = gameObject.AddComponent<EdgeCollider2D> ();
		edges [1].points = new Vector2[]{new Vector2(points[1].x, points[1].y - colliderCornerCut), new Vector2(points[2].x, points[2].y + colliderCornerCut)};

		edges [2] = gameObject.AddComponent<EdgeCollider2D> ();
		edges [2].points = new Vector2[]{new Vector2(points[2].x - colliderCornerCut, points[2].y), new Vector2(points[3].x + colliderCornerCut, points[3].y)};

		edges [3] = gameObject.AddComponent<EdgeCollider2D> ();
		edges [3].points = new Vector2[]{new Vector2(points[3].x, points[3].y + colliderCornerCut), new Vector2(points[0].x, points[0].y - colliderCornerCut)};

		//Disable BoxCollider2D since we now have edges
		bc.enabled = false;
	}

This lets me move smoothly on the surface. This method is really easy on box colliders but I don’t think it will be easy to implement the same method on different shapes. But I think this does it for now.

Thank you all for your suggestions and It will be great if someone has a better method to accommodate all kinds of shapes.

Thank you!

Xon, are you aware very simply of adjusting the penetration default?

“The minimum contact penetration value
in order to apply a penalty force
(default 0.05). Must be positive. This
value is usually changed in
Edit->Project Settings->Physics”

Often you can solve these sorts of physics problems by just adjusting that.


Second, note that it is very common when you’re dealing with let’s say “microphysics” like this, that you need unusually shaped colliders.

There was a suggestion above that you should use a round collider. that’s not right, but what you very likely need is a collider that is shaped like a cube, but, has rounded edges - bevels if you will.

(If you think about it, this is exactly what happens in real life. Real life cubes of all types have gently rounded edges, even if only seen at a small scale.)

You should try a collider like this …

60484-screen-shot-2015-12-22-at-81630-am.png

Turn off the box collider and add little balls like that. (You may wish to also leave on the box collider, perhaps inset a little, depending on how your game plays.)

Consider also using long thin capsule colliders along the edges.

It’s perfectly normal that you have to use a collection of colliders, to, make an object work in a video game, it is the usual thing. A very simple example is, have you yet done a car game. At first you might just put one box collider for the car. But it’s better to have one for the “lower part” of the car up to the lower window line, and then a box for the “upper part” of the car. Further, you might use perhaps a capsule collider for along the front or back. And so on.

in short try basically adding small “rounded, bumper” colliders to your object, and see if you can get what you need.

Don’t forget that in real life that dice or box would indeed have rounded edges. You don’t have absolutely sharp edges in real life.