0
\$\begingroup\$

Setup

The game has cars and collisions, and I'm trying to create the following system:

  • When a car T-bones another, the one getting T-boned is destroyed;
  • When the cars collide laterally (usually just bump into each other), a normal physics collision happens (and nothing is destroyed);
  • When the cars collide head-on, the lighter one is destroyed.

The cars are all instantiated from 1 prefab. This can't be changed.

Car Setup

The main body sans the bumper has a normal, non-trigger collider and the dynamic Rigidbody. It has the tag "Destructible".

A child object (which also houses the bumper model, but that shouldn't matter) has a normal, non-trigger collider for the bumper. It has no Rigidbody and reports to the parent's Rigidbody. It has the tag "Destroyer".

Attempted Solutions

1) The transform.forward solution

Get the transform.forwards of both cars and compute their dot product.

  • If the 2 vectors are opposite each other (or close to it), destroy the lighter car.
  • If the vectors are facing away from each other (or are close to parallel), let a normal collision happen.
  • If the vectors are perpendicular (or somewhere in that ballpark)... then I'm lost. How do I know which car T-boned which?

That brings us to the solution #2.

2) The 'multiple colliders' solution

Assign another collider to the bumper of the car and give it a separate tag (e.g. "Destroyer). As a consequence, give the other — main — collider a tag, too (e.g. "Destructible").

  • If a Destroyer collider hits a Destructible, the latter is destroyed.
  • If a Destructible hits a Destructible, a normal physics collision happens.
  • If a Destroyer hits a Destroyer, destroy the lighter one.

But here, I run into an issue.

  1. You can't have multiple colliders on the same game object. Ergo, create an empty child and attach it there. I won't set it to Trigger, or otherwise it won't detect collisions with another of its type (i.e. Destroyer).
  2. In order to destroy colliding objects, I need a script and an OnCollisionEnter() inside it.
  3. OnCollisionEnter() won't run if neither of the game objects has a non-kinematic Rigidbody. This means I need to give the bumper colliders a non-kinematic Rigidbody.
  4. But if I give them dynamic Rigidbodies, they'll just... float away from the car.

In other words, I need a way to create a 2nd collider but keep it firmly attached to the car. Furthermore, if the main collider covers it, then I need to exempt it from collisions with the 2nd collider (let's call it the sub-collider), and I can't use layers to do that or otherwise the sub-collider won't detect main colliders on other cars.

If I don't cover it, then I need the sub-collider to act as a normal physics collider, too, when it hits, for example, a wall, and not have the bumper sink into it. That means it needs a non-kinematic Rigidbody.

How can I solve this issue?

\$\endgroup\$
  • \$\begingroup\$ Doesn't your car already have a non-kinematic rigidbody on it? Why would the bumper collider need its own? You can have multiple child colliders all reporting their collisions up to a single shared rigidbody. Or, if you're using trigger colliders and OnTriggerEnter, even kinematic bodies will fire that message. \$\endgroup\$ – DMGregory Sep 17 at 13:26
  • \$\begingroup\$ Hey, I didn't know that bit about child colliders reporting to the parent Rigidbody! However, OnCollisionEnter() does not fire at all now. \$\endgroup\$ – verified_tinker Sep 17 at 13:35
  • \$\begingroup\$ Because you used trigger colliders? They'll fire OnTriggerEnter instead. \$\endgroup\$ – DMGregory Sep 17 at 13:41
  • \$\begingroup\$ No, no. I'm using normal colliders. I can't use make the bumper colliders triggers, because although they'll detect normal colliders (the main, Destructible bodies), they won't detect other Destroyers. From Unity docs: "If both GameObjects have Collider.isTrigger enabled, no collision happens." Thus, head-on collisions won't work. \$\endgroup\$ – verified_tinker Sep 17 at 13:43
  • \$\begingroup\$ Sounds like you should edit your question to walk us through your current setup. I'm not sure from your description what's missing. \$\endgroup\$ – DMGregory Sep 17 at 13:45
1
\$\begingroup\$

If the vectors are perpendicular (or somewhere in that ballpark)... then I'm lost. How do I know which car T-boned which?

Shoot a ray from the center of mass of the vehicle through the front. If the ray hits the other car, it was the other car that was t-boned. If they ray doesn't hit something, reverse the roles of both cars, shoot again.

You might need more than one ray and shoot through the front left/front right edges of the car as well.

Physics.Raycast should work well for that.

| improve this answer | |
\$\endgroup\$
  • \$\begingroup\$ The contact points given by the Collision data structure should give you similar info as the raycast hit, without a separate query. Think you could use those instead? \$\endgroup\$ – DMGregory Sep 17 at 18:34
  • \$\begingroup\$ I've not finished yet, but I'm going for solution #3: BoxCast "stripes" right around the bumper. I'm keeping 2 colliders -- the main one for the body and a child one for the bumper -- and so, depending on which the BoxCasts hit, I know what happened. \$\endgroup\$ – verified_tinker Sep 17 at 20:54

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.