Animating my Unicyclist

We have a cool unicyclist character who is intended to ride around on his unicycle at all times. He has an idle balancing animation, and a walk (slow cycling) and run (fast cycling) animations as well. Everyone else in the project is bipedal, so I have been using the Locomotion System on all of them, however this guy is not, so I have been using a script based off of the ComplexWalkBlend script included with the Character Animation tutorial.

I can get this script to work easily on a bipedal character, but not on the Unicyclist. He will move around from place to place properly, even changing the direction he faces, but will not animate at all. Even when I force the walk.weight to be 1 and the speed to be 1, I see no animation being played.

I realize the best way to diagnose this would be to create a package and post it, but at this point the project is massive and any package I export from it is equally so. We’re attempting to analyze any issues with the FBX export from max that may be involved with this, or anything specifically asset related. For now I can only offer up the scripts driving it and hope that someone has encountered a similar issue before.

using UnityEngine;
using System.Collections;

public class AvatarAnimator : Avatar {
	
	/*
	* AvatarAnimator.cs
	* by Aaron Siegel, 8-21-2010
	*
	* Acts as animation blend controller for avatars that don't use the locomotion system.
	*/
	
	public float walkSpeed = 2.3f;
	public float runSpeed = 3.6f;
	public float idleThreshold = 0.5f;
	public float speedSmoothing = 8.0f;
	public float gravity = 5.0f;
	
	private AnimationState run;
	private AnimationState walk;
	private float currentSpeed = 0.0f;
	private float smoothedSpeed = 0.0f;
	private Vector3 lastPos;
	private Vector3 pos;

	void Start () {
		// We are in full control here - don't let any other animations play when we start
		//animation.Stop();

		// By default loop all animations
		animation.wrapMode = WrapMode.Loop;
		
		// setup list of animations for reference when setting current animation via RPC
		walk = animation["Walk"];
		run = animation["Run"];
		
		// Enable all walk / run cycles 
		// We will manually adjust the blend weights every frame
		walk.enabled = true;
		run.enabled = true;
		
		// Synchronize all walk / run cycle animations
		animation.SyncLayer(0);

		// Put the idle animation in a lower layer.
		// This will make it only play if no walk / run cycle is faded in
		animation["Idle"].layer = -1;
		animation["Idle"].enabled = true;
		animation["Idle"].weight = 1;
	}

	void Update () {
		
		// check person object position for latest tracking data
		lastPos = transform.position;
		pos = person.getPosition();
		
		// look towards new position
		Vector3 offset = pos - transform.position;
		offset.y = 0;	// ignore Y height so character doesn't rotate along the X axis
		if(offset.x != 0  offset.z != 0){
			transform.rotation = Quaternion.LookRotation(offset,Vector3.up); 
			// move to new position
			currentSpeed = Vector3.Distance(pos, lastPos);
			CharacterController cc = (CharacterController)GetComponent ("CharacterController");
			Vector3 forward = transform.TransformDirection(Vector3.forward);
			cc.SimpleMove(forward * currentSpeed );
			if(!cc.isGrounded){
				transform.position = new Vector3(transform.position.x, transform.position.y - (gravity * Time.deltaTime), transform.position.z);
			}
		}
		
		smoothedSpeed = Mathf.Lerp(smoothedSpeed, currentSpeed, Time.deltaTime * speedSmoothing);
		// Calculate the weight between walk and run from the current speed
		float runWeight = Mathf.InverseLerp(walkSpeed, runSpeed, Mathf.Abs(smoothedSpeed));
		// adjust the animation playback to match the characters speed
		run.speed = smoothedSpeed / runSpeed;
		walk.speed = smoothedSpeed / walkSpeed;
		
		// When the character slows down fade out the run and walk weights
		if (Mathf.Abs(smoothedSpeed) < idleThreshold){
			run.weight  -= Time.deltaTime * 5.0f;
			walk.weight -= Time.deltaTime * 5.0f;
		} else {
			float totalWeight = run.weight + walk.weight;
			totalWeight += Time.deltaTime * 12;
			totalWeight = Mathf.Clamp01(totalWeight);

			// Set the weights based on the current speed
			run.weight = runWeight * totalWeight;
			walk.weight = (1.0f - runWeight) * totalWeight;
		}
		
		walk.weight = 1;
		run.weight = 0;
		walk.speed = 1;
		run.speed = 0;
		
		print("unicyclist info: runspeed "+ run.speed +", walkspeed "+ walk.speed +", runweight "+ run.weight +", walkweight "+ walk.weight);

	}
	
}

Here is the super class Avatar.cs being used for all characters in the project:

using UnityEngine;
using System.Collections;

public class Avatar : MonoBehaviour {

	/*
	* Avatar.cs
	* by Aaron Siegel, 6-10-2010
	*
	* Super class for all 3D model attributes used to interact with one or more person objects.
	*/
	
	public Person person;
	public bool fadingIn = true;		// booleans for events
	public bool fadingOut = false;
	public bool playSoundOnStart = true;
	public bool dancing = false;
	public Transform objectLabel;	// reference to object label applied to this avatar
	
	public void dance(){
		Vector3 v = Camera.main.transform.position - transform.position;
        v.x = v.z = 0.0f;
        transform.LookAt(Camera.main.transform.position - v);
		animation.CrossFade("Thriller");
		dancing = true;
	}
	
	public void setPerson(Person person){
		this.person = person;
		print("person set");
	}
	
	public void setPosition(Vector3 pos){
		transform.position = pos;
	}
	
	public void setRotation(Quaternion rot){
		transform.rotation = rot;
	}
}

Image included shows the environment with the Unicyclist in his T-pose and the rest of the characters happily walking around.

You need to set the blend mode to Additive to get the weights to work:-

walk.blendMode = AnimationBlendMode.Additive;

Well, I tried that and still don’t see any animation occurring. I was really hoping that would fix it. :? It’s not even playing the idle animation… it’s just stuck in the T-pose. “Play Automatically” is unchecked.

SOLVED.

Turned out to be some weird rigging issue in Max.