I have watched this brilliant tutorial about animation events in Unity and I have to say I am very impressed with their power and ease of use.
In my case however, I need to be able to have a function check specific conditions starting from a specific frame and ending at a specific frame. For example, using a similar case to the video above, if I have an attack animation 20 frames long, and I would like my function to check a condition from frames 12-18 only, can this be achieved using animation events only? I realise the same event could be created for each of these frames but then if I have a damage function for example, this function would be applying the damage multiple times (once in every frame it is called) which is not the desired effect. At the moment, the only way I can see this working is using a boolean also. Is there another way?
Animations are timebased in Unity. Animation consist of keyframes that are interpolated. So an animation ia always inbetween two keyframes. So frames doesn’t exist in terms of animations.
What you can do is create one animation event that sets a variable “true” and another one that reverts it to false. That way you have a variable that can be used in update. It will be true as long as the animation is in between your two animationevents.
edit
I guess you want to check for “hits” only between sepcific keyframes. As already said Keyframes are irrelevant for Unity. They are just used to interpolate the actual values. Animations and of course animation events are timebased. For more information see AnimationEvents.
I suggested to use a boolean to signal that the animation is in between the desired keyframes / timespan. This variable can be used as an additional condition. I guess you use a sword with a collider and use it as trigger (At least this is how we have done our collision so far).
In the OnTriggerEnter callback you can check if the condition is true. So any collisions that happens outside of the timespan will be ignored.
//C#
//[...]
public bool isAttacking; // set / reset by animation events
void OnTriggerEnter(Collider aOther)
{
if (isAttacking)
{
// do damage to aOther
}
}
// ********************************
// UnityScript (Unitys Javascript)
var isAttacking : boolean; // set / reset by animation events
function OnTriggerEnter(aOther : Collider)
{
if (isAttacking)
{
// do damage to aOther
}
}
Just as a final hint: We used a quite similar way for our hack & slash game. We didn’t used animation events, but also a timespan within the animation. The big problem with colliders / triggers and fast animations is that it will often miss a collision due to a low framerate. We tried a lot optimisations but nothing was satisfying. Since animations are sampled at the current time and the time advances in relation to the current FPS the actual movement will look different each time you play the animation. If a movement is really fast it could even happen that it completely skips the fast part (if the deltaTime is too big).
Our project has been abandoned since it was a student project so we stopped searching for a solution. I can’t really suggest a specific method since that depends on how your attack animations look like. If our project is resurrected the other day we thought about using non-animated colliders that just describe the trajectory of the weapon and apply damage to what ever is in this area at a specific time.