Search Unity

State behavior OnStateMove() called after state has ended?

Discussion in 'Animation' started by reslived, Mar 10, 2020.

  1. reslived

    reslived

    Joined:
    Feb 20, 2015
    Posts:
    2
    I'm working on a prototype fighting game. Fighting game animations need to be frame tight, and work in tandem with user inputs. I've decided against using the default animator multithreading by disabling the animator when a character is enabled and manually triggering Animator.Update() on every character Update() frame. (this was recommended in a different thread in the forums that I can no longer find).

    I've also set all transitions to have length 0, in the hopes that each frame would either be one call to the current state's OnStateUpdate(), or a transition call to the first state's OnStateExit() (with a call to the next state's OnStateEnter() on the next frame).

    In order to account for any movement or physics that may occur during an animation state, I was using the OnStateMove() call to handle all physics of moving the character based on a combination of inputs being read and the current state.

    I have run into 2 problems with this setup:

    1) Let's say I initiate a transition from state 1 to state 2. I've noticed that the OnStateMove() for state 2 appears to be getting called for one frame after its OnStateExit() has been called. In fact it is getting called in the same frame that state 1's OnStateEnter() is being called. How can I prevent this? I want to make sure that the OnStateMove() for each state only gets called while that state is active.

    2) I read inputs from the user before calling animator.Update(). For some reason, calling animator.Update() like this does not trigger a transition when using OnStateUpdate() to set animator parameters. It ends up looking like an input is read, the animator updates, the same input is read, animator updates again, input is read one more time, and finally the animator calls OnStateExit() to begin transition. How can I ensure that the frame an input is read that a transition begins?

    If using the Mecanim animator state behaviors is not optimal for this setup, I can try to code my own implementation, but I was really hoping I could lean into Unity as much as possible
     
  2. Kybernetik

    Kybernetik

    Joined:
    Jan 3, 2013
    Posts:
    2,570
    1) Can't you just set a bool in Enter() and Exit() which Move() checks to determine if it should do anything or not?

    2) You probably can't. The whole Animator Controller system is pretty unreliable and you can never be sure if it will actually do what you told it to. For example, if you call animmator.Play("StateA") then animmator.Play("StateB") in the same frame it will end up playing StateA and totally ignoring the second call without giving you any indication that it has done so unless you wait a frame and check what state it is in.

    You might be interested in Animancer (link in my signature) as an alternative to Animator Controllers or you can try to figure out how to use the Playables API yourself (not a fun task given its abysmal documentation and small user base).
     
    yektasarioglu likes this.
  3. reslived

    reslived

    Joined:
    Feb 20, 2015
    Posts:
    2
    1) I will definitely try that. That can help with that immediate issue for OnStateMove()

    2) That's unfortunate... I really like the flexibility with Unity but if it can't assure actions on a frame-by-frame basis I'm not sure if I should rely on it.

    Are Animancer/Playables API the only possible solutions here? I saw a pinned thread about the SceneLinkedStateBehavior... Is that something that might be able to help me solve my problems? I'm worried that I will have to rebuild my whole animator/character relationship from scratch to get the behavior I want.
     
  4. Kybernetik

    Kybernetik

    Joined:
    Jan 3, 2013
    Posts:
    2,570
    I doubt SceneLinkedStateBehavior can help, though I've never used it. You might be able to find other systems that use the Playables API, but Animator Controllers are too much of a restricted black box for anything to really fix an issue like this without changing to another system.
     
    yektasarioglu likes this.