【问题标题】:How can I prevent my Animations from starting when the other animations are playing?如何防止我的动画在其他动画播放时启动?
【发布时间】:2022-01-14 13:27:17
【问题描述】:

我试图让敌人攻击玩家并通过动画攻击敌人,但是当其他人处于活动状态时我必须阻止动画开始的方法不起作用。问题应该由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

【问题讨论】:

    标签: c# unity3d animation


    【解决方案1】:

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

    我还看到了一些可能造成影响但很难说的小问题:

    来自您的代码:

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

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

    另一个:

    您的代码:

    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
    }
    

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

    【讨论】:

    • 当你说我应该是一个“敌人”对象时,你的意思是这样的:public struck Enemy { public float health; public float speed; public Enemy(float health, float speed) { this.health = health; this.speed = speed; } } 抱歉,如果这是错误的,我不久前了解了结构,但我不太记得它们
    • 你会像这样初始化它:`Enemyenemy1 = new Enemy(health, speed);'
    • 是的,但在这种情况下使用类会更好。结构通常用于更“真实”对象的数据类型和类。我建议更多地了解 OOP 如何深入工作,看来你可能缺乏。但是,这是一个不同的问题,您可以在其他地方找到答案。先专注于解决这个问题,然后你可以重新组织一切。
    猜你喜欢
    • 2016-09-19
    • 2012-12-07
    • 2021-12-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-05-23
    • 2019-12-13
    相关资源
    最近更新 更多