So I have a player that moves to whatever position you touch on the screen and a box made of four walls keeping the player from leaving. I added a script to make enemies spawn and I gave the player the ability to spawn a small cannonball like object. This is where my issue comes in.
You see the idea is for the player to hit the balls into enemies and kill them, but if they lose momentum (they have a material with a bounciness of 0.5) they’ll get stuck on the wall and the player won’t be able to get the back.
I’ve tried using Mathf.Clamp and Layers to add a boundary before they hit the wall but then it doesn’t look as good and sort of ruins to immersion.
Is there any way for me to make sure they always bounce back from the wall and will never settle against it? Thanks!! Hopefully my question was clear enough!
Well, why do you use a bounciness of 0.5 in the first place if you don’t want them to loose momentum? Of course you need a bounciness of 1 in order to keep the momentum.
If, for some reason, you want the collisions between the enemies have a lower bounciness you can totally do that. Give your enemies a physics material with a bounciness of 0.5 and set bounceCombine on the enemies to Minimum. Give your wall colliders also a physics material but with a bounciness value of 1.0 and set bounceCombine to Maximum. The 4 different modes come with a priority hierarchy which is
Average < Minimum < Multiply < Maximum
That means if two materials with different combine values collide, the one with the greater priority will be used. Average (which is the default) has the lowest priority and Maximum has the highest.
For our case that means if two enemies collide they both have a combine value of Minimum. So the physics system will use the smaller bounciness value of the two colliding colliders. Since the enemies all have 0.5 that’s the value used. However if an enemy collides with a wall, the wall’s combine value (Maximum) has a higher priority and the maximum of the two bounciness values will be used. Since we set the wall to 1.0, that’s the value used for this collision.
Note that this just ensures that an enemy will always bounce off a wall at more or less the same speed it hit the wall. However if you have many objects bumping into each other it’s of course possible that other objects take away almost all of the momentum of one enemy and might push it close to a wall so it barely moves anymore. If you just want to ensure that the enemies kinetic energy does not drop below a certain minimum you might just want to check the velocity and keep it within a certain range. If you limit the lower bounds for the enemy speed you should also limit the upper bounds. This is because otherwise you could generate too much kinetic energy if many objects collide with each other.
// example values, might need to be adjusted
float minVelocity = 1.0f;
float maxVelocity = 20.0f;
// in FixedUpdate
var vel = rb.velocity;
float speed2 = vel.sqrMagnitude;
if (speed2 < minVelocity*minVelocity)
rb.velocity = vel * (minVelocity / Mathf.Sqrt(speed2));
else if (speed2 > maxVelocity*maxVelocity)
rb.velocity = vel * (maxVelocity / Mathf.Sqrt(speed2));