Unity 2D - Avoid Pushing between rigidbody

i have an issue with my 2D game in unity (pokemon style), i’m using transform.position to move the gameobjects

I have a player and enemies that follow him, all is ok, but when the enemies make a collision then they begin to push each other, enemies and player has rigidbody and box collider 2D

I need that nobody to be pushed when the enemies or player get a collision.

  • tryed to use kinematic in enemies but the player can push them.

  • tryed to add a big amount of mass to the player but he can push the enemies.

  • tryed to detect the collision in code with OnCollision* but when i cancel the enemy movement they dont return to move.

Here is a video of my problem

If you’re bypassing movement controlled by the 2D physics system then you must set the Rigidbody2D component to be Kinematic. If you don’t want the physics system to produce collisions then set the collider to be a trigger and use the OnTriggerXXX callbacks instead. Additionally, use the collision layers to control what can contact each other in the 2D physics settings.

1 Like

I need the collision but without pushing between them

When i try OnTriggerXXX callbacks both object stop but they dont move again because they are permanently collide

Im really out of ideas, somebody has a similar problem?

Really isn’t enough information to help you, the failing logic must be in your scripts and/or where you having those scripts called.

If you want collision response (presumably you’re calling this ‘pushing’) then don’t use triggers. If you don’t want a collision response then use triggers. If you want to know when it first happens then use the ‘enter’ callbacks, if you want it continuously then use the ‘stay’ callbacks and if you want it when the contact ends use the ‘end’ callback.

If you don’t want things to contact each other at all then use the 2D physics settings to control the what layer(s) can contact other layer(s).

Beyond that, not sure what else I can say without you providing more information.

First of all, you’re probably better of using rigidbody2D.MovePosition, instead of transform.position.

You should not be able to push things that are set to kinematic. I tried using several different movement techniques and I was not able to push anything kinematic. The only problematic situation I found was when two kinematic objects collide. In that case they pass through each other.

Detecting collision with OnCollision* and then moving back to the previous position should work.

You could always use something like Physics2D.OverlapCircle to see if the position you are about to enter is already occupied.

1 Like

As i can see Unity has not native way to prevent push between rigidbodies, I’ll try improve more complex way to prevent push and detect collider at same time (Physics2D.OverlapCircle can be a good option)

thanks for all guys

Again, why not use triggers? These tell you what overlap and don’t ‘push’ each other.

1 Like

Finally I’ll get the expected result,changing the rigidbody2D.isKinematic property to true when the target was close and stop it

Here is a video

And the enemy movement code

void FixedUpdate () {

    if(path == null)
        return;

    if(currentWayPoint >= path.vectorPath.Count)
        return;

    float distanceTarget = Vector3.Distance (transform.position, target.position);

    if (distanceTarget <= 1.5f) {
        rigidbody2D.isKinematic = true;
        return;
    }else{
        rigidbody2D.isKinematic = false;
    }

    Vector3 wayPoint = path.vectorPath [currentWayPoint];
    wayPoint.z = transform.position.z;

    transform.position = Vector3.MoveTowards (transform.position, wayPoint, Time.deltaTime * speed);

    float distance = Vector3.Distance (transform.position, wayPoint);

    if(distance == 0){
        currentWayPoint++;
    }

}

@MelvMay , I’ll try to test Physics2D.OverlapCircle and comment the result too

Do you have any example to apply in my case? i check the documentation but not understant at all

@MelvMay sorry, I thought you meant Physics2D.OverlapCircle. I tried triggers, but when 2 enemies collide both stop moving

If they stop moving then that’s your logic in the callbacks, nothing to do with the physics system so you need to look there. Also, you should ALWAYS use kinematic rigid-bodies (never use dynamic ones) if you’re setting the position yourself via the transform.

Hi,
first put your enemy in a layer (“EnemyLayer”) and your Player in another layer (“PlayerLayer”) then all you need to do is to create a new script and put the following code in Start method :
Physics2D.IgnoreLayerCollision (LayerMask.NameToLayer (“PlayerLayer”), LayerMask.NameToLayer (“EnemyLayer”));

after that put the script on camera and that’s it . . .

2 Likes