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\$
  • \$\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 '17 at 3:44
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\$
  • \$\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 '17 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 '17 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\$
  • \$\begingroup\$ Aww, you just beat me to it \$\endgroup\$ – Ed Marty Nov 13 '17 at 19:50

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.