Ragdoll Disabler

Woods

New member
Made a script that boosts performance if you want ragdoll deaths on characters but dont need to interact with after death. Add it to your character, assign the Character and Ragdoll Rig. Once the ragdoll stops moving, it gets disabled until respawn. Works pretty well for AI characters you want to ragdoll and then stay in place on the ground.
C#:
using Opsive.Shared.Events;
using Opsive.Shared.StateSystem;
using System.Collections;
using UnityEngine;

public class RagdollDisableMonitor : StateBehavior
{
    [SerializeField]
    private GameObject m_Character;
    [SerializeField]
    private GameObject m_RagdollRigParent;

    private Rigidbody[] rbs;
    private bool waitToDisable;
    protected override void Awake()
    {
        base.Awake();
      
        if (m_Character)
        {
            EventHandler.RegisterEvent<Vector3, Vector3, GameObject>(m_Character, "OnDeath", OnDeath);
            EventHandler.RegisterEvent(m_Character, "OnRespawn", OnRespawn);
        }
        if (m_RagdollRigParent)
        {
            rbs = m_RagdollRigParent.GetComponentsInChildren<Rigidbody>();
        }
    }
    private void OnDestroy()
    {
        if (m_Character)
        {
            EventHandler.UnregisterEvent<Vector3, Vector3, GameObject>(m_Character, "OnDeath", OnDeath);
            EventHandler.UnregisterEvent(m_Character, "OnRespawn", OnRespawn);
        }
    }
    private void OnDeath(Vector3 arg1, Vector3 arg2, GameObject arg3)
    {
        //Start a timer to disable the ragdoll
        if(rbs == null || rbs.Length <= 0)
        {
            Debug.LogError("RagdollDisableMonitor: the RagdollRigParent does not have any rigidbodies");
            return;
        }
        StartCoroutine(WaitToCheckDisabled());
    }

    private IEnumerator WaitToCheckDisabled()
    {
        //Wait a frame before checking to ensure any impact was applied to the rigidbody
        yield return null;
        waitToDisable = true;
    }

    private void OnRespawn()
    {
        StopAllCoroutines();
        waitToDisable = false;
        //Reset the ragdoll
        SetRagdoll(true);
    }

    private void Update()
    {
        if (waitToDisable)
        {
            var notMovingCount = 0;
            foreach (var rb in rbs)
            {
                if(rb.velocity.magnitude < 0.01f)
                {
                    notMovingCount++;
                }
            }
            if(notMovingCount == rbs.Length)
            {
                SetRagdoll(false);
                waitToDisable = false;
            }
        }
    }

    private void SetRagdoll(bool active)
    {
        if (m_RagdollRigParent)
        {
            m_RagdollRigParent.SetActive(active);
            foreach (var rb in rbs)
            {
                rb.velocity = Vector3.zero;
                rb.angularVelocity = Vector3.zero;
            }
        }
    }
}
 
Last edited:
Top