Health.cs, colliders in children don't receive force on damage

Sergey Bespalov

New member
Hello. I have written about this problem in other question, but that question was not only about this problem so I wanted to create more specific topic.

Main problem - If an object has the script "Health.cs" then colliders in children objects don't receive force from impact with bullets.
Only root object with Health.cs receives force. I can't use PuppetMaster to animate enemies because of it - body parts of a ragdoll don't receive force. (PuppetMaster)

Test:
1. There is a "White Crate" that is a parent of a game object "Health":
1542613217024.png
2. If I add "Health.cs" to "White Crate" then the crate will receive force.
3. But I add "Health.cs" to "Health" then the crate won't receive force.

Video:

Maybe is there other way to detect damage?
More about ragdoll: The root of rig has Health.cs, I shoot in head, body(root) receives force.
 
Health shouldn't affect the force at all - can you slowly remove pieces of the health script to see what is causing the problem?
 
Health shouldn't affect the force at all - can you slowly remove pieces of the health script to see what is causing the problem?

But Health.cs is applying force to the object in onDamage(...) method:


C#:
...
            var force = direction * forceMagnitude;
            if (forceMagnitude > 0) {
                // Apply a force to the object.
                if (m_ForceObject != null) {
                    m_ForceObject.AddForce(force, frames);
                } else {
                    // Apply a force to the rigidbody if the object isn't a character.
                    if (m_Rigidbody != null && !m_Rigidbody.isKinematic) {
                        if (radius == 0) {
                            m_Rigidbody.AddForceAtPosition(force * MathUtility.RigidbodyForceMultiplier, position);
                        } else {
                            m_Rigidbody.AddExplosionForce(force.magnitude * MathUtility.RigidbodyForceMultiplier, position, radius);
                        }
                    }
                }
            }
...

If I comment this code there will be no force on any object that has Health.cs.
 
Ah, yeah, it does apply a force when it is damaged, but it doesn't modify the force at all. If you set a force value of Vector3.zero then no forces will be applied.
 
Ah, yeah, it does apply a force when it is damaged, but it doesn't modify the force at all. If you set a force value of Vector3.zero then no forces will be applied.

The problem is that it is applying force only to "root" object, and it does not apply force to object in children that was hit.

For example: there is a ragdoll. Root object with Health.cs is a chest. When I shoot in a hand then this script will apply force to the chest and the hand won't receive force at all.
 
I have found following code in ShootableWeapon.cs

C#:
                        // If the Health component exists it will apply a force to the rigidbody in addition to deducting the health. Otherwise just apply the force to the rigidbody.
                        Health hitHealth;
                        if ((hitHealth = hitGameObject.GetCachedParentComponent<Health>()) != null) {
                            hitHealth.Damage(damageAmount, m_HitscanRaycastHits[i].point, fireDirection, m_ImpactForce * strength, m_ImpactForceFrames, 0, m_Character, m_HitscanRaycastHits[i].collider);
                        } else if (m_ImpactForce > 0 && m_HitscanRaycastHits[i].rigidbody != null && !m_HitscanRaycastHits[i].rigidbody.isKinematic) {
                            m_HitscanRaycastHits[i].rigidbody.AddForceAtPosition(fireDirection * m_ImpactForce * strength * MathUtility.RigidbodyForceMultiplier, m_HitscanRaycastHits[i].point);
                        }

I see in this code that it is applying force to an object only if it does not have "Health" component in parents. And Health component is applying force only to the parent object (in code in post above); I can modify it for my purpose. But how should it work? Should "Health" apply force only to root object (even if root object was not hit)?
 
For me I have added an argument "Rigidbody hitBody" to the method Damage(...) in Health.cs and send m_HitscanRaycastHits.rigidbody to it.
Then applying force in Health.cs:
C#:
var force = direction * forceMagnitude;
            if (forceMagnitude > 0)
            {
                // Apply a force to the object.
                if (m_ForceObject != null)
                {
                    m_ForceObject.AddForce(force, frames);
                }
                else
                {
                    // Apply a force to the rigidbody if the object isn't a character.
                    if (hitBody != null && !hitBody.isKinematic && radius == 0)
                    {
                        hitBody.AddForceAtPosition(force * MathUtility.RigidbodyForceMultiplier, position);
                    }
                    else if (m_Rigidbody != null && !m_Rigidbody.isKinematic)
                    {
                        if (radius == 0)
                        {
                            m_Rigidbody.AddForceAtPosition(force * MathUtility.RigidbodyForceMultiplier, position);
                        }
                        else
                        {
                            m_Rigidbody.AddExplosionForce(force.magnitude * MathUtility.RigidbodyForceMultiplier, position, radius);
                        }
                    }
                }
            }
It works for me for now.
 
Last edited:
Top