Tilevania problem with animation when shooting

Hello,
I decided to work a little more in Tilevania project so I added ability to shoot. But I have problem with one animation.

I modified player sprite and added one where player run and have raised arm to shoot. When player presses Fire1 button, animator sets Firing bool to true (and bullet is instantiated). When player lets go of Fire1 (GetButtonUp) Firing bool is set to false.

Everything works except when running.
Player correctly transitions into running firing animation and when player lets go of the button animation goes back to regular running animation. But the problem is - after transition both animations start from frame 0.

If player was on frame 3 in run animation, he will transition to frame 1 in shooting running animation. Or - what’s worse - when player spams fire button, animation will practicaly always stay on frame 1 (because animator is transitioning betwen normal run and shooting run animation and stays on frame 1 on both of them because animation does not have time to play properly).

I don’t know if I explained it correctly but what I would like to know is: is there a way to not reset animation frame after transition? If “Player Run” is on frame 3, then when transition is triggered (without any exit time, like in the tutorial) the target animation will start FROM same frame? And not from the beginning?
Make transition remember frame and set target animation to same frame?

Or is there another way to do this?

Hi,

Welcome to our community! :slight_smile:

Have you already seen this thread on reddit?

Maybe the suggested solution could help you solve your problem.


See also:

Okay, thank you, that thread pushed me in the right direction.

I have a solution but somebody smarter than me should probably check it. It does what I wanted but also uses deprecated code.

Anyway, I didn’t want to control this from my Player script - I wanted those animation states to manage themselves. I found info about StateMachinebehaviour - scripts that I can put directly in Animator. So I wasted few hours and this is my working solution:

public class StateSynchronizer : StateMachineBehaviour
{
    [SerializeField] string synchronizedTag;
    float stateTimeOffset = 0f;

    override public void OnStateExit(Animator animator, AnimatorStateInfo stateInfo, int layerIndex)
    {
        if (!string.IsNullOrEmpty(synchronizedTag) &&
            stateInfo.IsTag(synchronizedTag))
        {
            stateTimeOffset = stateInfo.normalizedTime % 1;
        }
    }

    override public void OnStateEnter(Animator animator, AnimatorStateInfo stateInfo, int layerIndex)
    {
        if (!string.IsNullOrEmpty(synchronizedTag) &&
            stateInfo.IsTag(synchronizedTag))
        {
            animator.ForceStateNormalizedTime(stateTimeOffset);
        }
    }
}

All you have to do is to put this script on base layer in animator and set synchronized tag name to something. Then set same tag name on animation states that script should synchronize. This will work only on animations that have exact same length.

This works but “ForceStateNormalizedTime” is throwing alert about being deprecated and proposes “Play” or “CrossFade” instead.
Problem is - both of those will create endless loop in animator because they will trigger OnStateEnter over and over again.

So yeah, if someone wants - this is my amateur solution. Works as intended but uses deprecated code.
If there is solution without use of deprecated commands, please feel free to correct this code.

Thanks again!

Hi there!

If I understood correctly what you want to achieve is something akin to Megaman, to do that is fairly simple actually if the animation isn’t that complicated and you won’t require code.

What you gotta do is use the Layers system of the Animator. Create a new layer and set it to something like this:

This will create a layer with the exact same animations as the Base Layer, replace the animations with the shooting animations and that’s it.

Now, unto coding, what you just gotta do is, when shooting, set the Weight of the Layer to 1, and when not shooting, set it to 0, that’s it.

If your shooting animation is more complicated, well, that’s gonna require a more sophisticated way, check this thread I wrote recently about how I achieved my shooting animation for my tilevania project.

Hope this helps.

If you need more help don’t hesitate to ask me directly, just be aware that I won’t be available for a couple of hours.

1 Like

Man. I was brainstorming so much for the last few hours and solution was so simple. :smiley:

Thanks Yee, yeah, animation is really simple (pretty much exactly like Megaman), I definitely should use this solution. Using layers didn’t even cross my mind even though I was looking at them all the time lol.

1 Like

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

Privacy & Terms