简体   繁体   中英

How do I make animation clips run one at a time and not blend together

I have 2D animations for look , walk , and attack -- each with 4 directions -- for a total of 12 animation clips. The animation controller has the following parameters:

  • facing (integer)
  • isMoving (boolean)
  • isAttacking (trigger)

I want only one clip to be playing at a time. It's working for the look and walk animations because those are mutually exclusive based on their parameters. The problem is the attack clip since that's based on a trigger. When I enter that state, it blends with the look or walk animation that is already playing. When I enter the attack animation, I want the current animation to stop and the attack animation to run to completion before the look or walk animation plays again.

Preferably, I want to do this by having transitions only go from Any State to each other state (no interstate transitions). I have a bunch of these animations for different characters and equipment, plus I'll have a few more types of animations beyond look/walk/attack in the future, so I'd like to avoid the complexity that'll come with adding a few dozen more transitions.

I thought about changing the isAttacking parameter from a trigger to a boolean, but that seems like a bad choice because then I'll have to have code and an animation event to keep track of my attack animation and set isAttacking to false when it's done playing, and that seems to add complexity and bloat to the system

You would have to connect all states in between each other ... that's like 66 transitions .. not a lot of fun .. because ... now add one transition spontainously :D

I mean you could do that and use HasExitTime = true; ExitTime = 1 HasExitTime = true; ExitTime = 1 for all transitions going out of attack states in order to wait for the animation to finish before transitioning - and for all others have HasExitTime = false in order to not wait but start the transiion directly.


But I would strongly recommend to rather use a little script and use a bool for isAttacking that would make your life a lot easier.

You can simply add a script ( StateMachineBehaviour ) to he attack states themselves (similar to components on GameObjects) where you wait until the animation finishes and reset the bool. Than you can leave all transitions on Any State and configure them how you want them.

When selecting a state in the animator window you will notice each state has an Inspector with the Add Behaviour button quite similar to GameObjects :

在此处输入图片说明

here create a new behaviour and simply do

using UnityEngine;

public class StopAttack : StateMachineBehaviour
{
    private float timePassed = 0;

    // OnStateUpdate is called before OnStateUpdate is called on any state inside this state machine
    // 
    // Unity's comment above sounds a bit confusing ... but
    // simply consider this the Update method of StateMachineBehaviours ;)
    public override void OnStateUpdate(Animator animator, AnimatorStateInfo stateInfo, int layerIndex)
    {
        timePassed += Time.deltaTime;

        // while timePassed is smaller than the animation clip's length
        // do nothing
        if (timePassed < stateInfo.length) return;

        // reset the bool
        animator.SetBool("isAttacking", false);
    }
}

Now for the smooth blending simply set the transitions to something like

  • HasExitTime = true
  • ExitTime = 0.75 (%)
  • TransitionDuration = 0.25 (seconds if FixedDuration , % otherwise)

depending on this transition duration etc you might also want the attack animation to reset the isAttacking a bit earlier like eg

if (timePassed < stateInfo.length - 0.25 * stateInfo.length) return;

EDIT Misread the question. You should be good to just set the transition duration in the transition settings in the inspector to 0.

In the animation controller: select the transition, go to the inspector, click the '-' symbol in the transitions list. You can also open the settings and change the transition if that is something you want with other animations.

在此处输入图片说明

Try adding an animation state into 8 corners instead of 4. So for example you may currently have 4 corners, UpRight, UpLeft, DownLeft, and DownRight, so when it goes to pick a state it picks a bit of 2 of them and doesnt know which one to stick with. Perhaps try adding nodes into the corners that are missing, like UP, DOWN, LEFT, RIGHT, and pick a relevant animation to fit.

I used this in my game and it seemed to at least get rid of the issue for now.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM