Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. We have updated the language to the Editor Terms based on feedback from our employees and community. Learn more.
    Dismiss Notice
  3. Join us on November 16th, 2023, between 1 pm and 9 pm CET for Ask the Experts Online on Discord and on Unity Discussions.
    Dismiss Notice
  4. Dismiss Notice

Getting layer information from animation event

Discussion in 'Animation' started by joshcamas, Mar 24, 2018.

  1. joshcamas

    joshcamas

    Joined:
    Jun 16, 2017
    Posts:
    1,268
    Hello friends!

    I have some animation events on my imported clips, like so:


    I've tried using "animEvent.animationState.layer", but it gets mad because it wasn't run by an animator component...


    Which is strange, since when I check "animEvent.isFiredByAnimator", it's true....

    Is there any way to use this?

    EDIT: Alright, I realize I got Animator Component and Animation Component mixed up. Anyways, the question still stands! But now I feel like it may be impossible, since animatorClipInfo contains basically nothing useful :(
     
    Last edited: Mar 24, 2018
  2. joshcamas

    joshcamas

    Joined:
    Jun 16, 2017
    Posts:
    1,268
    Alright, I guess I found a solution. Not exactly the best, but it seems to work fine.

    Basically it goes through each layer in the animator, and compares the current state and the state you are wanting to check. It also compares the next state info, since I had some trouble with events that were run right when the animation clip started.

    Code (csharp):
    1.  
    2.  
    3. public int GetLayer(Animator animator, AnimatorStateInfo animInfo)
    4.         {
    5.             for (int i = 0; i < animator.layerCount; i++)
    6.             {
    7.                 //Check current state on layer
    8.                 AnimatorStateInfo compareAnimEvent = animator.GetCurrentAnimatorStateInfo(i);
    9.                 if (animInfo.shortNameHash == compareAnimEvent.shortNameHash)
    10.                 {
    11.                     return i;
    12.                 }
    13.  
    14.                 //Also check the next, since timing is sometimes a bit off
    15.                 compareAnimEvent = animator.GetNextAnimatorStateInfo(i);
    16.                 if (animInfo.shortNameHash == compareAnimEvent.shortNameHash)
    17.                 {
    18.                     return i;
    19.                 }
    20.             }
    21.             //Couldn't find
    22.             return -1;
    23.         }
    24.  
    25.  
    Example usage:

    Code (csharp):
    1.  
    2. public void AttackReady(AnimationEvent animEvent)
    3. {
    4.       Debug.Log(GetLayer(animator,animEvent.animatorStateInfo));
    5. }
    6.  
     
    theANMATOR2b likes this.
  3. theANMATOR2b

    theANMATOR2b

    Joined:
    Jul 12, 2014
    Posts:
    7,790
    Glad you found a solution.

    Question - wouldn't registering when a certain animation is played be enough to of a condition/event to identify - so the built in event isn't needed? Since start/end animation/state is something that 'happens' can't that be identified rather than having to use a event 'tag' to identify those conditions. Sorry if my question doesn't make sense - for me (non-coder) there is a disconnect in mecanim from builtin accessible features and code accessible features.
     
  4. CaseyLee

    CaseyLee

    Joined:
    Jan 17, 2013
    Posts:
    40
    A good introduction, and lead in for using Animation Behaviors. Although I don't know enough about the situation to say for sure. One thing is for sure tho Animation events are sketchy and awkward and I don't ever use them. For the second solution, the point of having an event notification is to avoid having to ask each frame if that event has fired yet. And how many of these states need to ask each layer, each and every frame, if they are having their event?

    Now are you controlling your Mecanim? or is your Mecanim controlling you?? See, Its out on the town - off doing crazy gone-wild unadulterated stuff. Meanwhile your oblivious and then eventually frantic. Calling around, just hoping to figure out what its currently is and specifically is not doing. Now In my day when a guy was going to use a state-machine he sure as hell had access to its property values and I don't know where you got the nerve...


    Imagine an animation behavior on each of your animator states and state machines - call it Competent_State (can procedural add them no need to manually)... Okay and then during initialize/start a class named Competent_State_Machine gets a list of those Behaviors types from the animator component attached to the same GO as it is... so now Competent_state_machine gives the competent_states a reference to it,. because the anim-behaviors get callbacks for on-play/ during-play/ stop play. And also know what layer they are on because you procedurly added them and stored that value as you were iterating threw the more robust editor-version of animator-controller. So anyway your competent state machine knows everything and you are now the master of your domain and the king of your Castle.


    It's 10 O'clock... do you know where your animator-Controller is?
     
    theANMATOR2b and joshcamas like this.
  5. joshcamas

    joshcamas

    Joined:
    Jun 16, 2017
    Posts:
    1,268
    Well for me, I'm using events for item animations. For example, there may be an animation called "Sword_Aim"... the playing of this animation is controlled by mechanim, since I'm using it's transitions. Of course, I'm also aware that I am aiming on the game side of things... So why do I need an event in this case?

    Well, in my case, simply playing the aim animation isn't enough. In my game you need to aim (well, for a sword it's more like a "prepare to swing") for a certain amount of time before it is "ready", then it will attack.

    Think skyrim, where you need to hold down the mouse for a certain amount of time to make the character hold his axe up, and then when you let go of the mouse the character lets it swing down, causing damage.

    I want to give the animators the ability to decide when that "aim ready" time is. This is where I use an event!

    Another good example would be a "footstep" event, that is run every time a character's foot lands on the ground. The rate this happens is different per animation, (running, walking) so it's a perfect use for an event.
     
    theANMATOR2b likes this.