Search Unity

Question How can I create an animation event based on a window of frames, instead of a single one?

Discussion in 'Animation' started by SassyPantsy, Feb 17, 2021.

  1. SassyPantsy

    SassyPantsy

    Joined:
    May 17, 2020
    Posts:
    142
    HI all, I'm working on a combat system right now, which is based on a combinations of collision and animation.
    My mission at this moment is to create a "window of opportunity" for an attack to register once - I see it as an animation event that spans across a number of frames, instead of just one frame.

    Is there a way to do this? I've been thinking about rigging multiple animation events to the same function call, or to create a coroutine, that when triggered via animation event, sets a "canAttack" boolean to true for a certain amount of time (which would need to be set individually), but I was wondering about a more straightforward way.

    Thanks !
     
  2. M-Elwy

    M-Elwy

    Joined:
    Jan 28, 2021
    Posts:
    38
    I use similar technique, i use two events, "activateCollider" to activate collider for example at frame 5.
    And "deactivateCollider" to deactivate collider for example at frame 10.
    If animation got interrupted before "deactivateCollider" is fired (ex: receive damage), the collider will remain active.
    To solve this issue, you should deactivate all colliders while in "damage" and "idle" state.
     
    SassyPantsy likes this.
  3. SassyPantsy

    SassyPantsy

    Joined:
    May 17, 2020
    Posts:
    142
    Good logic, I'll def try that. Few questions:

    How do you deactivate/activate collisions? Via a state bool in OnTriggerEnter/OnCollisionEnter?

    Also, how do you counter the fact that damage can overlap? By the usual means? Cause I'm thinking of a target getting in and out and in during the damage window and getting hit multiple times. although the frames should pass quick enough now that I think about it
     
  4. M-Elwy

    M-Elwy

    Joined:
    Jan 28, 2021
    Posts:
    38
    I create empty gameobject, add components for capsule collider, rigid body, and the script that handles the collision, deactivate it and create prefab of it, parent prefabs to hands/legs/weapons.

    In animation event "activateCollider" I activate the prefab, then deactivate it in "onTriggerExit" and animation event "deactivateCollider"
    In both events I pass parameter (ex: ID) to identify which collider to activate/deactivate

    Code (CSharp):
    1. CapsuleCollider capCollider;
    2. bool alreadyHandling;
    3.  
    4. private void OnEnable()
    5. {
    6.     if (capCollider == null)
    7.     {
    8.         capCollider = gameObject.GetComponent<CapsuleCollider>();
    9.     }
    10.     capCollider.enabled = true;
    11. }
    12.  
    13. private void OnDisable()
    14. {
    15.     alreadyHandling = false;
    16. }
    17.  
    18. void OnTriggerEnter(Collider other)
    19. {
    20.     if (alreadyHandling)
    21.     {
    22.         return;
    23.     }
    24.     alreadyHandling = true;
    25.     doDamageToEnemy();
    26. }
    27.  
    28. void OnTriggerExit(Collider other)
    29. {
    30.     alreadyHandling = false;
    31.     capCollider.enabled = false;
    32.     gameObject.SetActive(false);
    33. }
    I forgot why I was deactivating both the collider and the prefab, deactivating one of them should be enough, but give it a try.
     
    Last edited: Feb 18, 2021
    SassyPantsy likes this.
  5. SassyPantsy

    SassyPantsy

    Joined:
    May 17, 2020
    Posts:
    142

    That's pretty clever... This seems like it allows for directional collision, which is also something I'm working on. Thanks bro!
     
    M-Elwy likes this.
  6. M-Elwy

    M-Elwy

    Joined:
    Jan 28, 2021
    Posts:
    38
    Good luck mate.
     
    SassyPantsy likes this.