Using Animation Events

Hiya,

I’m doing the course with a different model pack and animation library. As a result I’ve made some different model and animation choices. Because the course has the Unit model with the rifle in the same position when both idle and firing, the current code doesn’t handle animation transitions + shooting very well. In my case, my idle animation has the Unit with a rifle held at waste level, on shoot it fluidly raises the rifle into aiming position and fires. Unfortunately the existing code will shoot immediately from the hip instead of when the rifle is raised and the burst fire animation occurs.

As a result of this, I ended up using Unity Animation Events. Because Animation Events need to have access to a function on the Animator I created an event bridge script that grabs the parent object UnitAnimator and then instantiate the bullet. I wanted to understand

  1. Is using Animation Events a “good practice” for the use case I’m describing?
  2. Does reaching upwards into the parent create too tight of a coupling? Should I instead just have the event bridge script fire another event that the parent object can listen for and then instantiate the bullet?

Here is my code:

UnitAnimator.cs

    private void ShootAction_OnShoot(object sender, ShootAction.OnShootEventArgs e)
    {
        animator.SetTrigger(Shoot);
        
        // Store the target unit's position for when the bullet is instantiated.
        targetUnitShootAtPosition = e.targetUnit.GetWorldPosition();
        
        // If the target unit has a collider, aim for the upper half of the target.
        // Otherwise, just aim for the same height as the shoot point.
        if (e.targetUnit.TryGetComponent<BoxCollider>(out BoxCollider boxCollider))
        {
            float halfHeight = boxCollider.size.y / 2f;
            targetUnitShootAtPosition.y += halfHeight + Random.Range(0f, halfHeight);
        }
        else
        {
            targetUnitShootAtPosition.y = shootPointTransform.position.y;
        }
        
    }

    // Called by the animation event so that the bullet is created at the correct time
    public void InstantiateBullet()
    {
        Transform bulletProjectileTransform = Instantiate(bulletProjectilePrefab, shootPointTransform.position, Quaternion.identity);
        BulletProjectile bulletProjectile = bulletProjectileTransform.GetComponent<BulletProjectile>();
        bulletProjectile.Setup(targetUnitShootAtPosition);
    }

AnimationEventBridge

public class AnimationEventBridge : MonoBehaviour
{
    [SerializeField] private Unit parentUnit;

    private void Start()
    {
        parentUnit = GetComponentInParent<Unit>();
    }

    public void AnimationEvent_FireBullet()
    {
        parentUnit.GetComponent<UnitAnimator>().InstantiateBullet();
    }
}

I consider it a best practice. By using Animation Events, you can use multiple animations for variation and let each animation set the timing.

Best practice would be to fire another event. That doesn’t necessarily mean it’s the only practice. Your Bridge is tightly coupled, however, so that’s something to consider as the projects and abilities grow.

Perfect, thanks for confirming Animation Events are a best practice for these situations.

And yup, I refactored things to use an additional event since things were clearly tightly coupled. I also added some additional animations and logic that made it obvious this would get difficult to extend and maintain without it.

This topic was automatically closed 24 hours after the last reply. New replies are no longer allowed.

Privacy & Terms