Search Unity

Animation Events and Transitions. Help!

Discussion in 'Animation' started by Nanako, Apr 15, 2015.

  1. Nanako

    Nanako

    Joined:
    Sep 24, 2014
    Posts:
    1,047
    Ok, my situation.

    I have an animation (of my character swinging a hammer). Near the end of the animation, i have an animation event. This fires off a function which sets a specific variable ("canAttack") to true, thusly allowing more swings to be done, if the user clicks again

    The idea here is that the point where i consider the attack "finished" is not the same as the end of the animation, and this allows me to seperate those two concepts.

    What i intend is that if the user does not swing the hammer again, then the character slowly and smoothly transitions back to an idle pose. And i'd like that slow transition to be interruptible at any time, with a new swing.

    The problem right now is, as soon as the animation event hits, the animation ends and goes back to the neutral state immediately, with a transition that looks unnaturally fast. Basically here's not a ransition at all, it just teleports from one pose to the other

    Here's how my animator is setup. The states swing and hold are what's important (hold is a statemachine, although it currently contains only the single substate Hammer)



    Now what i've found is, a slow transition, the one i desire and want to see, DOES happen if the following are true:

    1. The transition from swing to hold "has exit time"
    2. The value of the exit time is set to happen BEFORE the animation event is triggered
    3. No parameter checking condition is set on the transition
    Under these conditions, the animation will slowly transition to the holding stance depending on the transition time i set, BUT this also prevents the transition from being interrupted by a new swing.

    If i set the exit time after the event, slow transition doesn't happen, i've no idea why.

    The main thing the animation does is set the boolean "canAttack" to true. If i add the condition "canAttack = true" then the transition doesn't work

    HOWEVER, if i set the condition "canAttack == false", and disable the exit time then the slow transition does happen. But with the same problem as above (the animation event isn't called until the transition ends)

    So, the slow transition ALSO works in the following circumstance:
    1. The parameter checking condition "canAttack == false" is set
    2a. Exit time is set on the animation, at a time before the anim event occurs
    OR
    2b: Exit time is not set on the animation

    But again, the transition cannot be interrupted with a new swing, and the logic for it working does not make sense.

    This is confusing me

    What logic dictates should happen, and what i'd like it to do, is to set an exit time after the event, to set the condition "canAttack == true", and for the slow transition to thusly happen after he animation event has triggered and set canAttack to true.

    I cannot find any state where a check for "canAttack == true" causes the slow transition to happen.

    I realise this thread is very convoluted. What could i provide to demonstrate the issue?
     
  2. waythewanderer

    waythewanderer

    Joined:
    Apr 6, 2015
    Posts:
    92
    Perhaps showing the screenshots of your state transitions' conditions?

    Maybe this whole issue has something to do with several transition conditions that work on different frames, layers or whatever, which kinda confused the Animator Controller I suppose?

    If the exit time is after the event, the transition turns abrupt, right? Which state does it go to? The hold stance?

    I don't know how to solve this if you insist on making the canAttack boolean = true, but I may go about this by just having the swing state go to the hold stance state (which will go to the idle/neutral state after a timer goes to zero/expires), while player input will still be able to make the 2nd swing occur, before the timer expires.

    It will be interesting if we can make this occur with the anim event, though I have not tried it myself :rolleyes:
     
  3. Nanako

    Nanako

    Joined:
    Sep 24, 2014
    Posts:
    1,047
    ok here's how things look just now. In order to have a little less complexity, i moved the hammer hold out of the state machine, it's the state now named "hammer"

    http://i.gyazo.com/62cdc48380f8d4cacce2a2261150a229.png


    The Hold statemachine floating at the top does nothing, its not involved. The transition from entry to swing is something i can't change or adjust, not sure what that is

    The transition from Any State to swing looks like this:



    I'm sure that's far more information than necessary, the only really relevant part is at the bottom. isAttacking is a trigger which is set by a script when i start attacking. The code controls when and how it can be set. But right now the internal logic for it is basically, if canAttack == true, then isAttacking can be set to true as well (doing so will set canAttack to false)

    The reason i have this transition from anystate is so that, as long as script logic allows, the character will drop everything else and swing their weapon when instructed to. Even if still in the animation of an existing swing (in practise this can only happen after the swing's animationevent triggers)



    Here is the transition from swing to hold, although i'm not sure what is gained in showing you this since as outlined above, i'm currently changing it wildly to try to make things work. Nevertheless, here's the settings for an optimal transition. The settings which, as far as i'm aware, should work perfectly (they don't).



    The exit time here is 0.87 (i'm aware that exit time is a normalised time value)
    For reference, the animation event fires about halfway through the swinging animation, so this exit time is set well after it.

    The condition is canAttack = true. I believe how this should work is, the transition should not begin if canAttack is not true. And if the end of the swing animation is reached, but canAttack is still somehow set to false, then the character should stay stuck in the last frame of the swing animation. Otherwise, the transition should begin at any point where the animation is at least 87% complete, and canAttack is set to true.

    Anyways, for reference, here is how this transition looks in the animation preview, slowed down so you can see it better (note that there isn't actually a hammer mesh visible, that's not relevant just now)



    Note that once his hands reach the left side of his hips, he starts returning slowly to the neutral stance. I'm pretty sure this is actually happening before the exit time i've set, though it seems about right for the animation event timing

    Anyways, Finally, here's how it actually looks ingame, with these settings



    I'm just spam clicking the swing button here. This is played at realtime, so he should be returning to the neutral pose over 1.5 seconds, but he just teleports back to it instantly instead.
     
  4. waythewanderer

    waythewanderer

    Joined:
    Apr 6, 2015
    Posts:
    92
    I just noticed this in the last statement of the following link:
    http://docs.unity3d.com/Manual/class-Transition.html

    "If you have “Has Exit Time” selected for the transition and have one or more conditions, the condition(s) will only be checked after the exit time of the state. This allows you to ensure that your transition will only occur during a certain portion of the animation."

    So it says. Though I wish to know how this works. Unity has made it that your canAttack condition will only be checked after the exit time.

    It all makes sense now. Having the canAttack condition looks like a redundant step, if all the animation event does is set this boolean to true. Without this event, the boolean (even if it's not in your code) will technically be true anyway, once you have the exit time and a transition arrow from your swing to hammer stance, don't you think?

    How will your canAttack somehow be set to false? Do you have functions doing that? Usually I use animation events for parameters I definitely want set to true/false, just a matter of firing them at different time points of the clip. Or, rather than timing your events this way, you can have several transitions to different states according to your needs, based on the corresponding parameter conditions. This can be easier.
     
  5. Nanako

    Nanako

    Joined:
    Sep 24, 2014
    Posts:
    1,047
    I fail to see how this is a problem. Logic would dictate then, that the canAttack will be sset true, then the exit time will occur, and then the conditiion will be checked, see that it is true, and begin the transition. Why is this not so?


    On nthe contrary, i would say it's the exit time which is redundant. The event is necessary for internal logic.. canAttack is set to false when the attack starts, remember? The event sets it BACK to true to signal that the attack is done.



    it was just mentioned for a matter of logical completeness. mostly it would happen in a case that i insert an improperly made animation

    I don't feel any closer to an answer here.
     
  6. waythewanderer

    waythewanderer

    Joined:
    Apr 6, 2015
    Posts:
    92
    Your canAttack will be set to true eventually, am I right?

    Try reviewing your working scripts to see if you made the code unnecessarily complicated.