Tracking Force Added to Kinematic Rigidbody

Hello! =)

Short form: Is there anywhere I can see how much force has been added to a kinematic rigidbody over the course of the current frame?

Alternatively:
Is there a way to catch or hook into AddForce() method invocations, so that whenever [some script] calls AddForce() on a particular rigidbody, I can execute some code that does something with the parameters of the call?

Long version:
Ok, so what I’m attempting to achieve here is to ‘ragdoll’ a character when the force applied to it exceeds a threshold.

The (Non-humanoid) character consists of a regular Unity character controller and a collection of Kinematic rigidbodies, that are used as hitboxes for it’s body and limbs.

I ragdoll the character using a script which deactivates the character controller and animator and sets the rigidbodies to non-kinematic. This works well enough, physics takes over and the character falls over as per the joints configured for the rigidbodies.

My problem lies in triggering the ragdoll state. I want the character to ragdoll upon losing it’s balance. My approach is to add together the forces being applied to the character into an ‘imbalance’ vector, and if this vector’s magnitude exceeds a threshold, the character is ragdolled and it falls over.

This is fine for collisions with physics controlled rigidbodies; I can simply calculate the force of the impact in OnCollisionEnter and add it to the running total, but I can’t find any similar solution to forces caused by non-collisions.

This means that wind effects, explosions, or any force applied by a script don’t contribute to triggering the ragdoll.

The only workable solution I can see at the moment is to modify every script I use that applies forces and add a check for the ragdoll’able character and apply the imbalance directly. This isn’t ideal, it’d clutter up those scripts and introduce difficult to detect bugs where I forget a particular call, or don’t account for the Forcemode by accident.

Where should I go from here? Is the ugly way my only option? Is there a better, smarter design that doesn’t have this issue?

Thought I’d throw this in the answer section in-case you decide it works for you too.

private Vector3 impactVelocity;

private bool doImpact;

private void OnCollisionEnter(Collision col)
{
    if (this.GetComponent<Rigidbody>().isKinematic)
    {
        if (col.relativeVelocity.sqrMagnitude > 6)
       {
            impactVelocity = col.transform.GetComponent<Rigidbody>().velocity;
             
            doImpact = true;
        }
    }
}

private void FixedUpdate()
{
    if (doImpact)
    {
        this.GetComponent<Rigidbody>().isKinematic = false;
        this.GetComponent<Rigidbody>().velocity = impactVelocity;

        doImpact = false;
    }
}

In my case, I’m using a ragdoll that has several rigidbodies that are set to isKinematic all attached to a parent. I need them all to switch at once so I suggest you use something like this to do that.

public void SetKinematic(bool newBool)
{
    Rigidbody[] rigidBodies = GetComponentsInChildren<Rigidbody>();

    foreach (Rigidbody rb in rigidBodies)
    {
        rb.isKinematic = newBool;
    }
}

Call this method like this:

SetKinematic(false);

or

SetKinematic(true);