Search Unity

StateMachineBehaviour.OnStateEnter Question

Discussion in 'Animation' started by lxmllr, Jan 31, 2019.

  1. lxmllr

    lxmllr

    Joined:
    Mar 27, 2018
    Posts:
    6
    Isn't this message supposed to be sent on the first frame of an animation state's loop? I'm only getting the message when the animator first hits that state, but on subsequent loops it won't keep firing.

    I've heard frame events are somewhat unreliable due to transitions, so what are the recommended ways to execute a command once per animation-state cycle?
     
    Last edited: Jan 31, 2019
  2. Kybernetik

    Kybernetik

    Joined:
    Jan 3, 2013
    Posts:
    2,570
    No, it's called when the state is entered. A looping animation enters its state once, it doesn't keep re-entering it at the end of every loop.

    What are you actually trying to do with the event?
     
  3. bbsuuo

    bbsuuo

    Joined:
    Jul 21, 2016
    Posts:
    16
    private int currentLoopIndex = 0;
    public override void OnStateUpdate(Animator animator, AnimatorStateInfo stateInfo, int layerIndex)
    {
    base.OnStateUpdate(animator, stateInfo, layerIndex);
    if((stateInfo.normalizedTime) / stateInfo.length> currentLoopIndex){

    //var value = Random.Range(clampRandom.x, clampRandom.y);
    //animator.SetInteger(parameterName, value);
    // do you thing
    currentLoopIndex++;

    }
    }
     
    apparition and zORg_alex like this.
  4. apparition

    apparition

    Joined:
    Jan 11, 2012
    Posts:
    120
    There's no need to divide stateInfo.normalizedTime by stateInfo.length because the time is already normalized (each increment of 1.0f represents a full loop). This should look something like this:

    Code (CSharp):
    1. private int currentLoopIndex = 0;
    2. public override void OnStateUpdate(Animator animator, AnimatorStateInfo stateInfo, int layerIndex)
    3. {
    4.     base.OnStateUpdate(animator, stateInfo, layerIndex);
    5.  
    6.     if (Mathf.FloorToInt(stateInfo.normalizedTime) > currentLoopIndex)
    7.     {
    8.         // do your thing
    9.         currentLoopIndex++;
    10.     }
    11. }