How can I prevent Physics2D Objects from bugging out when overlapping each other?

Hi,

I have a problem: In my game I have a surface (a table) with some objects on it; those objects have Physics2D Behaviour (Collider & Rigidbody) enabled when they are laying on the surface. However, when the player picks up one of those objects (clicks on them), I turn off Physics and make the object follow the mouse cursor.

This works well, however, when I drop the object on the surface, depending on whether or not the object overlaps another object, this leads to some unwanted behaviour:

Pictured here is a case in which this works well (when I drop similar sized objects on top of each other or when I drop something on the edge of something else)

alt text


And this gif shows the problem: When I drop a smaller sized object on top of a larger one, the smaller one “floats” inside the larger one until it leaves the collider (which can take a while).

alt text

So I know, the obvious solution would be to avoid turning on and off Physics but this is not really an option.
Is there maybe a way to “force out” the dropped upon object or something like that?

Thanks for your help!

Maybe just try this:

First, apply a tag (let’s say “pickableItem”) and a trigger collider to each of the items on the table.

using UnityEngine;
using System.Collections;

class forceMoveObjects : MonoBehaviour
{
bool checkForBug = false;
float minDistanceX = 0.0f; //choose the minimal allowed distance on x
float minDistanceY = 0.0f; //choose the minimal allowed distance on y

void OnTriggerEnter(Collider collider)
{
	if(collider.tag == "pickableItem")
	{
		checkForBug = true;
	}
}

void OnTriggerExit(Collider collider)
{
	if(collider.tag == "pickableItem")
	{
		checkForBug = false;
	}
}

void Update()
{
	if(checkForBug == true)
	{
		distanceX = Vector2.Distance(this.transform.position.x, collider.transform.position.x);
		distanceY = Vector2.Distance(this.transform.position.y, collider.transform.position.y);
		
		if(distanceX < minDistanceX)
		{
			if(this.transform.position.x < collider.transform.position.x) //this object is more to the left
			{
				this.transform.position = new Vector2(this.transform.position.x-20.0f, 0); //adjust the number (20.0f) until you like it
				collider.transform.position = new Vector2(collider.transform.position.x+20.0f, 0); //adjust the number (20.0f) until you like it
			}
			else //this object is more to the right
			{
				this.transform.position = new Vector2(this.transform.position.x+20.0f, 0); //adjust the number (20.0f) until you like it
				collider.transform.position = new Vector2(collider.transform.position.x-20.0f, 0); //adjust the number (20.0f) until you like it
			}
		}
		
		if(distanceY < minDistanceY)
		{
			if(this.transform.position.y < collider.transform.position.y) //this object is lower
			{
				this.transform.position = new Vector2(0, this.transform.position.y-10.0f); //adjust the number (10.0f) until you like it
				collider.transform.position = new Vector2(0, collider.transform.position.y+10.0f); //adjust the number (10.0f) until you like it
			}
			else //this object is higher
			{
				this.transform.position = new Vector2(0, this.transform.position.y+10.0f); //adjust the number (10.0f) until you like it
				collider.transform.position = new Vector2(0, collider.transform.position.y-10.0f); //adjust the number (10.0f) until you like it
			}
		}
	}
}

}

This basically checks if the something entered your trigger, then checks if the distance between those two objects is lower than you want (for each axis), and if so, it moves each object away from the other one by the number you have to adjust.

Hope this works, :stuck_out_tongue: