Edit:
Inspired by @ExplodingRabbit I’ve now uploaded a video showing the experiments detailed below. The annotations can go by quite quickly, so pause it if you need to! 1
I’m experiencing difficulties with colliders. At first I thought this was the old “bullet through paper” issue, but after investigating further I no longer think so.
The behaviour I’m observing makes little sense to me. I’ve created a greatly simplified test scene to demonstrate the behaviour.
Background:
- a sphere with:
- sphere collider
- is trigger = FALSE
- a ‘bouncy’ physics material
- rigidbody
- use gravity = TRUE
- is kinematic = FALSE
- discrete (collision detection) *
- a cube collider:
- is trigger = FALSE
- no rigidbody *
- a MonoBehaviour implementing the OnCollisionEnter method
- fixed timestep @ 0.02
- gravity @ -9.81
- The only other GameObjects in the scene are for diagnostics (e.g. GuiText for an updating velocity label)
- Unity Version: 3.5.2f2 (Windows 7 64 bit Ultimate)
* I have experimented with collision detection with no success. I get very strange behaviour from the sphere - I explain more later.
Notes:
- the sphere moves in Y and Z (think ball)
- the cube collider is static (think tennis net)
- the sphere approaches the cube predominantly in the Z axis and slightly in Y (due to gravity)
Intent:
When the sphere collides with the cube two things should happen:
- the cube collider should register the hit and fire an event
- the sphere should bounce off of the collider
Problem
The actual behaviour appears unpredictable. Sometimes the intended behaviour occurs, other times the sphere passes straight through the cube collider.
Originally I thought that:
- Unity was not registering the collision (bullet through paper),
- that the cube collider needed to be enlarged to detect the sphere collider and/or
- that the physics’ fixed timestep needed to be decreased (e.g. 0.02 → 0.01) or
- that I needed to use the new dynamic collision detection on the rigidbodies;
however, when the sphere passes through the cube, the cube collider’s OnCollisionEnter method is called. This suggests that Unity is registering the collision, but that the sphere is not being affected by it.
From reading the Q&A sites, the perceived wisdom is often to increase the depth of the collider(s); however, from my experiments this is not always valid. For example, in Test One below I begin with a configuration that causes the sphere to pass through the cube, then in Test Two I increase the speed of the sphere and decrease the depth of the collider and the result is the collision I would expect - the sphere bounces off of the cube.
The experiments that fail (i.e. those where the sphere passes through the cube) can be corrected by decreasing the physics’ fixed time step; however, this is a somewhat brute force approach that doesn’t explain to me:
- why the OnCollisionEnter method can be called but the sphere not react to the collision, i.e. it appears that the collision HAS been detected?
- why decreasing the size of the collider and increasing the speed of the sphere can result in a bounce?
- why moving the cube closer to the sphere emitter can affect the bounce/pass outcome (is it related to the angle of the collision)?
Further, I would prefer not to reduce the fixed time step if possible since I will be targetting mobile devices with reduced processing power.
An alternative would be to use the “DontGoThroughThings” script - however, this is remedial action for an unknown cause - at least unknown to me since the behaviour doesn’t comply with the normal remarks re colliders.
Any advice would be greatly appreciated. Does anyone from Unity have any thoughts?
Notes on the Experiments & Test Scene:
I have included a test scene.
The scene consists of a sphere emitted at a given velocity and at a given frequency, aimed at a cube.
The sphere should bounce off of the cube.
If the cube’s OnCollisionEnter method is called, a visual indicator shows this on the screen.
In the scene there is a GameObject named _Main in the Hierarchy.
_Main allows the following to be tweaked:
- Sphere Period: the time in seconds between spheres
- Velocity: the velocity applied to the sphere when emitted
- Position: the position of the sphere when emitted
- There then follows a series of check boxes that, when checked, will reproduce the tests below.
- Only check one box at a time
- Checking a box will override the Velocity and Position settings above - uncheck all boxes to use the V&P controls
Experiments:
Test One:
- cube collider Z scale @ 0.2
- sphere Z velocity @ 10
- sphere is 4 units from the cube in Z (1 in Y)
- sphere passes through the cube
- OnCollisionEnter IS called
Test Two: Shrinking the cube collider whilst speeding up the sphere results in the sphere bouncing off of the cube.
- reduce the Z scale of the cube collider from 0.2 to 0.01
- increase the Z velocity of the sphere from 10 to 11.7
- the sphere now bounces off of the cube!
- OnCollisionEnter is called
Test Three: Increasing the speed of the sphere further results in the sphere passing through the cube.
- increase the Z velocity of the sphere from 11.7 to 11.8
- the sphere now passes through the cube
- OnCollisionEnter is called
Test Four: The slight speed increase to 11.8 allows the cube to be enlarged from 0.01 to 0.34 and still the sphere passes through the cube
- increase the Z scale of the cube collider from 0.1 to 0.34
- the Z velocity of the sphere should be 11.8
- the sphere now passes through the cube
- OnCollisionEnter is called
Test Five: At a depth of 0.35, the cube collider will now deflect the incoming sphere
- increase the Z scale of the cube collider from 0.34 to 0.35
- the Z velocity of the sphere should be 11.8
- the sphere now bounces off of the cube
- OnCollisionEnter is called
Translating the cube in Z so that it is closer to the sphere emitter affects the result
Test Six: A slim cube results in a fast sphere passing through it
- cube collider Z scale @ 0.01
- sphere velocity @ 20
- cube Z position @ 0
- sphere is emitted @ Z position -4.5
- the sphere now passes through the cube
- OnCollisionEnter is called
Test Seven: A slim cube moved closer to the sphere emitter results in a fast sphere bouncing off of it
- cube collider Z scale @ 0.01
- sphere velocity @ 20
- cube Z position @ -1.55 (cube is now closer to the sphere emitter)
- sphere is emitted @ Z position -4.5
- the sphere now bounces off of the cube
- OnCollisionEnter is called
And just to confuse things further:
Test Eight: A slim cube and a very fast sphere results in bounce
- cube collider Z scale @ 0.01
- sphere velocity @ 40
- cube Z position @ 0
- sphere is emitted @ Z position -4.5
- the sphere now bounces off of the cube
- OnCollisionEnter is called
So far, the cube’s OnCollisionEnter method has been called, regardless of bounce or pass through, but:
Test Nine: A slim cube and a slower sphere can result in pass through AND NO OnCollisionEnter method call
- cube collider Z scale @ 0.01
- sphere velocity @ 10
- cube Z position @ -1.31 (cube is now closer to the sphere emitter)
- sphere is emitted @ Z position -4.5
- the sphere now passes through the cube
- OnCollisionEnter is NOT called
Rigidbody & Collision Detection
I have read that to overcome “bullet through paper” problems:
- the sphere should have a rigidbody with Continuous Dynamic collision detection
- the cube should have a rigidbody with Continuous collision detection, and Is Kinematic = true (since it is stationary)
Setting these values in the test scene results in (seemingly) crazy behaviour. For example with Test Two: (2)
- the sphere (generally) passes through the cube
- the sphere springs back towards the cube
- the sphere then seems to roll around on the vertical face of the cube, defying gravity
- the sphere never bounces off of the cube
- the velocity of the sphere goes crazy:
- X is affected (we never apply force to X)
- Y increases and decreases
- Z increases and decreases
I really hope that such obscure behaviour is a result of me having an incorrectly configured Unity environment/scene, otherwise this is quite worrying!
Thanks for any help,
James