Search Unity

Physics problem - Incorrect results / bad bounce

Discussion in 'Editor & General Support' started by VeraxOdium, Jul 15, 2011.

  1. VeraxOdium

    VeraxOdium

    Joined:
    Jul 2, 2011
    Posts:
    233
    View attachment 22526

    I have a game board with dynamic objects that the user adds and positions. In the picture there are 3 separate objects, the red arrow is where the ball is headed, the dark green arrow is where it should go, the blue arrow is where it goes on the occasional bad bounce. The ball bounces off the object 2 corner as if object 1 does not exist.

    I've had this problem before and solved it by taking the colliders off the game objects and just throwing down a single plane over the entire length of the game objects and adding a collider to it, but with this game being dynamic, writing a script to do this at runtime would be a nightmare. The game objects are going to be rotated, sometimes moving, in unlimited possible configurations. I also need all sides of the rectangles to correctly take hits.

    The ball is a Rigidbody with a Sphere Collider. The static game objects I've tried box collider and mesh collider. I've messed with every setting I can think of with no difference in results.

    I've read several posts about this but haven't found a solution that will work here. Any help or ideas is appreciated.
     
  2. hippocoder

    hippocoder

    Digital Ape

    Joined:
    Apr 11, 2010
    Posts:
    29,723
    The reason this occurs is because the object penetrates block 1, and bounces off the side or corner of block two. Makes sense. There are several ways to solve this, all of them are expensive.

    1. increase your fixedupdate rate. The default is 50fps, but a higher update rate will lead to less penetration.

    2. Try setting project settings -> physics -> min penalty to 0 or 0.001 etc (try this first)

    3. Try continueous dynamic collision for the ball and continueous for the surface (try this next)

    4. use a raycast just ahead of the ball and prevent it overlapping to begin with

    5. Try like handling the collision yourself. bounce isn't a big deal. To do this is simple enough, you raycast along the velocity vector of the ball, so there is a ray going in the direction you are travelling. This way, when you DO collide, you already have the ray and normal, so you can simply set its new velocity how it should be on collision exit to override.

    There are many solutions but it starts with realising that this is happening because it sinks in tile one enough before it hits tile 2. Knowing that, you can probably solve it.

    It hopefully is reassuring to you to know this is actually quite a common physics problem that crops up again and again over the years (physics problems between the edges of two blocks).
     
    pfjarschel likes this.
  3. Dreamora

    Dreamora

    Joined:
    Apr 5, 2008
    Posts:
    26,601
    That might not needfully be bad setup or anything alike, there is a good chance that the gap is causing it:

    1. Are the "boxes" there really box colliders or did you use mesh? If you used mesh, use box instead, its not bound to surface normal anomalies especially on joining borders between colliders.

    2. if you really line them up ensure that the green boxes overlap slightly so you ahve no gap. or alternatively don't have the box collider on the green boxes at all but place one large covering them.
     
  4. VeraxOdium

    VeraxOdium

    Joined:
    Jul 2, 2011
    Posts:
    233
    Gah! I was going to tweak fixed timestep but then got sidetracked and forgot about it, that absolutely fixed it, many thanks. I lowered it to .0025 (400 updates per second) and at that point was unable to reproduce the error. It killed the framerate from 2000 down to 700 but if the finished project can mantain a decent framerate on lower end hardware this is a perfect fix, it shouldn't be a problem. I tried all the other stuff to no additional effect, thanks for the help guys!
     
  5. hippocoder

    hippocoder

    Digital Ape

    Joined:
    Apr 11, 2010
    Posts:
    29,723
    400 updates per second is pointless though. The other suggestions I made are probably more reliable. 400 updates will kill a slower desktop. Are you sure you tried penalty setting and continueous?
     
  6. VeraxOdium

    VeraxOdium

    Joined:
    Jul 2, 2011
    Posts:
    233
    Yeah I tried 0 and .001 for penalty testing, I've left it at .001. I also tried continuous dynamic on the ball with a mesh collider on the rectangle objects, in the documentation it stated continuous dynamic will only work against a mesh collider not a box collider or else it defaults to discreet, so I switched that to no effect. During all this testing I had the fixed timestep at .01 for 100 updates per second.

    I exported a build to my daughters 5 year old laptop with an integrated GPU, it ran like hell, but it ran (sort of) at timestep .01 800 x 600. I haven't optimized anything in my game yet so it will get considerably better. Also the only rigidbody in the game is the ball, I don't think thats going to change. Almost everything else will be static, possibly I will add some other moving objects, not sure.

    I'm not sure now how this is going to work on slower hardware. The only variable I've changed that has had any effect on the error rate is the timestep. At .0025 I have no problems, at .005 I get an occasional error, perhaps 1 out of 20 ball drops. At .01 I get an error about 1 out of 4 drops.

    This is all done with pretty aggressive situations, the ball is moving quite fast, big drops, the timescale is at 2.75. The reason the timescale is so high is I scaled everything up quite a bit to get away from problems with physX and small objects. The smallest object in the scene is the ball with a scale of 2 built in unity as a sphere primitive. The tallest object which spans the vertical of the screen is 60 units tall. Does this large size plus increased time scale mess anything up? I assume large objects with time scale sped up is no different as far as computations / accuracy goes?
     
  7. hippocoder

    hippocoder

    Digital Ape

    Joined:
    Apr 11, 2010
    Posts:
    29,723
    One thing to really be aware of with physx is that if you have bounces > 1.0 in total (ie multiply or bad values between two) you can get explosive speed increases which break your physics with it passing through or penetrating deeper than you would normally expect. This can happen for many reasons. To fix this you do something like:


    rb.velocity = Vector3.ClampMagnitude(rb.velocity, maxVelocity);

    Where max velocity is the lowest value you can get away with while still having it look good. This prevents bad physics after a few bounces, which can make it penetrate too deeply as its for a short while, going too fast. You don't notice this as it is often corrected within a frame or two, but by then it's too late. Calling that each frame can lead to very stable physics.
     
  8. VeraxOdium

    VeraxOdium

    Joined:
    Jul 2, 2011
    Posts:
    233
    After much research and experimentation I've determined this problem is an unresolvable limitation of PhysX. In any situation involving the edge of a collider contacting a rigidbody it will always register and resolve regardless of what is around it. Lowering the timescale to ridiculous levels wasn't actually fixing it, it was lowering the erroneous forces to an almost imperceptible level. But even at .0025 (400), I could see the slightest fudging of the motion. At that level a player wouldn't notice and it doesn't matter, but like you said Hippo, its unusable on lower end hardware.

    I tried some experiements. Two separate planes with meshcolliders snapped together, if the ball hits the seam just right you will get a bad bounce no matter what, even if the ball is falling straight down with no x,z forces. Box collider + plane, box collider + box collider, mesh collider + plane, there is no combination that will work. Even if I stagger the seams of planes away from each other, a lone seam with a smooth plane at the same level, it still reacts to the seam.

    I can throw a single box collider over 3 objects like in the pic above and it'll be just fine, but I have other objects that require mesh colliders, with every joint of box collider butting up against the mesh collider there will be a seam and there will be an error.

    So the only solution left I take it, is to write a script to throw all the game objects together, combine it all into a single mesh, then run around merging near vertices at the seams, and fix all the data associated with it, lighting / triangles / uv's, then throw a single collider over the whole damn thing? Good god I don't want to do that.

    If anyone has any ideas please let me know, am I wrong about my analysis about physX? I've been screwing with it for about 20+ hours now and see no other possible conclusion. Wherever there is a seam, there is a problem, and that's all there is to it.

    One more thing, I tried combining the objects into a single mesh and throwing a mesh collider on it, it still acts like separate colliders with seams. I guess it combines separate mesh colliders and then calls it 1 collider. Even though the lone game objects don't have any collider on them when they are combined, I was surprised this didn't fix it, maybe I made a mistake somewhere.
     
  9. hippocoder

    hippocoder

    Digital Ape

    Joined:
    Apr 11, 2010
    Posts:
    29,723
    Yeah you're wrong sorta. You are kind of using Physx wrong. It's designed to be fudged, and designed to be an approximation of physics for the sake of speed.

    It fully expects you to correct physical weirdness like jitter and wrong bounces, with your own code in certain circumstances. It is not actually built to be a bullet proof solution, but a fast general purpose solution. Most of those amazing games you see out there today do kludges like raycasts or capping or even overriding physics behaviour with your own.

    Now I'm pretty sure you completely ignored my suggestion to raycast along the physics line and keep the value of the last raycast before a collisionenter, then use it in collision exit to reposition the ball and change it's velocity. If you did this, you would be using physx for movement and collision, but having watertight physics of your own overriding it.

    There is even a script in the wiki for it, something like no penetrate - you'll have to search for it.

    This is something you're not willing to do though, and I respect that. But then, you'll have to live with whatever alternative you want to stick with. There's so many ways you can get this working.

    Try: http://www.unifycommunity.com/wiki/index.php?title=DontGoThroughThings
     
    Last edited: Jul 16, 2011
  10. VeraxOdium

    VeraxOdium

    Joined:
    Jul 2, 2011
    Posts:
    233
    Ahh I see, I thought Physx was supposed to be near perfect, I didn't realize it needs assistance. I guess I had unrealistic expectations, there is no way to avoid getting your hands dirty sometimes. I'm somewhat timid when it comes to mucking with physics as once I tried to build a physics engine from scratch in actionscript / flash. I had many successes and got all kinds of stuff to work really well, but as it grew in complexity and more and more situations arose the hacks / fixes / fudges started to pile up until it became unworkable. Certainly though things here shouldn't come to that with unity and physx doing most of the gruntwork.

    I messed around with raycasting a bit with what you said, I just didn't want to get involved with that for aforementioned reasons, but since its apparent that is the norm and I'll have to do something of that nature, then I'm off now to get that working.

    Your help is much appreciated, you've cleared up a lot of things and steered me down the right track.
     
  11. Fooo

    Fooo

    Joined:
    Mar 11, 2011
    Posts:
    41
    One thing you didn't mentioned is whether or not your game is 2d vs 3d. We just integrated a version of Box2D in to our game and it made the physics simulation much more reliably than using PhysX. I'm not sure if it would address this particular issue, but that's always an alternative.
     
  12. pfjarschel

    pfjarschel

    Joined:
    Mar 31, 2015
    Posts:
    1
    Sorry for ressurrecting this post, but I felt I just had to say this.

    4 years later, and people still have this problem. Hippocoder, I just want to say that your suggestions helped A LOT! Thank you!
     
    hippocoder likes this.
  13. AlienFreak

    AlienFreak

    Joined:
    Jul 2, 2012
    Posts:
    40
    Edit->Project Settings->Physics
    Inspector will show PhysicsManager
    Set 'Default Contact Offset' from 0.01 to 0.001 (I use 0.0001)

    This WILL fix it as I use a ton of cubes in a 3D cubic tile based world. Specifically this works for a game using tons of 1x1x1 meter box colliders (most boxes are static and some dynamic) and a rolling sphere (continuous dynamic).