Analysis of an Explosion/Trigger Bug in Unity... Should I Report?
Asked Answered
A

0

1

I believe I have come across a bug in Unity. When using Rigidbody.AddExplosionForce() on a Rigidbody with an attached trigger Collider, the force that the object feels is affected by the size of the attached trigger, which seems unrealistic. I have tested this pretty thoroughly (see details below), but I thought I'd discuss it here before posting it to the official Issue Tracker, in case this is actually intended behavior.

SETUP

  • Empty scene with a Main Camera and Directional Light
  • Add a 3x3 Plane for the ground (GameObject > 3D Object > Plane)
  • Add a Cube (GameObject > 3D Object > Cube) at the origin. Attach a Rigidbody to it and keep all defaults, but set its constraints to "Freeze Position" along X and Z axes, and Freeze Rotation on all axes. Attach a SphereCollider and set its "Is Trigger" checkbox. This Cube will be the "target" of our explosions.
  • Add an empty GameObject at position (0, -2, 0). Attach the Exploder script (see code below). Set this Exploder's "Target" property to the Cube object, set Explosion Force to 2, and UpwardsModifier to 2. This object will be the "initiator" of our explosions.
  • We will vary the radius of the Cube's trigger SphereCollider, and the ExplosionRadius of the Exploder. Every time we initiate an explosion, we record the highest y-level obtained by the cube (logged to the Console by the Exploder script). For every trigger-explosion-radii setup, we record from 10 explosions. For consistency, only the first explosion from every run of the game should be recorded.
  • Our radii setups will be:
    1) Cube - 1, Exploder - 2
    2) Cube - 1, Exploder - 4
    3) Cube - 1, Exploder - 10
    4) Cube - 4, Exploder - 2
    5) Cube - 5, Exploder - 2
    6) Cube - 4, Exploder - 4
    7) Cube - 5, Exploder - 10
  • Below is a screenshot of this setup on my machine: Exploder scene setup

RESULTS

I ran the above setups on my machine, and my results are reported in the image below. The table gives the minimum, median, and maximum values of the max heights obtained for each setup, along with the first and second quartiles, range, and interquartile-range (IQR). The three charts below that are box-and-whisker plots. The left plot shows the effect of varying the explosion's radius on the Rigidbody cube's max height, the middle plot shows the effect of varying the trigger's radius, and the right plot shows the effect of changing how the explosion/trigger spheres overlap (discussed below).

Explosion Results Table Explosion Radius Chart Trigger Radius Chart Sphere Overlap Chart

DISCUSSION

The goal of the above setups was to demonstrate that, when using Rigidbody.AddExplosionForce() on a Rigidbody with an attached trigger Collider, the magnitude of the explosion force felt by the Rigidbody is directly proportional to the radius of that trigger. We would expect that a Rigidbody positioned x units away from an explosion will experience the same force, no matter the size of an attached trigger volume, but this does not appear to be the case.

The left plot above shows the affect on the Rigidbody's max height of varying the explosion's radius. These setups varied the explosion radius from 1 to 10 units, and the max height increased from a median of 1.12 to 11.02 units. Larger explosions clearly achieved greater heights, which is expected. Interestingly, the variation in max height also seems to increase with larger explosions, with the IQR increasing from 0.50 to 6.22 units.

The middle plot shows the affect on the max height of varying the radius of the trigger Collider attached to the Rigidbody. These heights should have been unaffected by the trigger's radius, because the explosion radius stayed the same. However, the height achieved by the Rigidbody increased dramatically when its trigger was made larger. The trigger radius was varied from 1 to 5 units, and the max height increased from a median of 1.12 to 78.71 units. This effect was even larger than for varying the explosion's radius! As in the left plot, increasing the trigger radius also seemed to increase variation in the cube's max height, raising the IQR from 0.50 to 20.66 units.

The right plot groups setups 1, 2, 4, and 6 according to the overlap of the explosion's sphere and the trigger's sphere, as beautifully illustrated below. In Setup 1, both spheres overlapped, but neither sphere overlapped the center of the other sphere. In Setup 2 (and 3), the explosion sphere overlapped the center of the cube. In Setup 4 (and 5), the cube's trigger sphere overlapped the center of the explosion. In setup 6 (and 7), both spheres overlapped the center of the other sphere. Clearly, the cube's max height increased when either sphere overlapped the center of the other sphere. This effect was greater when the trigger overlapped the center of the explosion (median of the max height increased from 1.12 to 15.93 units when the trigger overlapped, but only to 5.10 when the explosion overlapped). When both spheres overlapped the other sphere's center in Setup 6, the max height reached about the same level as for Setup 4 (median of 16.05 units) but variation was greater (IQR of 15.20 vs 7.25 units).

Explosion Trigger Overlaps

In summary, increasing the size of a trigger volume attached to a Rigidbody increases the effect on it by explosion forces. To me, this seems like non-physical, buggy, behavior. I have not tested the effects of using a trigger Collider other than a SphereCollider, however. Also, it is worth noting that the cube experienced a force even in Setup 1, when the explosion sphere did not overlap the cube's center. Disabling the cube's SphereCollider removed these explosion affects, as would be expected. Thus, adding a trigger to a Rigidbody can make it feel explosion forces that it wouldn't otherwise. This seems like very unrealistic behavior! It was also surprising to me how much variation I saw in the Rigidbody's max height under identical explosion conditions. I can only guess that Nvidia's PhysX engine (which Unity uses) adds some randomness to every physical interaction.

EXPLODER CODE

using UnityEngine;

public class Exploder : MonoBehaviour {
// HIDDEN FIELDS
private float _highY = 0f;
private bool _moving;

// INSPECTOR FIELDS
public Rigidbody Target;
public float ExplosionForce;
public float ExplosionRadius;
public float UpwardsModifier;

// EVENT HANDLERS
private void Update() {
    // Explode on click
    bool clicked = Input.GetMouseButton(0);
    if (clicked) {
        if (Target != null)
            Target.AddExplosionForce(ExplosionForce, transform.position, ExplosionRadius, UpwardsModifier, ForceMode.Impulse);
    }

    // Report the object's highest y-level
    if (Target.velocity.sqrMagnitude > 0) {
        _highY = Mathf.Max(_highY, Target.transform.position.y);
        _moving = true;
    }
    else if (_moving) {
        Debug.LogFormat("Highest Y: {0}", _highY);
        _highY = 0f;
        _moving = false;
    }
}
}

EDIT: Replaced all Physics.ApplyExplosionForce instances with Rigidbody.AddExplosionForce

Alternant answered 3/5, 2016 at 22:11 Comment(11)
"the force that the object feels is affected by the size of the attached [collider]" Of course it is. Consider the CG, Moment and so on.Hutchison
it is quite bizarre to add two collider components to the same item.Hutchison
My mistake, I meant to use Rigidbody.AddExplosionForce(). Edit has been made.Alternant
@JoeBlow I feel like having a trigger and a collider on the same object is not so uncommon. Would you recommend putting the trigger on a child object instead?Alternant
@JoeBlow I tried placing the SphereCollider from my setup on a child of the cube instead. Its radius still affected the explosion force that it felt (max height achieved). As per your earlier comment, I'm not sure I understand how this would affect the center of gravity on a sphere.Alternant
hi, the whole issue would appear to be that you seem to repeatedly refer to a "trigger". A trigger is just a collider. I suggest you go through and change each word "trigger" to "collider". note that OF COURSE, OBVIOUSLY if you vary the size of a collider, obviously it changes the way an object bounces, etc.Hutchison
@JoeBlow I have always thought of Colliders with "IsTrigger" checked as separate entities from unchecked Colliders. That's why I used the word "trigger." I thought that trigger Colliders were only for detecting enter/exits, but would not affect the physics of an attached Rigidbody. That's why I had two Colliders on the same object: one for actual physical colliding, and one for detecting when other objects are nearby.Alternant
It just seems wholly bizarre to try to have two colliders on the one component, and the idea of having a trigger and collider on the same component is wildly bizarre. if you phoned PhysX and asked they would probably say "man that is bizarre; behaviour is undefined". it makes complete sense to me that both colliders would of course affect the body motion as colliders. consider ... answers.unity3d.com/answers/383599/view.htmlHutchison
Joe is correct. Create two new GameObjects and attach the colliders to each one. Make the parent of both to be Cube. Don't use two colliders on 1 gameobject.Nunnally
Well this is all good to hear for me. I've been using the 1 collider + 1 trigger-collider on the same object pattern all over the place in my games. What's odd is that using Rigidbody.AddForce() on such objects has been working as expected so far (i.e. unaffected by trigger radius), only AddExplosionForce() has been weird. But I guess that's the nature of undefined behavior. I will try to avoid this pattern now.Alternant
So unfortunately, the explosion issue that was the subject of this post has not really been resolved. If one follows my above setup, but makes the SphereCollider (with IsTrigger checked) a child of the cube instead of attaching it to the cube, as suggested in the earlier comments, then one still gets insane explosion forces being applied to the Cube. This seems like illogical behavior to me, but even if it isn't, how can I get the force applied to the cube by Rigidbody.AddExplosionForce() to be the same, regardless of the size of a trigger collider in the GameObject's children?Alternant

© 2022 - 2024 — McMap. All rights reserved.