Fast moving ball ignores colliders.


I’m making a pinball game in unity. When the ball is at high speed it sometimes ignores the flipper colliders. Is there a better way then colliders to prevent my ball from going through?

Thanks for reading.

go into the rigidbody settings of the ball AND flippers and set collision detection from discrete to continuous dynamic for both.

As long as it runs smooth still leave it like that (that kind of collision detection that doesnt allow for the risk of something passing through the object by skipping past it in a frame is calculation intensive and it may cause your frame rates to drop)

If it does you need to add a little thickness to the flippers and there colliders so there a little bigger.

cap the speed of the ball to less meters per frame than say half the thickness of the flippers.

so lets say your flippers are 1 unit thick. You have 60 fps by default for physics. So you have 1/60th of a second distance you basically teleport each frame.

if you are 1 meter thick that means in 1/60th of a second it has to go less than half a meter.
scaled up thats 30 meters per second cause its .5 * 60.

you need to clamp your balls velocity (the flipper may be moving too and you may have to play around with this some to get consistent results, but that’ll give yuou a good starting point)

30 meters per second is around 70 miles per hour so thats a pretty quick moving pin ball.

try this script:

#pragma strict 
var layerMask : LayerMask; //make sure we aren't in this layer 
var skinWidth : float = 0.1; //probably doesn't need to be changed 
private var minimumExtent : float; 
private var partialExtent : float; 
private var sqrMinimumExtent : float; 
private var previousPosition : Vector3; 
private var myRigidbody : Rigidbody; 
//initialize values 
function Awake() { 
   myRigidbody = rigidbody; 
   previousPosition = myRigidbody.position; 
   minimumExtent = Mathf.Min(Mathf.Min(collider.bounds.extents.x, collider.bounds.extents.y), collider.bounds.extents.z); 
   partialExtent = minimumExtent*(1.0 - skinWidth); 
   sqrMinimumExtent = minimumExtent*minimumExtent; 
function FixedUpdate() { 
   //have we moved more than our minimum extent? 
   var movementThisStep : Vector3 = myRigidbody.position - previousPosition; 
   var movementSqrMagnitude : float = movementThisStep.sqrMagnitude;
   if (movementSqrMagnitude > sqrMinimumExtent) { 
      var movementMagnitude : float = Mathf.Sqrt(movementSqrMagnitude);
      var hitInfo : RaycastHit; 
      //check for obstructions we might have missed 
      if (Physics.Raycast(previousPosition, movementThisStep, hitInfo, movementMagnitude, layerMask.value)) 
         myRigidbody.position = hitInfo.point - (movementThisStep/movementMagnitude)*partialExtent; 
   previousPosition = myRigidbody.position;