How do I apply different physics to different object collitions?

:information_source: Attention Topic was automatically imported from the old Question2Answer platform.
:bust_in_silhouette: Asked By nebneb

I have a simple ball game where kinematic body players interact with a rigidbody ball in an arena closed by a static body arena. I need to make it so that the ball bounces with no absorption off walls and with absorption when colliding with players. I found a workaround where I disable absorption when the ball is close to players, but of course this is not ideal and can have unexpected outcomes when players, balls, and walls are all near each other/colliding. Is there a solution for this?

:bust_in_silhouette: Reply From: ibrahim.semab

Yes, there is a solution for this. You can achieve this by setting the ball’s physics material to have different properties for collisions with players and collisions with walls.

First, create two physics materials, one for players and one for walls. Set the restitution (bounciness) to 1 for the wall material and to a lower value (e.g. 0.5) for the player material. You can also adjust the friction values to get the desired behavior.

Next, assign the appropriate material to each object. Assign the wall material to the arena’s static body and the player material to each player’s kinematic body. Finally, assign both materials to the ball’s rigidbody, and set the “custom” mode for the ball’s physics material override.

This will make the ball bounce with no absorption off walls and with absorption when colliding with players.

Here’s some sample code to get you started:

# create physics materials
var player_material = PhysicsMaterial.new()
player_material.restitution = 0.5
var wall_material = PhysicsMaterial.new()
wall_material.restitution = 1

# assign materials to objects
$Ball.physics_material_override = PhysicsMaterialOverride.new()
$Ball.physics_material_override.set_material(PhysicsMaterialOverride.MATERIAL_PLAY ER, player_material)
$Ball.physics_material_override.set_material(PhysicsMaterialOverride.MATERIAL_WAL L,wall_material)

for player in $Players.get_children():
    player.physics_material_override = player_material

 $Arena.physics_material_override = wall_material

This assumes that the players are children of a node named “Players”, the ball is a child of a node named “Ball”, and the arena is a child of a node named “Arena”. You may need to adjust the code to fit your specific scene structure.