Allow cars to hit each other.

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

I’m making a multiplayer car/racing game, and I want it to detect when the cars hit each other and maybe make the other car get pushed back a little and play a sound?

:bust_in_silhouette: Reply From: DaddyMonster

Easily done. I assume you’re using a KinematicBody2D? If you use the physics engine it’ll pass a collision object to you. To do this, use the _physics_process(delta) method (not _process(delta)) with move_and_slide() - that slides by default but you can add your own behaviour.

Something like this:

func _physics_process(delta):
    velocity = move_and_slide(velocity*delta)
    if get_slide_count():
        var collision = get_slide_collision(0)
        print(collision.collider.name) 
        velocity = -velocity #just a simple example

Check the docs for what info the collider obj can give you. The collider.normal is probably the most helpful thing - that’s the vector perpendicular to what you just hit.

There’s also move_and_collide() that has different inbuilt behaviour. Personally I don’t like it as much but your mileage my vary.

Actually, I am doing 3D, and I am using a VehicleBody node for the cars :slight_smile:

SF123 | 2022-05-18 23:38

Ah, the 3d doesn’t change anything but the VehicleBody does as it inherits from RigidBody. You need to make sure that contact_monitor is enabled, set contacts_reported to a positive int and use the body_entered signal. You need to add motion with forces / impulses instead of directly moving the car

DaddyMonster | 2022-05-18 23:52

Here’s my code:

steering = lerp(steering, Input.get_axis("right", "left") * 0.4, 5 * delta)
#steering = Input.get_axis("right", "left") * 0.4
#engine_force = Input.get_axis("forward", "backward") * 100
var acceleration = Input.get_axis("forward", "backward")
var rpm = $back_left_wheel.get_rpm()
$back_left_wheel.engine_force = acceleration * max_torque * (1 - rpm / max_rpm)
rpm = $back_right_wheel.get_rpm()
$back_right_wheel.engine_force = acceleration * max_torque * (1 - rpm / max_rpm)

I set the contact monitor to true and the contacts_reported to a positive integer, is there any way you could give me an example of what to do?

SF123 | 2022-05-19 00:09

Are you picking up the collision? Select the VehicleBody node, on the right go to the “Node” tab. Double click on “body_entered(body: Node)”, select your VB script. That gets you this:

func _on_car_body_entered(body):
    apply_central_impulse(Vector3.UP * 10000)
    printt("Weeeeeeeeeeeee! I hit ", body.name)

Obviously just add whatever linear algebra you need to get the behaviour you’re after.

If you want to do something more advanced you can use _integrate_forces(state). I used it for an amphibious craft so you can newtonian gravity / buoyancy / thrust from the rotating outboard motor etc. Unfortunately there’s no visualisation in the editor so this is advanced. You probably just want a simple impulse.

DaddyMonster | 2022-05-19 11:29

:bust_in_silhouette: Reply From: Mohammad Kashif

what and idea bro well done you will definetly be success