Mecanim Events going ballistic from blend trees.

I’ve got a blend tree set up with 4 directions and all 4 movement animations have footstep events assigned to them.

When I play, the footsteps are going WILD. Sounds to me like it’s trying to play the footstep sounds of every single walk animation in the blend tree as if they were all playing at once.

I was previously using the Mecanim event third party add-on and never had this problem with an identical setup.

Is this a known bug? Will it be fixed? It’s of utmost importance to my project. I’m assuming any bug not listed in the “known issues” thread hasn’t yet been acknowledged.

I am having the exact same problem. I am just thinking about checking if the sound is already playing, but it is not a good solution…

This issue is still un-resolved.

Seems like unity flattens out the animation events and just plays them all, irrespective of the actual weight of the clip.

How should it behave? If you’ve got one animation blended to 0.1 and another to 0.9, should it play events from both? What about when they’re 0.5 and 0.5?

I’ve always used curves for exactly this reason - the curves blend across the animations in the same way as any other curve, and I use zero-crossings to indicate when footfalls occur. The result is zero-crossings that match the foot’s actual movement and so are synchronized to the animation no matter what blend situation it’s in.

4 Likes

Create 2D animations and you’ll very quickly see where this system breaks down.

Unity clearly knows which animation has dominance at any given time but plays the events from animations that technically aren’t playing. Again, make a blend tree for 2D animations and you’ll see that animations play only when they’re dominant.

It shouldn’t be too difficult to have an option for a blend tree to only play events from its current most dominant animation so that those of us making 2D games can still enjoy the organization/power of blend trees.

Making 2D animations without using blend trees gets very tricky, especially when you have 4 directions and 2 different movement speeds (walking and running) to worry about.

If there’s a better way to accomplish what we’re trying to do though, I’m all ears. All I care is that I have a working solution.

I encounterd the same issue. Still no solution besides using curves?

Well you could check his foot transform is close to the floor, and set a no duplicate flag, ie don’t do it in mecanim. This would be a horrible workaround I know.

I’m not sure how it would work when blending between two poses. I think it probably should have conditionals in this case.

Thank you Hippo, you gave me another idea for a workaround with a timer:

    private var canEmit : float = 0.1;
          
function Footstep() {
    if( canEmit <= 0.0 ) {
    var rotation : Quaternion = Quaternion.LookRotation(-myTransform.forward, myTransform.up);
    var position : Vector3 = myTransform.position +  myTransform.forward * -0.5;
    position.y = myTransform.position.y + 0.2;
    ParticleManager.instance.EmitParticle( "particleFootstep", position, rotation, 0.4 );
  
  
    mySoundManager.EmitSound( 0.1, 0.2, "footstep", 5.0 );
    canEmit = 0.1;
    } else {
        decreaseTimer();
    }
}

function decreaseTimer(){
    while( canEmit > 0.0 ) {
        canEmit -= Time.deltaTime;
        yield;
    }
}

It killed the second doubled footstep as expected., but I have to see how stable this workaround is.

Here’s how I solved the footstep problem:

  1. Make 2 different function calls. One for forward steps, one for side.
  2. On your forward & backward animations, put a call to the forward function.
  3. On you side animations, put a call to your side function.
  4. Set up your input so you can measure the side speed and forward/backward speed of your character.
  5. use: if(Mathf.Abs(forSpeed)>Mathf.Abs(sideSpeed)){ in the forward function and the opposite in the side function
    this way it only calls the footstep if the input is pointing to it.

after that for safety, you may also want to add in a delay factor.

2 Likes

I made a video about how to get around this problem. Instead of trying to use Animation Events, use Curves instead! Check out my video for a detailed explanation.

2 Likes

video not available

https://www.youtube.com/watch?v=ISoBKFxQLic

Great Solution!
Put my example code here:

    void FootForward() {
        if(Mathf.Abs(turnAmount) < Mathf.Abs(forwardAmount)) {
            audioSource.clip = footSound;
            audioSource.Play();
        }
    }

    void FootSide() {
        if(Mathf.Abs(turnAmount) > Mathf.Abs(forwardAmount)) {
            audioSource.clip = footSound;
            audioSource.Play();
        }
    }