【问题标题】:Coroutine is not running code correctly the second time it is called协程第二次调用时没有正确运行代码
【发布时间】:2021-09-25 23:28:12
【问题描述】:

我仍在学习编码,所以希望这很容易解决。我正在尝试制作基于回合的 RPG,但我的协程遇到了问题。

我使用这些来移动角色,并且它在第一次(第 1 回合)时起作用,无论我选择攻击 1 还是攻击 2。但是,当玩家用尽他的团队回合时,敌人会攻击然后它的玩家再次转身。

当我此时尝试使用攻击时,角色会永远原地不动。不知道问题出在哪里,但很明显协程一直运行到它遇到第一个 while 循环,因为它就在运行动画触发 animator.SetBool("Run", true) 之后。

第一个协程用于基本攻击,第二个协程用于特殊攻击。 enemyPos 存储了敌人位置的 Vector3,它来自另一个脚本。

我正在研究协程,但发现许多相互矛盾的信息。例如,协同程序不能同时运行,但它是一个回合制游戏,每个字符每回合只能运行一次(所有字符都使用相同的脚本),所以我不确定问题出在哪里。

我正在为 Unity 编写 C#。

抱歉小说哈哈,为你的帮助喝彩。

 IEnumerator Movement()
    {
        if (moving)
        {

            if (isAttacking == true)
            {
                animator.SetBool("Run", true); //Begin run

                if (base_Char.ranged == false)
                {
                    
                    while (transform.position != enemyPos)
                    {
                        transform.position = Vector3.MoveTowards(transform.position, enemyPos, base_Char.speed * Time.deltaTime);

                        yield return null;
                    }

                    animator.SetBool("Run", false); //End run when location reached

                }

                else if (base_Char.ranged == true)
                {
                    Vector3 stepForward = new Vector3(transform.position.x + 2f, transform.position.y, transform.position.z); //For ranged attackers

                    while (transform.position != stepForward)
                    {
                        transform.position = Vector3.MoveTowards(transform.position, stepForward, base_Char.speed / 2 * Time.deltaTime);
                        yield return null;
                    }

                    animator.SetBool("Run", false);

                }

                //TEMPORARY to check if their is an animator on enetity
                if (GetComponent<Animator>() != null)
                {
                    animator.SetTrigger("BasicATK"); //Enable Basic attack trigger
                }

                yield return new WaitForSeconds(1.5f);
                BasicAttack(enemyPos);


            }



            else if (isAttacking == false)
            {
                animator.SetBool("Run", true); //Begin run

                while (transform.position != startingPos)
                {
                    transform.position = Vector3.MoveTowards(transform.position, startingPos, base_Char.speed * 2 * Time.deltaTime);
                    yield return null;
                }

            }

            animator.SetBool("Run", false); 
            moving = false; //Stop Update, used when testing with Update()
            base_Char.turnOver = true;
            base_Char.RunTurnCheck();

        }

    }


IEnumerator MoveChar(string movement)
    {
        if (movement == "Enemy")
        {
            while (transform.position != enemyPos)
            {
                transform.position = Vector3.MoveTowards(transform.position, enemyPos, base_Char.speed * 1.5f * Time.deltaTime);

                yield return null;
            }

        }

        if (movement == "Middle")
        {
            Vector3 target = new Vector3(0, 2, transform.position.z);

            while (transform.position != target)
            {
                transform.position = Vector3.MoveTowards(transform.position, target, base_Char.speed * Time.deltaTime);

                yield return null;
            }

        }

        if (movement == "StepForward")
        {
            Vector3 target = new Vector3(transform.position.x + 1f, transform.position.y, transform.position.z);

            while (transform.position != target)
            {
                transform.position = Vector3.MoveTowards(transform.position, target, base_Char.speed * Time.deltaTime);

                yield return null;
                
            }

        }

        base_Char.turnOver = true;
        base_Char.RunTurnCheck();

        yield return new WaitForSeconds(2f);

        while (transform.position != base_Char.startingPos)
        {
            transform.position = Vector3.MoveTowards(transform.position, base_Char.charPos.transform.position, base_Char.speed * 2 * Time.deltaTime);

            yield return null;
        }
    }

【问题讨论】:

    标签: c# unity3d coroutine


    【解决方案1】:

    我可能需要更多信息,例如 base_Char.RunTurnCheck(); 的作用是什么?功能做什么?你的更新功能是什么样的?

    但是,我的建议是制作一个状态机,而不是通过单个类运行所有内容。您可以创建一个状态类,在其中编写所有特定行为,然后将其传递到状态机以供其执行,这将大大提高您的可扩展性。

    【讨论】:

      猜你喜欢
      • 2018-10-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-10-26
      相关资源
      最近更新 更多