当其他动画正在播放时,如何防止我的动画启动?

How can I prevent my Animations from starting when the other animations are playing?

我试图让敌人攻击玩家,而敌人通过动画进行攻击,但是当其他人处于活动状态时我必须阻止动画启动的方法不起作用。该问题应显示为 this(可能是低质量)。如您所见,问题在于它不断打开和关闭布尔值。我不知道为什么会这样,因为我的方式应该有效。有没有办法阻止他们这样做并且 运行 一次一个有效?这是我的代码:

编辑:我忘记说了,但我的代码没有收到任何错误

public void AttackPlayer(GameObject playerPos, Animator anim, NavMeshAgent agent, GameObject self, bool MultiAttack, float inRange, float inView, float AttackRange, bool isBlocking, bool HasSeenPLayer)
    {
        distDif = Vector3.Distance(self.transform.position, playerPos.transform.position);

        if (distDif >= AttackRange)
        {
            agent.SetDestination(playerPos.transform.position);
            anim.SetBool("walk", false);
        }

        else if (distDif <= AttackRange)
        {
            anim.SetBool("walk", false);
        }

        MultAttack(playerPos, anim, agent, self, MultiAttack, inRange, inView);

        if (!MultiAttack)
        {
            anim.SetBool("Attack2", false);
            anim.SetBool("Attack3", false);
            StartCoroutine(PlayAnim(anim, "Attack"));
        }

        if (!PlayerPos.FindPlayerPos(AttackRange, playerPos.transform, inView, self, HasSeenPLayer))
        {
            anim.SetBool("Attack", false);
            anim.SetBool("Attack2", false);
            anim.SetBool("Attack3", false);
            state = State.Chase;
        }
    }

    private bool noloop = true;

    public void MultAttack(GameObject playerPos, Animator anim, NavMeshAgent agent, GameObject self, bool MultiAttack, float inRange, float inView)
    {
        if (!MultiAttack) return;

        if (random == 0) random = Random.Range(1, 5);

        if (random == 1)
        {
            StartCoroutine(PlayAnim(anim, "Attack"));
            random = 0;
            return;
        }

        if (random == 2)
        {
            if (HasParameter("Attack2", anim))
            {
                StartCoroutine(PlayAnim(anim, "Attack2"));
                random = 0;
                return;
            }

            StartCoroutine(PlayAnim(anim, "Attack"));
            random = 0;
            return;
        }

        if (random == 3)
        {
            if (HasParameter("Attack3", anim))
            {
                StartCoroutine(PlayAnim(anim, "Attack3"));
                random = 0;
                return;
            }

            StartCoroutine(PlayAnim(anim, "Attack"));
            random = 0;
            return;
        }

        if (random == 4)
        {
            BlockPlayer(playerPos, anim, agent, inRange, inView, self);
            random = 0;
            return;
        }

        StartCoroutine(PlayAnim(anim, "Attack"));
        random = 0;
        return;

    }

    public static bool HasParameter(string paramName, Animator animator)
    {
        foreach (AnimatorControllerParameter param in animator.parameters)
        {
            if (param.name == paramName)
                return true;
        }
        return false;
    }

 IEnumerator PlayAnim(Animator anim, string booleanName)
    {
        anim.SetBool(booleanName, true);
        yield return new WaitForSeconds(anim.GetCurrentAnimatorStateInfo(0).length + anim.GetCurrentAnimatorStateInfo(0).normalizedTime); 
        //^^^ this has a value I had debug.Log print the value and it has one value
        anim.SetBool(booleanName, false);
        
    } 

编辑 2:攻击函数是这样调用的:(在它自己的脚本中)

public void ChoseChasingWhatStateToAttackPlayer(NavMeshAgent agent, GameObject playerPos, GameObject Gself, Animator anim, bool MultiAttack, float inRange, float inView, float AttackRange, bool isBlocking, bool HasSeenPLayer)
    {
        switch (state)
        {
            case State.Chase:
                ChasePlayer(playerPos, Gself, anim, agent, AttackRange, inRange, inView, HasSeenPLayer);
                break;
            case State.Attack:
                AttackPlayer(playerPos, anim, agent, Gself, MultiAttack, inRange, inView, AttackRange, isBlocking, HasSeenPLayer);
                break;
            case State.Idle:
                IdlePlayer(playerPos, anim, agent, Gself, inRange, inView, HasSeenPLayer);
                break;
            case State.Wander:
                WanderPlayer(playerPos, anim, agent, Gself, HasSeenPLayer);
                break;
        }
    }

这是在主脚本中:

TtF.ChoseChasingWhatStateToAttackPlayer(agent, Player_pos.player, self, anim, MultiAttack, inRange, inView, AttackRange, isBlocking, hasSeenPlayer);
// called in update

我认为您的主要问题可能是您重复调用了 AttackPlayer() 函数。如果是这种情况(编辑:你更新了代码,看起来就是这种情况),那么它会重复调用 MultAttack() ,这会导致它每次都选择一个新的随机攻击动画来播放(可能是每次帧)。

我还发现了一些小问题,这些问题可能与此有关,但很难说:

From your code:

if (distDif >= AttackRange)
{
    agent.SetDestination(playerPos.transform.position);
    anim.SetBool("walk", false);
}

您确定要在此处将“行走”动画设置为 false 吗?

另一个:

Your code:

MultAttack(playerPos, anim, agent, self, MultiAttack, inRange, inView);

if (!MultiAttack)
{
    anim.SetBool("Attack2", false);
    anim.SetBool("Attack3", false);
    StartCoroutine(PlayAnim(anim, "Attack"));
}

即使变量 MultiAttack 为假,您仍在调用 MultAttack()。如果 MultiAttack 为假,而不是仅仅“撤消”您在 MultAttack() 中所做的一切,也许只是不调用它,除非 MultiAttack 为真?像这样:

if(MultiAttack)
{
    MultAttack(/*arguments here*/);
}
else
{
    //trigger single attack animation
}

我还强烈建议通过这些函数将所有这些数据作为单个对象或结构或其他东西传递。这看起来像是应该存储在“敌人”对象上的那种数据。拥有所有这些参数使得很难判断发生了什么并且很难组织。