Have Gameobject move with rigidbody/ragdoll

So, I have been staring at this too long and feel I may not know the right words to search for this as I have failed as of late lol.

I have added ragdoll to my main character. That appears to work from a model/visual standpoint, but after the ragdoll is turned off, the model moves back to the original position. I did some outputs and the rigidbody never changes position it seems. What I am trying to do is have the character flung to a location, have the camera follow, and when the ragdoll is disabled the player/camera is now at the new position. Any tips/help?

How I am triggering for testing…tried way too many things lol

if (Input.GetKeyDown(KeyCode.J))//temporary. To be removed when quest system is implemented.(right mouse button)
        {
            rBody.velocity = new Vector3(40f, 40f, 0f);
            //this.gameObject.GetComponent<Rigidbody>().velocity = new Vector3(0f, 40f, 0f);
          
            StartCoroutine(waitPlayer());
            EnableRagdoll(true);
            Rigidbody[] bones = GetComponentsInChildren<Rigidbody>();
            foreach (Rigidbody bone in bones)
            {
                //bone.AddForce(transform.up * 800);
                bone.AddForce(transform.forward * 1000);
            }
            StartCoroutine(enablePlayer());
            //rBody.AddTorque(Vector3.up * magnitude, ForceMode.Impulse);
            //rBody.AddForce(Vector3.up * magnitude, ForceMode.Impulse);
        }

The ragdoll code I found/use.

public void EnableRagdoll(bool enableRagdoll)
    {
        if (enableRagdoll)
        {
            Debug.Log("FLY LITTLE DOLL!");
            //rBody.AddForce(Vector3.up * 5, ForceMode.Impulse);
            //Rigidbody[] bones = GetComponentsInChildren<Rigidbody>();
            //foreach (Rigidbody bone in bones)
            //{
            //    bone.AddForce(transform.up * 800);
            //}
            //rBody.velocity = new Vector3(0f, 40f, 0f);//AddTorque(Vector3.up * 5, ForceMode.Impulse);
            //rBody.AddForce(Vector3.up * 5, ForceMode.Impulse);
            //this.gameObject.transform.position.Set(this.gameObject.transform.position.x, this.gameObject.transform.position.y + 20f, this.gameObject.transform.position.z);
        }
        anim.enabled = !enableRagdoll;
        foreach (Collider item in allCollider)
        {
            item.enabled = enableRagdoll; // enable all colliders  if ragdoll is set to enabled
        }

        foreach (var ragdollRigidBody in ragdollRigidBodies)
        {
            ragdollRigidBody.useGravity = enableRagdoll; // make rigidbody use gravity if ragdoll is active
            ragdollRigidBody.isKinematic = !enableRagdoll; // enable or disable kinematic accordig to enableRagdoll variable
        }

        foreach (Collider item in colliderToEnable)
        {
            item.enabled = !enableRagdoll; // flip the normal colliders active state
        }
      
        rBody.useGravity = !enableRagdoll; // normal rigidbody dont use gravity when ragdoll is active
        rBody.isKinematic = enableRagdoll;
        if(!enableRagdoll)
            this.transform.position.Set(rBody.position.x, rBody.position.y, rBody.position.z);
    }
1 Like

Hi, I have the same question. Did you ever found a solution on this?

I was able to get better results by setting the player position to one of the bones, like so:

transform.position = bones[1].position;

How it looks in my code.

IEnumerator enablePlayer()
    {
        yield return new WaitForSecondsRealtime(3);
        transform.position = bones[1].position;
        EnableRagdoll(false);
        enableLimp = false;
        bones = Array.Empty<Rigidbody>();
        if (variableManager.GetComponent<VariableManager>().EnergyLevel < 0.01f)
        {
            transform.position = GameObject.Find("/MySpawns/hospitalSpawn").transform.position;
            if (variableManager.GetComponent<VariableManager>().cash > 10.00)
                variableManager.GetComponent<VariableManager>().cash = variableManager.GetComponent<VariableManager>().cash - 10.00;
            else
                variableManager.GetComponent<VariableManager>().cash = 0.00;
        }
    }
variableManager.GetComponent<VariableManager>()

You should know that getting components is not free. Your code above does that 5 times. You should get it once and store it in a local variable.

Also, GameObject.Find isn’t a cheap call either and should be avoided in runtime code.

1 Like

Thanks for the knowledge gain. I know I have been sloppy coding my way through things. Maybe it’s a good time to revisit and clean some of the code.

1 Like