How to do it...

To make a character get up from being a ragdoll, follow these steps:

  1. Place your character in the scene.
  2. Make two copies of it and name the characters CharacterAnimatedCharacterSkinned, and CharacterRagdoll. We will use these names for better clarity.
  3. Make all characters stand in the exact same place in the scene.
  4. Select the CharacterRagdoll and follow the Creating a humanoid ragdoll with the ragdoll wizard recipe to make a character a working ragdoll. We are not going to use the HandleRagdoll.cs script this time, so you can stop after using the Ragdoll Wizard.
  5. Select CharacterRagdoll game object's rig and name it Ragdoll.
  6. Select the CharacterAnimated and expand its hierarchy.
  7. Remove all objects but the rig of the character. You cannot change the rig's name.
  8. Select the CharacterSkinned and expand its hierarchy.
  9. Rename the CharacterSkinned rig to SkinnedRig.
  10. Select the SkinnedRig and the skinned mesh (or meshes if you have more). Drag and drop them onto CharacterAnimated. A window warning about prefab connection loss may appear. Click on Continue. This will parent the SkinnedRig and the mesh skinned to it to the CharacterAnimated game object.
  11. Select CharacterRagdoll, grab the Ragdoll rig, and drop it onto the CharacterAnimated game object to parent it. Again click on Continue if the warning appears.
  12. You can delete the CharacterRagdoll and CharacterSkinned game objects.
  13. Create an Animator Controller or open an existing one.
  14. In this controller, create two Triggers: StandUpFaceUp and StandUpFaceDown.
  1. Create four transitions:
    • Any StateStandUpFaceDown with one condition: StandUpFaceDown Trigger. Has Exit Time should be set to false and Transition Duration set to 0.
    • Any StateStandUpFaceUp with one condition: StandUpFaceUp Trigger. Has Exit Time should be set to false and Transition Duration set to 0.
    • StandUpFaceDownIdle with no conditions: Has Exit Time should be set to true and Transition Duration set to around 0.2.
    • StandUpFaceUpIdle with no conditions: Has Exit Time should be set to true and Transition Duration set to around 0.2.
  2. Assign the controller to the character's Animator component.
  3. [Optional] You can find the ShowRig.cs script in the Shared Scripts folder. If you attach it three times to the CharacterAnimated game object, you may drag and drop its three rigs, one to each ShowRig script. You may also assign different colors for each rig. If you play the game, you will be able to see the three rigs working. In the following screenshot, the red rig is the ragdoll, the yellow one is the one that is animated (we cannot change its name, in our example it's called metarig), and the green one is the one our mesh is skinned to (it's not clearly visible because it's hidden inside the mesh).
Ragdoll rig (red), animated rig (yellow), and skinned rig (green)
  1. Create a new C# script and name it RagdollWeight.cs. This script contains several functions. First, in the void Init() function that is called from the Start() function, we set references to the bones of our three rigs to be able to blend between them later on. We also get the reference to the Rigidbody and Animator components attached to our character. Finally, we turn the ragdoll game object off:
      void Init() 
      { 
          rb = GetComponent<Rigidbody>(); 
          anim = GetComponent<Animator>(); 
     
          skinnedRigTransforms = 
          skinnedRig.GetComponentsInChildren<Transform>(); 
     
          ragdollTransforms = 
          ragdoll.GetComponentsInChildren<Transform>(); 
     
          animatedRigTransforms = 
          animatedRig.GetComponentsInChildren<Transform>(); 
     
          ragdoll.gameObject.SetActive(false); 
      } 
     
  1. In the voidEnableRagdoll() function, we first check whether our float blendFactor is not greater than 0.5 (that would mean we are still in the "ragdoll phase"). If it is less than 0.5, we set all ragdoll bones' positions and rotations to match the animatedRigTransforms (we match the pose of the ragdoll to the current character pose). Finally, we set the main Rigidbody component to kinematic and enable the ragdoll game object. We also set the blendFactor to 1, which means the ragdoll is fully enabled:
      void EnableRagdoll() 
      { 
          if(blendFactor > 0.5f) 
          { 
              return; 
          } 
          for (int i = 0; i < ragdollTransforms.Length; i++) 
          { 
              ragdollTransforms[i].localPosition = 
              animatedRigTransforms[i].localPosition; 
         
              ragdollTransforms[i].localRotation = 
              animatedRigTransforms[i].localRotation; 
          } 
          rb.isKinematic = true; 
          ragdoll.gameObject.SetActive(true); 
          ragdollOn = true; 
          blendFactor = 1f; 
      } 
  1. In the voidDisableRagdoll() function, we check if our character is lying face down or face up and play an appropriate standing up animation. After we trigger the animation, we start the IEnumeratorBlendFromRagdoll() coroutine to blend smoothly from the ragdoll rig to the animatedRig:
      void DisableRagdoll() 
      { 
          bool faceUp = Vector3.Dot( 
          faceDirectionHelper.forward, Vector3.up) > 0f; 
     
          if (faceUp) 
          { 
              anim.SetTrigger("StandUpFaceUp"); 
          } 
          else 
          { 
              anim.SetTrigger("StandUpFaceDown"); 
          } 
 
          StartCoroutine("BlendFromRagdoll"); 
      } 
  1. The IEnumerator BlendFromRagdoll() coroutine decreases the blendFactor in time and checks if it's still greater than 0. If it is less than or equal to 0, we set it to be exactly 0, enable the main Rigidbody component again, and disable the ragdoll:
      IEnumerator BlendFromRagdoll() 
      { 
          while (blendFactor > 0f) 
         { 
              blendFactor -= Time.deltaTime * blendSpeed; 
              yield return null; 
          } 
          blendFactor = 0f; 
          rb.isKinematic = false; 
          blendFactor = 0f; 
          ragdollOn = false; 
          ragdoll.gameObject.SetActive(false); 
      } 
 
  1. In the FixedUpdate() function, if the ragdoll is on, we move our character's Rigidbody to the position of the ragdoll's hips. We additionally check the ground position to make sure our main Rigidbody stands on the ground and doesn't levitate. We also rotate the Rigidbody so that the character looks in the hips -> head direction. We intentionally omit the Y component of the Vector3desiredLookVector to prevent our character's capsule from tilting. Moving our character's Rigidbody to the position of the ragdolls hips makes the blending from ragdoll to animation easier:
      void FixedUpdate() 
      { 
          if (!ragdollOn) 
          { 
              return; 
          } 
          desiredLookVector = head.position - hips.position; 
          desiredLookVector.y = 0f; 
          desiredLookVector = desiredLookVector.normalized; 
          lookVector = Vector3.Slerp(transform.forward, 
          desiredLookVector, Time.deltaTime); 
 
          if (Physics.Raycast(hips.position, Vector3.down, 
          out groundHit, groundCheckDistance, 
          groundCheckMask)) 
          { 
              finalPosition = groundHit.point; 
          } 
          else 
          { 
              finalPosition = hips.position; 
          } 
          rb.MovePosition(finalPosition); 
          rb.MoveRotation(Quaternion.LookRotation(lookVector 
          ));          
      } 
  1. In the Update() function, we check whether the player pressed the space bar. If so, we enable or disable the ragdoll depending on whether it is enabled or disabled at the moment:
      void Update() 
      { 
          if (Input.GetKeyDown(KeyCode.Space)) 
          { 
              if (ragdollOn) 
              { 
                  DisableRagdoll(); 
              } 
              else 
              { 
                  EnableRagdoll(); 
              } 
         } 
      } 
  1. In the LateUpdate() function, we constantly interpolate the localPosition and localRotation of all the bones of the skinnedRig (the one our character's mesh is using). The position and rotation of the bones is interpolated between the position and rotation of the ragdoll and the animatedRig. We use the blendFactor variable for the interpolation:
      void LateUpdate() 
      { 
          for (int i=0; i<skinnedRigTransforms.Length; i++) 
          { 
              skinnedRigTransforms[i].localPosition = 
              Vector3.Lerp( 
              animatedRigTransforms[i].localPosition,                   ragdollTransforms[i].localPosition, 
              blendFactor); 
 
              skinnedRigTransforms[i].localRotation = 
              Quaternion.Lerp( 
              animatedRigTransforms[i].localRotation, 
              ragdollTransforms[i].localRotation, 
              blendFactor); 
          } 
      } 
  1. Add the preceding script to the character.
  2. Drag and drop the animated rig (in our example it's called metarig) to the Animated Rig field, the Ragdoll to the Ragdoll field, and the SkinnedRig to the Skinned Rig field. Choose the chest bone as the Face Direction Helper (if it doesn't work, you may create an empty object parented to the chest bonethe goal here is to have the forward axis of this helper object point down when the character lays face down, and up when it lays face up). Set the Ground Check Mask to contain your level layers. Assign the hips bone to the Hips field and the head bone to the Head field (you may choose different bones that properly describe your character's rotation when the ragdoll is on).
  3. Play the game and press the space bar to see the effect.
..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.21.248.162