Best practice to perform an action in time with an animation

I’ve got a custom CharacterController script setup. When the player clicks on a resource that he wants to harvest, I need to harvest a piece of that resource but only in time with the animation (i.e, the animation takes 3 seconds to complete, so the character’s input should be “locked” for 3 seconds at which point the player gets a resource and then can issue new commands). I’m curious what the best practice is to accomplish. Any tips?

Currently I’m using Mecanim animations; I can start the animation from my c# script like this:

anim = GetComponent<Animator>();
anim.SetBool("isHarvesting", isHarvesting);

One way to do it would be to block the user’s input at the start of the harvest, and then use an Animation Event at the end of the animation to unlock it.

Here’s the relevant documentation.

Several ways to do this.
An animation event would certainly do the trick, and they shouldn’t be missed. Here’s hoping that Unity has something in place to prevent that.

Another way to do this is with a coroutine, when you click the button to harvest the crop, you start the coroutine. You can use:
yield return new WaitForSecond(3.0f); to lock it down.

When your coroutine starts you lock input, and when the coroutine finishes, you unlock the input. You can then setup the animator controller to transition back to the default state as well. As well as any other bits and pieces. This approach may be more flexible than an animation event, depending on what your game can do to the character while harvesting.
The veggies fight back maybe?

Here’s some documentation on coroutines to get you going:

Hopefully this’ll help.

All above solutions should work but they have dissadvantages:

  • animation event might be missed depending on how you setup the transitions, also every time you update the animation you will need to redo the event
  • pairing coroutine has a risk to desynchronise with the animation

the best and most reliable method would be to unlock the input using https://docs.unity3d.com/ScriptReference/StateMachineBehaviour.html

simply go to your state in mecanim and in inspector click addBehaviour. and continue from there.
If you want an action after animation is done use the OnStateExit or OnStateUpdate in which you can get the time of current animation. These event always fire unlike the animation events.

you could try this if(!isHarvesting){ %|-433809979_1|% }