为什么我的协程不能运行多次?

问题描述 投票:0回答:1

在我的游戏中,玩家可以拾取的能量提升,首先检查角色是否已经能量提升。如果没有,那么它会启动名为“FireBreathing”的协程来处理加电的效果。如果它们已经通电,我想停止协程并重新启动它,以免多个相同的协程重叠。

我这里的东西在我看来应该有效,但事实并非如此。它将像平常一样通过协程播放,但是当它完成时(通过等待协程完成,或者通过再次通电来重新启动循环),协程将不会再次启动。

type herepublic class StrawbiliEffect : MonoBehaviour
{
    [SerializeField] float strawbiliMoveSpeed = 5f;
    [SerializeField] float strawbiliJumpForce = 12f;
    [SerializeField] float strawbiliDuration = 3f;

    public bool isStrawbiliBoy;
    IEnumerator coroutine;
    
    AltPlayerController playerController;
    Animator animator;

    void Start() 
    {
        playerController = GetComponent<AltPlayerController>();
        coroutine = FireBreathing();
    }

    public void StrawbiliPowerUp()
    {
        Debug.Log("Function Called");
        if (isStrawbiliBoy == false)
        {
            StartCoroutine(coroutine);
        }
        else if (isStrawbiliBoy == true)
        {
            StopCoroutine(coroutine);
            Debug.Log("Coroutine stop attempted");
            StartCoroutine(coroutine);
        }
    }

    IEnumerator FireBreathing()
    {
        Debug.Log("Coroutine has started");
        isStrawbiliBoy = true;
        playerController.isNormalGerm = false;
        playerController.moveSpeed = strawbiliMoveSpeed;
        playerController.jumpForce = strawbiliJumpForce;
        //animator.SetBool ("isStrawbiliBoy", true);
        yield return new WaitForSeconds (strawbiliDuration);
        //animator.SetBool ("isStrawbiliBoy", false);
        playerController.isNormalGerm = true;
        playerController.moveSpeed = playerController.normalMoveSpeed;
        playerController.jumpForce = playerController.normalJumpForce;
        isStrawbiliBoy = false;
        Debug.Log("Coroutine has finished");
    }
}

我开始收集电源,控制台打印出“调用的函数”,所以我知道拾取方法仍然可以正常工作。我已检查以确保所有布尔变量都切换回正确的状态。我只是不知道出了什么问题。

c# unity-game-engine coroutine ienumerator
1个回答
0
投票

问题是,在第二次调用之前,coroutine.MoveNext() 将返回 false。由于 IEnumerator 已到达末尾。

简而言之,您需要稍微不同地使用它。

public class StrawbiliEffect : MonoBehaviour
{
    [SerializeField] float strawbiliMoveSpeed = 5f;
    [SerializeField] float strawbiliJumpForce = 12f;
    [SerializeField] float strawbiliDuration = 3f;

    public bool isStrawbiliBoy;
    
    // CHANGED.
    Coroutine coroutine;
    
    AltPlayerController playerController;
    Animator animator;

    void Start() 
    {
        playerController = GetComponent<AltPlayerController>();
        coroutine = FireBreathing();
    }

    // CHANGED.
    public void StrawbiliPowerUp()
    {
        Debug.Log("Function Called");
        if (isStrawbiliBoy == false)
        {
            if (coroutine != null) StopCoroutine(coroutine);
            coroutine = StartCoroutine(FireBreathing());
        }
        else if (isStrawbiliBoy == true)
        {
            if (coroutine != null) StopCoroutine(coroutine);
                Debug.Log("Coroutine stop attempted");
            coroutine = StartCoroutine(FireBreathing());
        }
    }

    IEnumerator FireBreathing()
    {
        Debug.Log("Coroutine has started");
        isStrawbiliBoy = true;
        playerController.isNormalGerm = false;
        playerController.moveSpeed = strawbiliMoveSpeed;
        playerController.jumpForce = strawbiliJumpForce;
        //animator.SetBool ("isStrawbiliBoy", true);
        yield return new WaitForSeconds (strawbiliDuration);
        //animator.SetBool ("isStrawbiliBoy", false);
        playerController.isNormalGerm = true;
        playerController.moveSpeed = playerController.normalMoveSpeed;
        playerController.jumpForce = playerController.normalJumpForce;
        isStrawbiliBoy = false;
        Debug.Log("Coroutine has finished");
    }
}
© www.soinside.com 2019 - 2024. All rights reserved.