Ragdoll Fish

Game Ready Unity Rig

Intro

Rigged in Maya and Unity for a student game project, this oarfish uses a combination of Unity Character Joints, Rigidbody physics, and C# scripts to create a ragdoll effect and fish-like motion with no keyed animations. This provides a fluid and adaptive system for any kind of movement the fish undergoes without the need for a set of predetermined animations.

Methods

There are lots of ways to do ragdoll physics in Unity and multiple people have been asking me about it recently, so here's a little more info on what's happening under the hood with this particular rig.

I referred to this article for the general setup and code to carry the motion through the tail. This method is great for simple physics driven movement stemming from one "parent" point (in this case the fish's head), but it can be easily modified and expanded on.

The joints are divided into five chains of movement, one main chain through the body and one through each of the pectoral and pelvic fins. The joints in a chain each have a rigidbody component, a capsule collider scaled to fit the portion of the fish's body controlled by that joint, and a Unity Character Joint linking it to the rigidbody on its parent joint. They also have a C# script attached that carries the force of movement from the parent joint through to the rigidbody on the child.

// On update childRigidBody.AddForce((parentPositionLastFrame - parent.position) * 100); parentPositionLastFrame = parent.position;

The joint at the head is the source of movement for the whole rig. As the head moves based on player input, this movement is passed down the chain from joint to joint as rigidbody force. The head also has an attached script to make the fish roll when its direction of movement changes.

// Moving right at high enough speed, and currently upside down or twisting if (parentRb.velocity.x > velocityCap && transform.localEulerAngles.y < 180) { // Roll 180 degrees transform.localEulerAngles = new Vector3(transform.localEulerAngles.x, Mathf.Min(transform.localEulerAngles.y + twistSpeed * Time.deltaTime, 180), transform.localEulerAngles.z); } // Moving left at high enough speed, and upside down or twisting else if (parentRb.velocity.x < -velocityCap && transform.localRotation.eulerAngles.y > 0) { // Roll -180 degrees transform.localEulerAngles = new Vector3(transform.localEulerAngles.x, Mathf.Max(transform.localEulerAngles.y - twistSpeed * Time.deltaTime, 0), transform.localEulerAngles.z); }

Without this the fish would continue swimming belly up any time it's moving to the right.

And that's basically it for this particular rig. You can modify simple characteristics like the stiffness and springiness of the chains using the Unity Character Joint component settings (like how in this case the body doesn't flop around as much as the pelvic fins). And you can add more complex behaviors through the scripts on the joints. Feel free to get in touch if you're experimenting with this method or make any cool additions to it.