Update 17 May 2014: If you're interested in physics simulation and character animation, check also our latest research. Also, please note that Mecanim has had some changes since the original post, and now the script could be implemented more elegantly. I also haven't tested the script with different characters - the comments suggest that some characters with different bone structure might not work out of the box.
Sharing a Unity project with a RagdollHelper.cs script that can be used to turn a Mecanim character into a ragdoll and then back. Using the script is simple: there's just one public property called "ragdolled", which can be set to true or false. When the property is changed from true to false, the script blends from the ragdolled pose to a get up animation. This is illustrated in the video below.
Transitioning from Mecanim animation to a ragdoll is as easy as disabling the Animator component of the character and setting all ragdoll rigid bodies to non-kinematic. The reverse is more complex, and my solution is not without kludges, as Mecanim doesn't allow as low level control of the animation as Unity's older animation system. The main problems are that one can't use scripting to enforce an immediate state transition without a blend, and apparently one can't also add states programmatically into an animation controller.
In the old animation system, one could create a new animation clip from the ragdoll's current pose, turn of ragdolling and blend the animation from the created clip to a recovery animation. In Mecanim this is not possible, and after turning Mecanim back on, we have to manually lerp the hip position and slerp all body part rotations back towards the last ragdolled pose in LateUpdate() to achieve a smooth blending. Additionally, we have to wait some frames for Mecanim to transition to the get up animation while using LateUpdate() to move the pose back to the ragdolled one, and then read back the get up animation start body orientation and position, and update Mecanim character's root so that the animated orientation and position match the ragdolled one as well as possible. In the old system we could just update the character transforms with a single script command according to a specific frame of a given animation, and then read whatever info we need. Actually we could possibly use the legacy animation system for that, but then the script would need additional handles to the animation etc., so it seems there's no really simple and beautiful way. One could also perhaps use an editor script to precompute the info.
Here's the Unity project as a zip file in case someone finds it useful: https://drive.google.com/file/d/0B8lAtheEAvgmYUlqX1FjNm84cVU/view?usp=sharing&resourcekey=0-kVdY0_KU-BRQP9xZibN0Fw
Open the test scene, click with mouse on a body part to add an impact to the character, press space to make it get back up.
Update 5 Dec 2013: Today I noticed that Unity 4.3 has added the Animator.Update() which could be used to implement the ragdoll to animation blend more elegantly without the LateUpdate() trickery. I'll have to update this example when I have time.
This is very cool - thank you for posting this.....was looking for something exactly like this!!!!!
ReplyDeleteh
DeleteGreat work!, very useful, thanks for sharing!
ReplyDeleteI agree, this is great stuff. Thanks for providing it!
ReplyDeleteThis comment has been removed by the author.
ReplyDeleteHello. This is awesome!
ReplyDeleteI want to ask you, can you give me a reference to this model? I really want to use it since it looks pretty much like this one: http://www.characterink.com/2011/10/24/free-unity-character/
and I would like to use both of them in a game, but couldn't find the source of the warrior you are using.
Thanks!
The character is from mixamo.com.
ReplyDeletethanks alot
ReplyDeletevery good :)
Hello, this is great work! but if i use my own character, the most of the time it goes back to standing position the right way, But sometime it does not play the animation (standUpFromBack - StandUpFromBelly) end goes directly to the idle animation, kinda looks weird. Did you find a solution for this?
ReplyDeleteHi there! I seem to have the same problem as Kevin above. Any thoughts? 4/5 times it will work probably, but sometimes it goes right from ragdoll to idle and looks super weird. I've tried a million things and the only difference i can determine is the character model.
ReplyDeleteI was having the same issue. The problem is if you have any atomic transitions in your animator. If when your model was ragdolled it was in mid atomic transition then it wont allow it to change to the getup transition.
DeleteThe solution is to set all your transitions to atomic=false;
This is just what I needed will help my death animations on stairs and slops look more realistic .. Thank you.
ReplyDeleteCan not download, why?
ReplyDeleteMaybe because you right click?
DeleteThank you very much for this tutorial!
ReplyDeleteI just have one question: in your setup is it possible to add gravity to the character?
I have a ragdoll which I only want to use when dying. In the rest of the time I want my character to be affected by gravity while in idle or walking.
I've managed to achieve this with a RigidBody, but the character slides across collision even when in idle, with speed 0.
Any help is greatly appreciated!
Same problem did you find a fix ?
DeleteThis may be late but I fixed it by setting all colliders in bodyparts to false while animating and enable them when ragdolled.
DeleteThanks for posting the source for this. It was fun to play around with. Here's my results from a little bit of tinkering http://imgur.com/mURZztG
ReplyDeleteHi, is it possible for you to share how you made the ragdoll be affected by gravity? (I know it's been 2 years now)
DeleteThanks, very good work but maybe you give the explanation of the script you made and not the idea of your script, that will be much better. But anyway nice work. You are the guy
ReplyDeleteAwesome! Any updates?
ReplyDeleteHi malcolm,
Deletehave you make it worked for unity5??
mine is not getting up when I press spacebar.
it says nullPointRefrence
NullReferenceException: Object reference not set to an instance of an object
RagdollHelper.set_ragdolled
Loved it! And wow! It was in 2013. Man it works great, but i has one problem. When it is blending from ragdoll to mecanim, transforms that are child of a bone behave strange, their positions and rotations change =/
ReplyDeleteCan you help me with that? Thanks a lot for the script
William, I had the same issue as you: my character holds a sword, and falls to the ground still grasping it. But when he gets up (using any of both animations), the sword is out of his hand. It's still a child of the hand, but it is offset.
DeleteBy the way, Perrttu, your script is awesome! Congratulations! And thank you for sharing it!
I just would really like to know how to solve this small problem.
Lucky you, i found a solution just yesterday! Lets talk about the facts: this script recognizes every transform in the ragdoll as a bone, so you don't want your sword to be recognized as a bone. To fix that, you need to ignore all the transforms that are'nt a bone. This is what i did, i went to the Start function and made some changes:
DeleteI put a tag named "Bone" to every bone i wanted to do the transition, and this method checks if the transform has this tag, and then if it does, it adds this transform to the components.
_components = GetComponentsInChildren(typeof(Transform));
components = new Component[_components.Length];
for (int i = 0; i < _components.Length; i++)
{
if (_components[i].tag == "Bone")
{
components[i] = _components[i];
}
}
Sorry for my bad english, and i hope it helps you! :D
Great idea, Wilian!
DeleteI simplified your solution: instead of needing to tag all bones, I just put the condition of having a rigidbody (wich all ragdoll parts have). The Start function ended up like this:
void Start ()
{
//Set all RigidBodies to kinematic so that they can be controlled with Mecanim
//and there will be no glitches when transitioning to a ragdoll
setKinematic(true);
//Find all the transforms in the character, assuming that this script is attached to the root
Component[] components=GetComponentsInChildren(typeof(Transform));
//For each of the transforms, create a BodyPart instance and store the transform
foreach (Component c in components)
{
if (c.GetComponent () != null)
{
BodyPart bodyPart = new BodyPart ();
bodyPart.transform = c as Transform;
bodyParts.Add (bodyPart);
}
}
//Store the Animator component
anim=GetComponent();
}
Ops! There is the "Rigidbody" part missing after "if (c.GetComponent..."; I believe it is because of the Blogspot API.
DeleteWhen I apply script, my character is being kept in spot. Animations work but it just won't move. Why this happens ?
ReplyDeleteI really like what this does. I have one problem, and I'm hoping you can help me solve it.
ReplyDeleteWhen I add this script to my character, it works, but it makes the character MUCH heavier/harder than it should be. When I hit them with a car, the car is abruptly stopped like hitting a tree, then they topple over slowly.
My other characters with just a ragdoll flop over the car as they should. Could there be something in here that affects the mass, or force?
Love you man !
ReplyDeletelove
ReplyDeleteHey Y POSİTİN ALWAYS GO ZERO !!!! how fix that ?
ReplyDeletefind newRootPosition.y=0;
ReplyDeleteChange y to = -100 and it will snap to lowest ground level
hey guys, please help me,
ReplyDeleteI'm trying to use this project with unity 2018/2017 but the prefabs are all messed up and the scripts missing, please help :(
I am also getting this error did you fixed it?
DeleteI managed to fix this, pm me if you still need it
Delete@Bugek i need help in setting up the project in current version
DeleteBravo, man!!!It's still workable after tiny modifications in Unity version 2018.4.6f1.Thank you:)
ReplyDeletecan you please tell me how you modified this to work in the new unity? Thanks
DeleteThis comment has been removed by the author.
ReplyDeleteGreat article. I also reccomend https://typkota.wordpress.com/2020/04/17/cat-claw-survival-rozwiazania-na-ratunek/
ReplyDeleteA very awesome blog post. We are really grateful for your blog post. You will find a lot of approaches after visiting your post. z code system discount
ReplyDeleteanyone can help me get this working in unity 2019?
ReplyDeleteTo make it works good, I
ReplyDeletefind newRootPosition.y=0;
and just comment it(or delete)
and add capsule collider to character or/and navmashagent
than Y position is corrects
Deleteawesome, however when I import the project the warrior prefab is missing,
ReplyDelete