• Advertisement
  • Popular Tags

  • Popular Now

  • Advertisement
  • Similar Content

    • By MadeWithRealLemons
      Hello all, I'm pretty new to programming and game development but I'm currently studying computer science at FSU and am just working on a project on that side that I hope to put on my resume one day... Any and all advice would be welcome!  I made a quick, shitty, little dev vlog where I just spliced a few of the features I've added into a single video.
      Please leave a comment if you have any words of encouragement or advice!  
    • By abarnes
      Hello All!
      I am currently pursuing a degree in video game programming, so far I have completed an intro to programming course and object oriented programming course. Both were taught using C++ as the programming langauge which I know is very popular for game development, but in these classes we do not actually do any game development. I would like to start to build my skills with C++ for game development as that is a common required thing for a job and am looking for ways to do this. Any recommendations such as books to read or youtube videos to watch will be greatly appreciated!
    • By RoKabium Games
      While looking out for that pesky Terrator, our little alien is doing a bit of relaxed mining down on the new gas planet "Lelantos" this weekend.... 
      #gamedev #indiedev #madewithunity #screenshotsaturday
    • By vividgamer
      I have a native iOS game (objective c, XCode build) which I am considering to port to other platforms.
      Core gameplay is based on solely on geographical maps, and custom drawing over maps. It also has Core Data. This part is complete in development.
      What is not done yet is: monetization, gamification (leaderboards, challenges) and multiplayer functionality.
      As I think more about it, I am tempted to think if this is the right time to move to a cross platform tool such as Unity. But before dedicating time to port my 5 years side-project effort in Objective C, I really want to know if its worth it.
      - Does Unity support such plugins / assets that will fulfill all my above requirements?
      - Unity Personal seems to have only 20 concurrent users - is it too costly scaling if I decide for extending to web and android platforms?
      - What is the general workflow involved in publishing to iOS, Android, PC, and web platforms while using Unity? I mean to ask about various points of signing stuff, paying fees and getting certified.
      - How long will it really take to port my entire Objective C project into Unity? I am somewhat familiar with C# but I am finding it hard fidgeting with Unity IDE as lot of things are focused around FPS and 3D while my game is still 2d - not much action involved. I seem bit overwhelmed by the list of features I see there. All in all, I do not want to lose my momentum while still making sure its portable to everywhere.
      - Any assets I could use (for free to try basis in debug) that are relevant for my game?
      - Last but not the least, are there any costs that I need to be paying upfront to Unity, for using it (apart from their monthly subscription model)? I don't understand their costing for multiplayer in conjunction with their subscription fees - if someone could kindly elaborate.
      Thanks in advance for your time reading a newbie
    • By GytisDev
      me and few friends are developing simple city building game with unity for a school project, think something like Banished but much simpler. I was tasked to create the path-finding for the game so I mostly followed this tutorial series up to episode 5. Then we created simple working system for cutting trees. The problem is that the path-finding is working like 90% of the time, then it get stuck randomly then there's clearly a way to the objective (tree). I tried looking for some pattern when it happens but can't find anything. So basically I need any tips for how I should approach this problem.
      Use this image to visualize the problem.
  • Advertisement
  • Advertisement

C# Unity3D: How we optimized Ragdoll animation of death

Recommended Posts

How we optimized Ragdoll animation of death in Unity

Or how easily to turn Ragdoll into AnimationClip.


Hello everyone. We are a small indie game studio called  Drunken Monday.
We’ve made recently a game on Unity3d where you run on the arena, rotate around yourself with the huge axe and try to hit other players. Good smash - good kill.

To make the death looks more realistic we used usual ragdoll animation based on physics. And everything was good… in the beginning.

When the number of the characters and calculations started growing, the game began working slowly and lagging on the old phones. Disabling all physics calculation gave us 50-60 fps and absolute smoothness. But we didn't want to refuse the cool ragdoll deaths of the characters.
One of the solutions was to force the animators to build a pack of death animations. But we’ve got a great idea to record a few ragdoll deaths directly in Unity and then just show the desired animation? Deaths will turn out to be diverse, there will no need to occupy animators, and the most important - everything will be fast, beautiful and realistic.

What we get:



The animation clip in the Unity is presented by the AnimationClip class, which contains array of AnimationCurve. AnimationCurve defines the curve for the changes of one particular property of a particular object, for example, the localPosition.x. Values change in the timeline are described by a number of Keyframe structures.


The idea is simple: for the each property of the each character object we create an AnimationCurve and store the values of this property on the curve for the each frame. The generated AnimationClip is exported through  AssetDatabase.CreateAsset at the end.

Let's create the class AnimationRecorderItem to track the each character object. All properties of the monitored object will be described through the dictionary, where the keys are the name of the properties and the values are the animation curves.

Properties = new Dictionary<string, AnimationCurve> ();
Properties.Add ( "localPosition.x", new AnimationCurve () );
Properties.Add ( "localPosition.y", new AnimationCurve () );
Properties.Add ( "localPosition.z", new AnimationCurve () );
Properties.Add ( "localRotation.x", new AnimationCurve () );
Properties.Add ( "localRotation.y", new AnimationCurve () );
Properties.Add ( "localRotation.z", new AnimationCurve () );
Properties.Add ( "localRotation.w", new AnimationCurve () );
Properties.Add ( "localScale.x", new AnimationCurve () );
Properties.Add ( "localScale.y", new AnimationCurve () );
Properties.Add ( "localScale.z", new AnimationCurve () );

For the all object properties in the each frame will be set theirs current values:

Properties["localPosition.x"].AddKey (new Keyframe (time, _animObj.localPosition.x, 0.0f, 0.0f));
Properties["localPosition.y"].AddKey (new Keyframe (time, _animObj.localPosition.y, 0.0f, 0.0f));
Properties["localPosition.z"].AddKey (new Keyframe (time, _animObj.localPosition.z, 0.0f, 0.0f));
Properties["localRotation.x"].AddKey (new Keyframe (time, _animObj.localRotation.x, 0.0f, 0.0f));
Properties["localRotation.y"].AddKey (new Keyframe (time, _animObj.localRotation.y, 0.0f, 0.0f));
Properties["localRotation.z"].AddKey (new Keyframe (time, _animObj.localRotation.z, 0.0f, 0.0f));
Properties["localRotation.w"].AddKey (new Keyframe (time, _animObj.localRotation.w, 0.0f, 0.0f));
Properties["localScale.x"].AddKey (new Keyframe (time, _animObj.localScale.x, 0.0f, 0.0f));
Properties["localScale.y"].AddKey (new Keyframe (time, _animObj.localScale.y, 0.0f, 0.0f));
Properties["localScale.z"].AddKey (new Keyframe (time, _animObj.localScale.z, 0.0f, 0.0f));

But if you record all values for the each frame for the each property of the each object, the output file of the animation will turn out to be too large. Lets introduce the conditions for limiting the minimum changes in comparison with the previous frame. If the object has moved, increased and turned just a little bit, we will not record these changes.

Completed class: AnimationRecorderItem.cs

Also we have to create a manager class AnimationRecorder.

This script should be executed through the all children of the animated object and create an instance of AnimationRecorder for each of them.
And also immediately generate and remember relativePath under which it will be saved in AnimationClip.

According to the documentation,  relativePath is generated as follows:


Path to the game object this curve applies to. The relativePath is formatted similar to a pathname, e.g. "root/spine/leftArm". If relativePath is empty it refers to the game object the animation clip is attached to.

The code will look like:

private List<AnimationRecorderItem> _recorders;
void Start ()
    Configurate ();
void Configurate ()
    _recorders = new List<AnimationRecorderItem> ();
    var allTransforms = gameObject.GetComponentsInChildren< Transform > ();
    for ( int i = 0; i < allTransforms.Length; ++i )
        string path = CreateRelativePathForObject ( transform, allTransforms [ i ] );
        _recorders.Add( new AnimationRecorderItem ( path, allTransforms [ i ] ) );
private string CreateRelativePathForObject ( Transform root, Transform target )
    if ( target == root )
        return string.Empty;
    string name = target.name;
    Transform bufferTransform = target;
    while ( bufferTransform.parent != root )
        name = string.Format ( "{0}/{1}", bufferTransform.parent.name, name );
        bufferTransform = bufferTransform.parent;
    return name;


To calculate current animation time and record the properties values for the each frame:

private float _recordingTimer;
private bool _recording = false;
void Update ()
    if ( _recording )
        for ( int i = 0; i < _recorders.Count; ++i )
            _recorders [ i ].AddFrame ( _recordingTimer );
        _recordingTimer += Time.deltaTime;


But the  Update function is called quite often and recording the animation every frame is pretty redundant, so we limit the record. 30 fps should be enough for everyone. 
We will start recording by tapping on Spacebar.

private const float CAPTURING_INTERVAL = 1.0f / 30.0f;
private float _lastCapturedTime;
private float _recordingTimer;
private bool _recording = false;
void Update ()
    if ( Input.GetKeyDown ( KeyCode.Space ) && !_recording )
        StartRecording ();
    if ( _recording )
        if (_recordingTimer==0.0f||_recordingTimer-_lastCapturedTime>=CAPTURING_INTERVAL)
            for ( int i = 0; i < _recorders.Count; ++i )
                _recorders [ i ].AddFrame ( _recordingTimer );
            _lastCapturedTime = _recordingTimer;
        _recordingTimer += Time.deltaTime;
public void StartRecording ()
    Debug.Log ( "AnimationRecorder recording started" );
    _recording = true;

Let’s implement an animation export. We will create the AnimationClip instance and fill it with the collected values.

private void ExportAnimationClip ()
    AnimationClip clip = new AnimationClip ();
    for ( int i = 0; i < _recorders.Count; ++i )
        Dictionary<string,AnimationCurve> propertiles = _recorders [ i ].Properties;
        for ( int j = 0; j < propertiles.Count; ++j )
            string name = _recorders [ i ].PropertyName;
            string propery = propertiles.ElementAt ( j ).Key;
            var curve = propertiles.ElementAt ( j ).Value;
            clip.SetCurve ( name, typeof(Transform), propery, curve );
    clip.EnsureQuaternionContinuity ();
    string path = "Assets/" + gameObject.name + ".anim";
    AssetDatabase.CreateAsset ( clip, path );
    Debug.Log ( "AnimationRecorder saved to = " + path );

Completed class AnimationRecorder.cs

Finally, we will create the  AnimationRecorderRagdollHelper helper class, which function will stop the Animator on the animated object, turn on all collisions, give the object acceleration and start recording our animation. The end of the animation recording will be completed by ourselves. 
To avoid some artifacts due to scene loading and the initialization of various objects, script will start working with the specified delay.

Completed class <b>AnimationRecorderRagdollHelper.cs
That's all, we add AnimationRecorderRagdollHelper on our character, set the impact force, then start the scene - and watch how the character cheerfully fly around the scene.
When the cold corpse freezes on the ground - press Spacebar. 



The script will exports our animation to the root of the project.






We recorded 4-5 animations for each character in this way and switch on them randomly at the character death.
P. S. Or not quite randomly.
Our game is multiplayer, physics is calculated on the server and the vector of impact comes to us. So we select the necessary animation based on vector which comes to us from the server, simply looking for the closest vector which the animation was recorded.
Project on a GitHub

" rel="external nofollow">A video of the game on YouTube with some deaths

Slash Arena: Online ( Facebook )

Slash Arena: Online ( Steam )


Edited by tatar1nro

Share this post

Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

  • Advertisement