I am working on a match 3 game in Unity. The tiles have a RigidBody2D in dynamic mode and a BoxCollider2D. When a match occurs and the tiles are removed, the tiles above (including spawned replacement tiles) fall until they land on another tile or the tile catcher at the bottom of the board. There is a routine which checks when everything is settled (all tile rigidbodies are asleep) and then processes any new matches. However, the tiles push each other down on impact, causing a rebound and a very slow process of "settling" to their final position. The physics material for the tiles has no bounciness, so I believe this is being caused by the cumulative force of the tiles landing on each other in the physics simulation.

What I'm hoping to do is have the tiles drop the way they do (the gravity simulation is just right!) but essentially stop when they collide with another tile (i.e. not transfer any force at the point of collision). This way, they shouldn't rebound visually and also should sleep more rapidly, so matches from falling can process more immediately.

So far, the suggestions I've seen are:

  • Set the velocity to 0. This doesn't work, and I assume it's because there is still being force applied.
  • Detect the tile collision and set the tile to kinematic, then set it back to dynamic. I haven't been able to get this to work, as they won't turn back to dynamic. I even tried to disable the colliders until they turn back in case the collision detection keeps happening and is just overwriting it too rapidly. At any rate, this feels like a dead end.
  • Scrap the rigidbodies and essentially write my own, scripted gravity simulation. I'm simply hoping to avoid this because the rest of the simulation is working great.
  • Create a kinematic rigidbody on a child object, set the dynamic parent and kinematic child to ignore collisions with each other, make the kinematic collider slightly (0.1) larger so it collides first. I gather the idea here is to have the physics simulation pull down the dynamic body, while the kinematic child will stop on collision. At any rate, this also did not work, and also sounds like a bad idea.

I've considered trying to calculate the impact force and apply an equal opposing force, but I haven't figured that out yet, and I imagine at that point I should just write my own gravity simulation, per above.

I've recorded a video for visual reference on the "bounciness": https://youtu.be/aSCEJX4nzoI

  • \$\begingroup\$ i think your physics based method on this is wrong. even if you want to go physical you have to handle may things. \$\endgroup\$ – virtouso Sep 9 '19 at 7:46
  • \$\begingroup\$ I think your physics is just fine, you just need to tweak the project settings. It looks as though it's not "Bouncing", rather it's overshooting the collision and correcting itself (by moving the tiles away from each other to remove the overlap - that's the 'decompression' you are seeing). I would try increasing the "Default Contact Offset" to remove the overlap, and reducing the "Time to Sleep" to try and get them to settle quicker... Project Settings -> Physics 2D is the answer here. \$\endgroup\$ – allnodcoms Sep 9 '19 at 9:12
  • \$\begingroup\$ Default Contact Offset increases spaced the objects out vertically, but the settling behavior didn't change. That said, I did some stuff with Gizmos and it's absolutely that they are pushing "into" each other and then resolving out. So that is the right angle of attack. Time to Sleep helped a bit with responsiveness. I also put a bit of drag on the tiles and increased the effect of gravity on them to compensate for the reduced falling speed and it feels a bit better. Thanks for your help. I'll try any other ideas, but this is okay for now. \$\endgroup\$ – Justin Duewel-Zahniser Sep 9 '19 at 11:21
  • \$\begingroup\$ maybe you shouldn't use physics and you could just use scripts to make your blocks fall? this would eliminate the problem. \$\endgroup\$ – Millard Sep 11 '19 at 17:59
  • 1
    \$\begingroup\$ Just had a thought... What's the Collision Mode? Discrete? Try Continuous.Discrete allows object penetration (which you are experiencing) while continuous doesn't. \$\endgroup\$ – allnodcoms Sep 13 '19 at 4:58

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.