Grenade Action

When I got to setting up the sword animation, I decided to set up a grenade throwing animation. I found a decent animation from Mixamo where the model started holding a rifle and then threw a grenade with their other hand, perfect for our model. I imported the animation as we have done other times and set up the transitions close to the sword ones. I was able to get everything set up, except that the grenade would fly and land all while the animation had just started. I wanted to set up an animation event, but I wasn’t sure how to write it up the way that we are using animations.

I was able to create an event, but since the animation is read only, I couldn’t wire a script to it. I ended up just putting the TakeAction into a coroutine with a delay in order to hack it. But I’m wondering if there’s away to do it using an animation event as I was trying. Most of my experience when using animations is actually pulling the animation out of the container it comes in with mixamo which then changes the animation from read only to read and write. However since we’re not using them this way I was wondering what alternatives there are.

Here’s my hack code:

    public override void TakeAction(GridPosition gridPosition, Action onActionComplete)
    {
        OnThrown?.Invoke(this, EventArgs.Empty);
        //hack to wait for animation to complete
        StartCoroutine(Delay(gridPosition, onActionComplete));
    }

    IEnumerator Delay(GridPosition gridPosition, Action onActionComplete)
    {
        yield return new WaitForSeconds(2);
        //Transform grenadeProjectileTransform = Instantiate(grenadeProjectilePrefab, _unit.GetWorldPosition(), Quaternion.identity);
        Transform grenadeProjectileTransform = Instantiate(grenadeProjectilePrefab, grenadeThrowLocation.position, Quaternion.identity);
        grenadeProjectileTransform.GetComponent<GrenadeProjectile>().Setup(gridPosition, OnGrenadeBehaviousComplete);
        print("Grenade Action");

        ActionStart(onActionComplete);
    }

Thanks for your time!!!

Every instructor likes to extrac the animations from the fbx import, but this isn’t strictly neccessary. Within the animation import dialogue, you can change the name of the animation, and if you scroll down, you can add animation events. If you still want to extract the animation after you’ve added the event, you can, and the event will be in the animation. (You can extract the animation by copying it and pasting it into the directory).

1 Like

You can remove the ReadOnly tag by duplicating the animation to get it outside the .fbx How to FIX Read-Only Animations (and Edit Humanoid Animations inside Unity) - Code Monkey

With that you can use Animation Events although your approach is also valid. Personally I dislike coroutines but I’ve used my FunctionTimer class several times to do exactly that kind of animation timing logic. Trigger an Action after some Time - Code Monkey

1 Like

OK, thanks for the input and the quick response, guys! I was worried that a timer or my coroutine might not look great if there’s some lag in the game causing the timing to be off.

Which of the two methods do you consider to be a better approach?

I did get them the animation event working, but am more curious to see which approach makes more sense.

Here’s how I got the animation event working:
I altered the TakeAction to save the target position to a private field. In order for the animation event to be able to trigger a method, it seems the animator and the script need to be on the same level. Since our scripts are on the parent object and the animator is on the child model, it couldn’t access the scripts. I created a new script that was attached to the model WITH the animator:

public class ThrowGrenade : MonoBehaviour
{
    private GrenadeAction _grenadeAction;

    private void Start()
    {
        _grenadeAction = GetComponentInParent<GrenadeAction>();
    }

    public void GrenadeHasBeenThrown()
    {
        _grenadeAction.ThrowTheGrenade();
        print("thrown");
    }
}

It just calls the method “ThrowTheGrenade” (in the parent class GrenadeAction) when at the apex of the throw. Then I moved the actual Instantiate of the prefab into the method “ThrowTheGrenade”:

    public override void TakeAction(GridPosition gridPosition, Action onActionComplete)
    {
        OnThrown?.Invoke(this, EventArgs.Empty);
        _targetGridPosition = gridPosition;
        ActionStart(onActionComplete);
    }

    public void ThrowTheGrenade()
    {
        Transform grenadeProjectileTransform = Instantiate(grenadeProjectilePrefab, grenadeThrowLocation.position, Quaternion.identity);
        grenadeProjectileTransform.GetComponent<GrenadeProjectile>().Setup(_targetGridPosition, OnGrenadeBehaviousComplete);
    }

Then I set up the animation event and added the method:


At first the ThrowGrenade script triggered an event that the GrenadeAction.ThrowTheGrenade method was watching, hilariously it triggers EVERY SINGLE Unit to throw a grenade. I then looked to make sure that the TakeAction had thrown a grenade first, but then decided to refactor it so the ThrowGrenade class just calls the ThrowTheGrenade method in the GrenadeAction directly to avoid this.

Thanks so much!

Julian

1 Like

This is pretty much how I handle animation events when the Animator is not on the same level as the core logic/actions.

1 Like

OK, thanks! One last question. If you export the animation as Code Monkey demonstrates. When you select the animation event, you can actually select the actual method, rather than typing in a method name and hoping it works. It seems a bit “safer” to me.


I guess my main question is are there advantages to keeping the animation in the FBX file? Or if I need to edit the animation or add an animation event, should I just go ahead and extract it knowing that I’m not making any sacrifices in functionality?

Thanks again for the help! You are truly a Unity Asset. :slight_smile:
Julian

I tend to keep them in the FBX, unless I have to make modifications to them like with the Rifle Running to fine tune things… That’s just a preference for organization. There’s no hard and fast rule, and when they are packaged for a final Build, Unity does it’s own thing with both in FBX and separate animations, so neither is inherently faster performance.

Privacy & Terms