4
\$\begingroup\$

My object must explode when the player touches it or when it collides at a low speed.

The problem I'm having is that its speed becomes zero when the floor collides for example and then the OnCollisionEnter event is called, it is already late and never fulfills the condition.

Someone knows what I'm doing wrong or what I should do to fix this?

void OnCollisionEnter(Collision other)
{
    Debug.Log(Mathf.Abs(rb.velocity.magnitude));
    if (Mathf.Abs(rb.velocity.magnitude) >= detonationImpactVelocity)
        Explosion(200);

    if (other.gameObject.tag == "Player")
        Explosion (600);

}

I came up with this but I guess there must be a better way to do it.

void Update()
{
    if (Mathf.Abs(rb.velocity.magnitude) >= detonationImpactVelocity)
        explosionSpeedAchieved = true;
    else
        explosionSpeedAchieved = false;
    Debug.Log(Mathf.Abs(rb.velocity.magnitude));
}

void OnCollisionEnter(Collision other)
{
    Debug.Log(Mathf.Abs(rb.velocity.magnitude));
    if (explosionSpeedAchieved)
        Explosion(200);

    if (other.gameObject.tag == "Player")
        Explosion (600);

}
\$\endgroup\$
1
  • \$\begingroup\$ Note that you don't need to wrap magnitudes in an absolute value function - they're non-negative by definition. \$\endgroup\$
    – DMGregory
    Nov 14, 2017 at 3:44

2 Answers 2

8
\$\begingroup\$

Check instead the collision's relative velocity:

void OnCollisionEnter(Collision collision)
{
    Debug.Log(collision.relativeVelocity.magnitude);
    if (collision.relativeVelocity.magnitude >= detonationImpactVelocity)
        Explosion(200);

    if (collision.gameObject.CompareTag("Player"))
        Explosion (600);
}

On a side note, it would be more efficient to check the sqrMagnitude against the square of detonationImpactVelocity to avoid an unnecessary sqrt calculation.

\$\endgroup\$
2
  • \$\begingroup\$ "On a side note, it would be more efficient to check the sqrMagnitude against the square of detonationImpactVelocity to avoid an unnecessary sqrt calculation." I do not understand the idea well \$\endgroup\$
    – NorbyAriel
    Nov 13, 2017 at 20:14
  • 5
    \$\begingroup\$ For example: if (collision.relativeVelocity.sqrMagnitude >= detonationImpactVelocity * detonationImpactVelocity) or possibly if (collision.relativeVelocity.sqrMagnitude >= sqrDetonationImpactVelocity) if you precalculate sqrDetonationImpactVelocity in Start. This is because calculating collision.relativeVeolocity.sqrMagnitude is simpler (and faster) for the computer to do than calculating collision.relativeVelocity.magnitude. \$\endgroup\$
    – Ed Marty
    Nov 13, 2017 at 20:25
3
\$\begingroup\$

You could try the relative linear velocity from the Collision object itself:

if (Mathf.Abs(other.relativeVelocity.magnitude) >= detonationImpactVelocity)

See also: https://docs.unity3d.com/ScriptReference/Collision-relativeVelocity.html

\$\endgroup\$
1
  • \$\begingroup\$ Aww, you just beat me to it \$\endgroup\$
    – Ed Marty
    Nov 13, 2017 at 19:50

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .