Search Unity

Object too small for Physics

Discussion in 'Scripting' started by MitchStan, Jun 17, 2007.

  1. MitchStan

    MitchStan

    Joined:
    Feb 26, 2007
    Posts:
    568
    I have a small object (hockey puck). When it's velocity is too great, it doesn't react with the box colliders for the ice surface, the end boards or the players.

    I've tried playing around with the time values in the project settings, but it is hit and miss.

    Is there anything I can do to get the physics engine to 'catch' the collisions of a small object at high speeds?

    Should I scale everything up in size? But then I would have to scale up the speed as well.

    I'm stumped. Any advice would be greatly appreciated.

    Mitch
     
  2. AaronC

    AaronC

    Joined:
    Mar 6, 2006
    Posts:
    3,552
    If you create a denser mesh, ie more polygons/verts, that will increase colision detection. this may solve your problem.
    AC
    Edit-I guess your using a mesh collider for your puck and need to use primitives for your level. Try having 4 or 8 box colliders side by side where you currently have one...HTH
     
    art092 likes this.
  3. bronxbomber92

    bronxbomber92

    Joined:
    Nov 11, 2006
    Posts:
    888
    How are you moving the object. I know when moving something at a high speed by directly changing it's location, or using the translation, it will often not collide.
     
  4. Eric5h5

    Eric5h5

    Volunteer Moderator Moderator

    Joined:
    Jul 19, 2006
    Posts:
    32,401
    I'd probably raycast in the direction the puck is traveling in, and the length of the raycast should be the distance the puck would travel in one physics frame (which you'd get from the velocity's magnitude). If the raycast hits anything, move the puck to the raycast hit location. That way it should collide 100% of the time. Otherwise the puck can pass though objects from one physics frame to the next and thus not register a collision, which you already know but I said it anyway. ;)

    Not such a good idea if so...I used a mesh collider for the coin in Unity Invaders, but had to limit the velocity (you can "throw" the coin around), or else it would do some really wacky things. For Unitroids, I switched the coin's collider to a group of 8 box colliders instead, which works about 95% as convincingly as the mesh collider but doesn't have any problems.

    --Eric
     
    Deleted User likes this.
  5. forestjohnson

    forestjohnson

    Joined:
    Oct 1, 2005
    Posts:
    1,370
    I would use a raycast instead too. You don't even need to have a rigidbody envolved. And if your hockey sticks actually collide with the puck as it is now, it would be simple to create a hockey stick script that fakes collisions with the puck.

    Generally anything that is too small/fast for the physics engine should be raycasted.
     
  6. DaveyJJ

    DaveyJJ

    Joined:
    Mar 24, 2005
    Posts:
    1,558
    I need this for my soccer ball too. It can at times be "kicked" to fast and fly through what are normally solid objects.

    How do you write a raycast though from the object looking forward?
     
  7. bronxbomber92

    bronxbomber92

    Joined:
    Nov 11, 2006
    Posts:
    888
    There might be problem raycasting as the ball is moving on a dynamic curved path (I believe), so you probably need to precalculate the end of the path (or any points in the air if there is collision in the air), and check for collision there, and then you could use raycasting after it lands. Here's how to use Raycasts: http://unity3d.com/Documentation/ScriptReference/Physics.Raycast.html?from=RaycastHit

    *Cough*AIM*Cough* :)
     
  8. MitchStan

    MitchStan

    Joined:
    Feb 26, 2007
    Posts:
    568
    I'll try using a raycast - I'm learning Unuty as I go - so I'll give it my best.

    One question though - I am using rigidbody.AddForce to move the puck. If I use a raycast to catch collisions - how should I use that info to move the puck? Do I cancel out the rigidbody.velocity for the physics frame that involves a collision and move the puck's transform.position via coding?

    Thanks for any advice.
     
  9. Eric5h5

    Eric5h5

    Volunteer Moderator Moderator

    Joined:
    Jul 19, 2006
    Posts:
    32,401
    Well, no, you'd just get the forward velocity of the ball. My idea is to look forward a small bit (the distance between physics frames) as it's moving. This avoids the "passing through obstacles" effect. With all due respect to the mighty Yogster, I'd stick with rigidbodies because you want the puck/ball to bounce around and stuff, and objects can change between the time you hit the puck/ball and the time it hits something. Unlike a bullet where you just look along a straight line to the hit point and it goes more or less instantly.

    But as far as the soccer ball, try increasing the physics timestep first. I don't think you're doing much physics, so you should be fine increasing it from .02 to .01 (which makes physics go 120fps instead of 60fps). If that doesn't work, then we'll try the raycasting.

    --Eric
     
  10. forestjohnson

    forestjohnson

    Joined:
    Oct 1, 2005
    Posts:
    1,370
    I should probably post one of my numerous raycast projectile scripts reworked as a puck.

    Code (csharp):
    1.  
    2. // PuckPhysics.js
    3.  
    4.  
    5. var mass = 1.00;
    6. var drag = 0.00;
    7. var bounce = 1.00;
    8.  
    9. private var velocity : Vector3;
    10. velocity = transform.TransformDirection(Vector3.forward) * speed;
    11.  
    12.  
    13. function AddForce(f : Vector3)
    14. {
    15.     velocity += f / mass;
    16. }
    17.  
    18. function Update ()
    19. {
    20.     velocity -= velocity * Time.deltaTime * drag;
    21.    
    22.     var hit : RaycastHit;
    23.     if(Physics.Raycast(transform.position, velocity, hit, velocity.magnitude * Time.deltaTime))
    24.     {
    25.         transform.position = hit.point;
    26.        
    27.         velocity = Vector3.Reflect(velocity, hit.normal) * bounce;
    28.        
    29.         if(hit.rigidbody) hit.rigidbody.AddForce( (-hit.normal + velocity.normalized) * mass * 0.5 );
    30.     }
    31.  
    32.     transform.position += velocity * Time.deltaTime;
    33. }
    34.  
    To use it:

    Code (csharp):
    1.  
    2. someObject.GetComponent(PuckPhysics).AddForce(direction * whackForce);
    3.  
     
  11. MitchStan

    MitchStan

    Joined:
    Feb 26, 2007
    Posts:
    568
    Thank you, Yoggy.

    So, the solution is to not use the built in phyics engine and script all the physics?

    Anyway to do this utilizing the physics engine?

    By the way - I am seeing some odd behavior with the physics engine. I have a puck with a box collider and a rigidbody attached. I let it drop from 100 meters high onto a flat plane.

    The puck falls due to gravity - it bounces once - goes up, then back down - and then it FALLS through the plane.

    Why would it register a collision on the first impact and not the second? The velocity is greater on the first hit (having fallen 100 meters) than on the 2nd bounce.

    Why would the physics engine catch the collision on the faster velocity and not the slower velocity?

    I have no scripts attached to any GO.

    Is this normal?
     
  12. MitchStan

    MitchStan

    Joined:
    Feb 26, 2007
    Posts:
    568
    I think I may have a solution. The issue seems to be the small size of the box collider around the puck. If I make the box collider larger, it can handle the collisions at higher speeds.

    But that kind of looks odd - the collision happens before the puck actually touches anything (the box collider is larger then the puck mesh).

    But I can offset the box collider so that the leading edge of the puck is up against the edge of the box collider in the direction it is traveling.

    And that looks and works perfect. I've been doing this all via the inspector. Once I code something that works, I'll post it.

    Mitch
     
  13. Eric5h5

    Eric5h5

    Volunteer Moderator Moderator

    Joined:
    Jul 19, 2006
    Posts:
    32,401
    If the collider happens to intersect with another collider that frame, no matter how fast it's going, then you'll get a collision. But if the collider happens to just miss intersecting with another collider even if it's going slower, it won't collide. So it can be kind of random. But faster speeds are more likely to result in misses.

    Anyway, you seem to have a pretty nifty solution. If that works, go for it. If you'd still like to use raycasting, try this:

    Code (csharp):
    1.  
    2. private var diameter : float;
    3.  
    4. function Start() {
    5.     // Use "diameter = collider.radius * 2" for sphere colliders
    6.     diameter = collider.extents.y * 2; // Should be smallest axis
    7. }
    8.  
    9. function FixedUpdate() {
    10.     var distanceThisFrame = rigidbody.velocity.magnitude * Time.deltaTime;
    11.     // If the distance is less than the diameter, just let the physics engine handle collision detection
    12.     if (distanceThisFrame > diameter) {
    13.         var hit : RaycastHit;
    14.         var direction = rigidbody.velocity.normalized;
    15.         // If we would hit something this frame, move to that position to ensure it
    16.         if(Physics.Raycast(transform.position, direction, hit, distanceThisFrame)) {
    17.             transform.position = hit.point;
    18.         }
    19.     }
    20. }
    21.  
    DaveyJJ, that works well for soccer balls...note the comment in the Start function.

    If you'd like to try something that approximates a cylinder for the hockey puck so that it might have more realistic reactions to collisions, make some box colliders as children of the puck, as shown below.

    And make sure the collider(s) are on the Ignore Raycast layer, or else the raycast will detect the puck/ball itself, and then bad things can happen. ;)

    --Eric
     

    Attached Files:

  14. DaveyJJ

    DaveyJJ

    Joined:
    Mar 24, 2005
    Posts:
    1,558
    Duly noted Eric, thanks. I will after work attempt this and also getting the "if the ball speed is less than ... destroy the ball" thing working.

    Otherwise, project moving ahead lovely.

    Sorry for the thread hijack.
     
  15. Daniel_Brauer

    Daniel_Brauer

    Unity Technologies

    Joined:
    Aug 11, 2006
    Posts:
    3,355
    Question! Why doesn't Ageia do this anyway? After a certain point, increasing the rate FixedUpdate fires has diminishing returns. Checking lines between previous and current positions isn't a perfect solution, but it's better than missing entirely when you go through something.
     
  16. Aras

    Aras

    Unity Technologies

    Joined:
    Nov 7, 2005
    Posts:
    4,770
    Just checking the lines is not a completely robust solution. If the object is mostly spherical, you'd have to check the capsule ("swept sphere") - because a ray from current position to future position might pass, but object should have collided with something just a bit "off the center".

    It gets more complicated with non-spherical objects, i.e. how would you robustly check a box that is moving, while rotating at the same time? The proper way would be colliding something like a "screw" shape...
     
  17. MitchStan

    MitchStan

    Joined:
    Feb 26, 2007
    Posts:
    568
    Thanks for the help, Eric. I'm still learning Unity, so Ignore RayCast layer is new to me.

    But I think a combination of dynamically changing the size of the box collider size and center with respect to velocity works well in combination with Physics.Raycast.

    Pseudo code:

    if (Physics.Raycast hit.distance <= velocity.magnitude)
    adjust box collider to register the collision
    else
    reset box collider to original state

    I'm working on the code now - I have the box collider size and center adjusting dynamically to velocity and it works great, but I anticipate side effects such as a collision registering behind the puck if a player should skate in behind the puck.

    So I will now try the raycast conditional statement.

    Will post some code soon.

    Mitch

    PS - Your code looks a lot simpler than my crazy solution. Might just go with your code. Thanks again.
     
  18. Eric5h5

    Eric5h5

    Volunteer Moderator Moderator

    Joined:
    Jul 19, 2006
    Posts:
    32,401
    It's also useful for when you have invisible trigger areas that block effects like lens flares. In this case you just put the triggers on Ignore Raycast and the effects will show through properly. Also if you have objects or triggers blocking other objects that you want to react to OnMouseOver etc. events, then put the blocking objects on Ignore Raycast and mouse events will go through them.

    As far as raycasting, it might be useful to cast several rays from the edges of the object instead of one from the center. That should take care of perfect spheres, although it still wouldn't account for possible tumbling of any other shape. But I think you could assume that objects aren't going to tumble enough from one physics frame to the next to make any real difference, especially since Max Angular Velocity defaults to a quite low value. Effectively I think several raycasts would cover almost all real situations.

    But I guess at some point you have to say "good enough"...at those extreme speeds I doubt you'd be able to tell visually if the puck (or whatever) should have clipped something or not anyway. The big concern is having objects just pass right through stuff they obviously shouldn't, so even one ray prevents that.

    --Eric
     
  19. Daniel_Brauer

    Daniel_Brauer

    Unity Technologies

    Joined:
    Aug 11, 2006
    Posts:
    3,355
    I guess it just seems that even a non-robust solution would be better than none. Currently, it's very easy for small things to go through big ones, and checking a few lines could prevent most of the instances I've seen.
     
  20. MitchStan

    MitchStan

    Joined:
    Feb 26, 2007
    Posts:
    568
    Eric,

    I'm trying to learn from your coding example, but it's just not working. I'm dropping the puck from 1000 meters so by the time it reaches the playing surface, it's gained a lot of velocity.

    With your script attached - it just passes right through.

    Any thoughts?

    Mitch
     
  21. Eric5h5

    Eric5h5

    Volunteer Moderator Moderator

    Joined:
    Jul 19, 2006
    Posts:
    32,401
    Hmm...I accelerated a small puck using that script to about 10 km/s and it never passed through anything, so it should work just as well under more sane conditions. (Edit: just tried 100 km/s and it still works...) Can you post your script?

    --Eric
     
  22. MitchStan

    MitchStan

    Joined:
    Feb 26, 2007
    Posts:
    568
    I am using just the code you posted - no other code.

    The puck is a GO -> Cylinder. I removed the capsule collider and added a box collider. And also added the rigidbody component. Reduced the scale of the transform to (1, .25, 1) in the inspector. So the scale.y is reduced. (Makes the cylinder look like a puck).

    The playing surface is just a GO -> plane (with a mesh collider).

    The project fixed time stamp setting is .01.

    I'm just dropping the puck from 1000 meters and it passes right through the plane mesh. Again, I have only your code attached.

    Should work. What could I be doing that makes this physics test fail?

    Mitch
     
  23. hsparra

    hsparra

    Joined:
    Jul 12, 2005
    Posts:
    750
    I don't think I would want to get in the way of that puck :eek:
     
  24. MitchStan

    MitchStan

    Joined:
    Feb 26, 2007
    Posts:
    568
    After much experimentation and trial and error, I was able to modify Eric's and Yoggy's script and come up with something that works for small GO's traveling at high velocities. It let's the physics engine do all the work, the code just makes sure that the object doesn't pass through anything without colliding.

    It seems to work no matter how fast or at what rotation or direction the GO (puck) is traveling, or whatever the rotation and position and scale of the mesh in collides with.

    I've yet to find a way to break it.

    I'm posting this for completeness since I'm sure others will have this same issue.

    I do have one question that maybe someone can help me with. If you look at the code, you'll see the constant .025 is used to dictate the scale of the puck's shortest axis (the Y axis). I was trying to use collider.bounds.extents.y, but for some reason that didn't work. I also tried collider.extents.y - still no success.

    The value of extents seems to change based on the GO's rotation! This might be a good thing.

    The scale of the Y-axis of the puck is .025. The x and z axis is longer -- .076.

    Does anyone know how I can use the collider.bounds.extents in combination with the GO's rotation and the velocity vector of the rigidbody to dynamically program the length of the axis in the forward direction of travel? So if the puck is traveling on end (instead of flat) the value of diameter properly reflects that. Or for any rotation at all (the puck as a projectile does not always point in the direction it travels).

    I hope that made some sense. Thanks for any and all help.

    Mitch

    Code (csharp):
    1.  
    2. var distanceThisFrame : float;
    3. var direction : Vector3;
    4. private var diameter = .025;
    5.  
    6. function FixedUpdate()
    7. {
    8.     var hit : RaycastHit;
    9.     direction = rigidbody.velocity.normalized;
    10.     distanceThisFrame = rigidbody.velocity.magnitude * Time.deltaTime;
    11.    
    12.     // if distanceThisFrame < diameter, no need to check for collision - physics engine will work fine
    13.     if (distanceThisFrame > diameter)  // the scale of the smallest axis
    14.     {
    15.         if(Physics.Raycast(transform.position, direction, hit, distanceThisFrame))  // we will hit something and the physics engine won't register the collision so ...
    16.         {
    17.             transform.position += direction*(hit.distance-diameter);
    18.         }
    19.     }
    20. }
    21.  
    22. function LateUpdate()
    23. {
    24.     // drawray to visualize raycast
    25.     Debug.DrawRay(transform.position, direction*distanceThisFrame, Color.black);
    26. }
    27.      
    28.  
    29.  
     
  25. MitchStan

    MitchStan

    Joined:
    Feb 26, 2007
    Posts:
    568
    For the sake of completeness and sharing, here is the newest, latest, final code. Attach this to a small projectile traveling at high speed to ensure that it will not pass through any objects without colliding.

    I figured out how to use the collider. bounds.extents in combination with the rigidbody velocity to register a hit so that the physics engine can do the real work and you don't have to hard code any numerical values into the script.

    It should be plug and play.

    I had to make some tweaks to the physics settings in the project settings:

    Min Penetration For Penalty: 1e-10
    Solver Iteration Count: 50
    Max Angular Velocity: 50
    Bounce Threshold: 1 (works well for a hockey puck!)

    Also, my puck GO is made up of 16 empty GO's with box colliders attached. You can see in the script how the colliders are gathered in an array and averaged. Using the value of just one collider didn't work. so I averaged the whole array.

    Here's the code - feel free to use or comment or improve. And thank you, Eric, for some fantastic input.

    Code (csharp):
    1.  
    2. private var puckColliders : Component[];
    3.  
    4. private var distanceThisFrame : float;
    5. private var direction : Vector3;
    6.  
    7. private var transformPosition : Vector3;
    8. private var puckHit : boolean;
    9.  
    10.  
    11.  
    12. function Start ()
    13. {
    14.     // collect all the colliders in an array
    15.     puckColliders = gameObject.GetComponentsInChildren (BoxCollider);
    16.  
    17.     // set puckHit flag to false
    18.     puckHit = false;
    19.  
    20.     // lower center of mass for puck
    21.     rigidbody.centerOfMass = -Vector3.up*.0125;
    22.    
    23. }
    24.  
    25.  
    26. function FixedUpdate()
    27. {
    28.     // get the extents of all box collider and get average - do this in fixedupdate since extents continually change value as puck tumbles
    29.     var puckExtents : Vector3;
    30.     for (var i=0; i<puckColliders.length; i++)
    31.         puckExtents += puckColliders[i].collider.bounds.extents;
    32.     puckExtents /= puckColliders.length;
    33.     // correct the puckExtents y  x value due to puck GO scale  collider GO scale
    34.     puckExtents.y /= 2;
    35.     puckExtents.x = puckExtents.z;
    36.  
    37.     // get the normalized vector of the velocity
    38.     direction = rigidbody.velocity.normalized;
    39.     // get the magnitude of the velocity per deltatime
    40.     distanceThisFrame = rigidbody.velocity.magnitude * Time.deltaTime;
    41.     // get the extents in the direction of travel
    42.     var puckExtentsByDirection = Vector3.Scale(puckExtents,direction);
    43.    
    44.     // test to see if the distance traveled this frame is more than the magnitude of the puck extents by direction
    45.     if (distanceThisFrame > puckExtentsByDirection.magnitude)  // if < let physics engine handle it
    46.     {
    47.         var hit : RaycastHit;
    48.         // test to see if the puck will strike something this frame
    49.         if (Physics.Raycast(transform.position, direction, hit, distanceThisFrame))
    50.         {
    51.             // place the puck at the hit point minus the puckExtents by direction -- but do it in function Update
    52.             transformPosition = hit.point - puckExtentsByDirection;
    53.             // set flag
    54.             puckHit = true;
    55.         }
    56.     }
    57. }
    58.  
    59. function Update()
    60. {
    61.     if (puckHit)
    62.     {
    63.         // manually place puck
    64.         transform.position = transformPosition;
    65.         // reset flag
    66.         puckHit = false;
    67.     }
    68. }
    69.  
    70. function LateUpdate()
    71. {
    72.     // drawray to visualize raycast
    73.     Debug.DrawRay(transform.position, direction*distanceThisFrame, Color.yellow);
    74. }
    75.      
    76.  
     
  26. Eric5h5

    Eric5h5

    Volunteer Moderator Moderator

    Joined:
    Jul 19, 2006
    Posts:
    32,401
    Very cool. The Min Penetration For Penalty seems really low and the Solver Iteration Count quite high, but if they work for your game, then who cares. :)

    It's called Hypersonic Hockey, and is not for the faint of heart or slow of reflexes. ;)

    --Eric
     
  27. MitchStan

    MitchStan

    Joined:
    Feb 26, 2007
    Posts:
    568
    For what it's worth, the code I posted has some problems with the puck squirting through the boards at certain rotations.

    This code works better, but I expect to find some issues sooner or later. I'm only posting in the hopes that this can be helpful to someone else at a later time.

    Sorry for all the posts:

    Code (csharp):
    1.  
    2. private var direction : Vector3;
    3. private var distanceThisFrame : float;
    4. private var puckColliders : Component[];
    5.  
    6. var power : float;
    7.  
    8. function Start ()
    9. {
    10.     // collect all the colliders in an array
    11.     puckColliders = gameObject.GetComponentsInChildren (BoxCollider);
    12.  
    13.     // set the inertiaTesor stuff
    14.     rigidbody.inertiaTensorRotation = Quaternion.Euler(Vector3(.038, .0125, .038));
    15.     rigidbody.centerOfMass = Vector3(0, -.0125, 0);
    16.  
    17.     rigidbody.AddRelativeForce(Vector3.forward*power);
    18. }
    19.  
    20.  
    21. function FixedUpdate()
    22. {
    23.     // get the extents of all box collider and get average - do this in fixedupdate since extents continually change value as puck tumbles
    24.     var puckExtents : Vector3;
    25.     for (var i=0; i<puckColliders.length; i++)
    26.         puckExtents += puckColliders[i].collider.bounds.extents;
    27.     puckExtents /= puckColliders.length;
    28.     // correct the puckExtents y  x value due to puck GO scale  collider GO scale
    29.     puckExtents.y /= 2;
    30.     puckExtents.x = puckExtents.z;
    31.        
    32.     // get the normalized vector of the velocity
    33.     direction = rigidbody.velocity.normalized;
    34.     // get the magnitude of the velocity per deltatime
    35.     distanceThisFrame = rigidbody.velocity.magnitude * Time.deltaTime;
    36.  
    37.    
    38.     // test to see if the distance traveled this frame is more than the magnitude of the puck extents by direction
    39.     if (distanceThisFrame > puckExtents.y)  // if < let physics engine handle it
    40.     {
    41.         var hit : RaycastHit;
    42.         // test to see if the puck will strike something this frame
    43.         if (Physics.Raycast(transform.position, direction, hit, distanceThisFrame))
    44.         {
    45.             print (hit.transform.name);
    46.             transform.position = hit.point;
    47.                            
    48.             if (hit.transform.name == "ICE")
    49.                 transform.position.y += puckExtents.y;
    50.            
    51.             if (hit.transform.name == "SIDEBOARD+X")
    52.                 transform.position.x -= puckExtents.y;
    53.                
    54.             if (hit.transform.name == "SIDEBOARD-X")
    55.                 transform.position.x += puckExtents.y;
    56.                
    57.             if (hit.transform.name == "CORNERBOARD-X+Z")
    58.                 transform.position.x += puckExtents.y;
    59.  
    60.             if (hit.transform.name == "CORNERBOARD+X+Z")
    61.                 transform.position.z -= puckExtents.y;
    62.  
    63.             if (hit.transform.name == "CORNERBOARD+X-Z")
    64.                 transform.position.x -= puckExtents.y;
    65.  
    66.             if (hit.transform.name == "CORNERBOARD-X-Z")
    67.                 transform.position.x += puckExtents.y;
    68.         }
    69.     }
    70. }
    71.  
    72. function LateUpdate()
    73. {
    74.     // drawray to visualize raycast
    75.     Debug.DrawRay(transform.position, direction*distanceThisFrame, Color.yellow);
    76. }
    77.  
    78.  
     
  28. BrettFromLA

    BrettFromLA

    Joined:
    Jan 29, 2009
    Posts:
    244
    I just found this 3-year-old thread. Anyone know if physics collisions are improved in Unity 3.0?

    Great code, MitchStan. Unfortunately, it works for something small (like a hockey puck) hitting something big (like a wall) ... but it doesn't work for my situation: Pachinko.



    The raycast can easily miss the tiny pins that the ball is supposed to collide with. I was thinking of making an invisible cylinder trigger that sticks out in front of the speeding ball. Each FixedUpdate it could scale itself to stick out only as far as the ball will move in the next FixedUpdate. Then if OnTriggerEnter occurs, you know you've hit something -- even a narrow pin.

    Seems tricky to implement, though. Comments? Questions? Code?
     
  29. Epic

    Epic

    Joined:
    May 30, 2010
    Posts:
    76
    How about making everything bigger
     
  30. BrettFromLA

    BrettFromLA

    Joined:
    Jan 29, 2009
    Posts:
    244
    I'm pretty sure it's all relative: if the pegs are 10 times as big, and the ball is 10 times as big, but it's moving 10 times as fast, I bet it will still fly through them.

    EDIT: Hey, this is my 100th post on the Unity forum! Cool!
     
  31. Eric5h5

    Eric5h5

    Volunteer Moderator Moderator

    Joined:
    Jul 19, 2006
    Posts:
    32,401
    Relative or not, scaling things up does make the physics work better. Also, increase the physics framerate so stuff doesn't move as far each physics frame.

    --Eric
     
  32. Quietus2

    Quietus2

    Joined:
    Mar 28, 2008
    Posts:
    2,058
    ^ This. PhysX does not like tiny objects. You want to try and normalize everything according to Unity's default scale. This won't change in Unity 3.0.

    Make your pachinko ball 1m inside Unity and scale up gravity and other meshes accordingly. Bump up your physics iterations and frame rate a hefty amount.

    You will then have no problem colliding with your mesh collider pins. No need for any raycast code or other measures in this application.
     
  33. BrettFromLA

    BrettFromLA

    Joined:
    Jan 29, 2009
    Posts:
    244
    I'll have to scale up the pins and the thin walls too. I just did a test, and a 1m sphere can pass through a thinner "wall" (cube scaled to 0.2 x 3.5 x 3.5) if the sphere's velocity.magnitude is 130 and the cube is at 23-degree angle to it.

    I'll tell you how it goes.
     
  34. BrettFromLA

    BrettFromLA

    Joined:
    Jan 29, 2009
    Posts:
    244
    I created demo that shows some 2m diameter spheres, with rigidbodies attached, passing through cubes of various thicknesses up to 2m. Here's the link: www.createdbybrett.com/Unity_sphere_through_cube.html

    Other than the code that repositions the sphere and speeds it up during OnCollision (below), the only other code in the project is a GUI display.

    Code (csharp):
    1.  
    2. public var i_gui_top : int;
    3. public var fl_cube_thickness : float;
    4.  
    5. private var fl_velocity : float = 100;
    6. private var r_rect : Rect;
    7. private var v3_start : Vector3;
    8.  
    9. function Start() {
    10.     r_rect = Rect (290, i_gui_top, 200, 50);
    11.     v3_start = transform.position;
    12.     rigidbody.velocity = Vector3 (fl_velocity, 0, 0);
    13. }
    14.  
    15. function OnGUI() {
    16.     GUI.Label (r_rect, "cube thickness:  " + fl_cube_thickness + "\nspeed:  " + fl_velocity);
    17. }
    18.  
    19. function OnCollisionEnter () {
    20.     transform.position = v3_start;
    21.     fl_velocity ++;
    22.     rigidbody.velocity = Vector3 (fl_velocity, 0, 0);
    23. }
    24.  
    On my computer, the 0.1-thick cube blocks sphere speeds up to 126, the 1m-thick cube blocks speeds up to 193, and the 2m-thick cube blocks speeds up to 238. It very much appears to be a ratio of speed to object size! BTW, I left the framerate and physics iterations as default. I could boost them up as you suggest, but I bet the sphere would still pass through the cube, just at a higher speed.

    Don't get me wrong -- I love Unity. I've been using it 40 hours a week for the last 18 months. I'm just recently frustrated by collisions. Sounds like it's time to break out the raycasts!
     
  35. Quietus2

    Quietus2

    Joined:
    Mar 28, 2008
    Posts:
    2,058
    More than the scale, the physics settings are what will affect your objects passing through colliders at speed. If you double the values, you double the speed that it can handle.

    Changing the thickness of the colliders works the same way, but is obviously only applicable for border geometry.

    Your pachinko scene is very light. You have a single rigidbody. Therefore you can easily crank up the values to crazy levels and not notice.

    Scale is not going to effect anything other than the stability of the simulation. Model a ball at one inch and drop it on a mesh collider it wall tend to pass right through. Normalize the scale to unity's units and it will catch. That however is a different issue altogether than passing through colliders at high speed.



    I have a pinball game I'm working on. The pinball can move at a relative 90+ mph. It has no trouble colliding with the thinest of meshes such as wire lane dividers. They are quite similar to your pachinko pins.

    So we can make that bet. I'll win though!
     
  36. BrettFromLA

    BrettFromLA

    Joined:
    Jan 29, 2009
    Posts:
    244
    But MY bet was that if you cranked up the physics settings, the ball would still pass through the cube, just at a higher speed. You sure you wanna bet? :)

    (I'm just saying the physics collisions don't work 100% realistically. I mean, our world isn't like Ewan McGregor at the end of "The Men Who Stare at Goats".)

    So for your pinball machine, which also has only one rigidbody (probably), you just raised the physics settings? Cool that even those wire lane dividers trigger collisions!
     
  37. Quietus2

    Quietus2

    Joined:
    Mar 28, 2008
    Posts:
    2,058
    Heh you have a point there.


    Well there are a lot more than a single rigidbody. Flippers, gates and others. But still the scene is relatively light so there's a lot of CPU left over for physics.

    But yeah I used the same techniques that Eric mentioned. Everything scaled around my ball being 1 Unity unit. Crank up settings.

    You have to really consider what PhysX and rigidbody simulations are designed for. It's not bouncing a beta particle off a metal plate using those scales and masses. It's for a bunch of boxes toppling over each other. So if you want it to work well, use it as it was intended.

    If you wanted to bounce that beta particle of that plate using PhysX, you would need to make the particle 1 meter in size. Make sense?
     
  38. BrettFromLA

    BrettFromLA

    Joined:
    Jan 29, 2009
    Posts:
    244
    Sounds good. Thanks! (Though the 2m balls in my demo still passed through cubes. But I like the "use it as it was intended" concept.)

    I (and others, I'm sure) would love to see your pinball game when it's ready for a public unveiling!
     
  39. Quietus2

    Quietus2

    Joined:
    Mar 28, 2008
    Posts:
    2,058
    They will eventually, once they reach a velocity threshold where it passes by the collider in one physics iteration. But at least you have control now over when that occurs.

    I sure will. More than a physics exercise it's really just a testbed for me to develop my weak modo skills. Modeling, then using procedural textures and baking them, that sort of stuff.

    I'm a programmer, so I am naturally a bucket of fail at art. Just trying to rectify that.
     
  40. medsouz

    medsouz

    Joined:
    Jun 2, 2010
    Posts:
    259
    You guys are all doing it the complicated way. 8)


    Just scale up everything in the game so the puck is larger but still to scale. :wink:
     
  41. BrettFromLA

    BrettFromLA

    Joined:
    Jan 29, 2009
    Posts:
    244
  42. Eric5h5

    Eric5h5

    Volunteer Moderator Moderator

    Joined:
    Jul 19, 2006
    Posts:
    32,401
    As noted, that's not sufficient. Also, increasing the physics framerate isn't exactly complicated....

    --Eric