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

标签 c# unity3d animation

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

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

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 为 false,您也在调用 MultAttack()。如果 MultiAttack 为假,而不是仅仅“撤消”您在 MultAttack() 中所做的一切,也许只是不要调用它,除非 MultiAttack 为真?像这样:

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

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

关于c# - 当其他动画正在播放时,如何防止我的动画启动?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/70294594/

相关文章:

c# - 如何安全地保存用户名/密码(本地)?

c# - 我可以将构造函数参数传递给 Unity 的 Resolve() 方法吗?

c# - 查找所有集合中字段的最大值

node.js - 在游戏中同步 NPC 行为。使用 socket.io/node.js。 Unity2D

jquery - 使用.each(),如何等待动画结束?

c# - 将 Google API 离线访问添加到 .NET Core 应用程序

c# - 用于引用公共(public)属性的静态实例和枚举

audio - Unity-为什么我无法通过脚本播放所需的声音?

objective-c - iPhone 模态视图动画帮助

objective-c - 使用 UIScrollView subview 调整 UIView 的大小