Mecanim Layers -- How to gracefully blend between?

I have set up an enemy who walks/runs/turns/idles wonderfully. I’ve added an upper body layer for attacking, when the enemy is close enough to the player (1st person). The first attack blends into the start nicely, but cuts off half way through, and subsequent attacks (every 4 seconds or so) last only a brief moment and are very very choppy.

Here’s a video showing the issue: http://www.sfbaystudios.com/layersissue.mov

I’m posting the code below. I think I’m unsure how to gracefully blend between layers, using SetLayerWeight, and also how to allow enough time for the animation to finish before changing the layer weight. Unfortunately Unity Tutorials hasn’t posted the next (and probably the answer to my question) section of the Stealth project. :slight_smile:

CODE: (I’ve cut out unimportant parts, and I’m sure it can be optimized, so there are likely unneeded parts too)

function Update () {
	if (reenableNav < Time.time && didAttack)
	{
		didAttack = false;
		enemyAnimator.SetBool ("Attack1", false);
		enemyAnimator.SetLayerWeight(1, 0);
	}
	
	distanceToPlayer = Vector3.Distance(transform.position, playerPosition);
}

function OnTriggerStay (other : Collider)
{
	
	// First find if it's player
	if (other.gameObject.tag == "Player" && enemyNav.enabled)
	{
		// If enemy is within attack range to player, and cooldown has finished, attack player
		if (distanceToPlayer <= attack1Range && cooldownTime < Time.time)
		{
			reenableNav = (Time.time + 0.9);
			enemyAnimator.SetBool ("Attack1", true);
			enemyAnimator.SetLayerWeight(1, 1);
			cooldownTime = (Time.time + attack1Cooldown);
			didAttack = true;
		}
	}
}

It looks to me like the attack is retriggering too soon.

Two suggestions:

  1. Do you really need to set layer weights? Why can’t your upper body layer just be in a null state most of the time, and transition to attacks when you set the Attack* bools to true? The attack states would transition back to the null state on exit time. If this would work for you, then you just need to set the weight to 1 at the start. Seems like this would take some complexity out of debugging the issue.

  2. Always check the current state before turning off parameter bools. OnTriggerStay works off the Physics loop, which is different from the Update() loop.