微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

带有无法工作的布尔值的循环计时器 Unity 3D

如何解决带有无法工作的布尔值的循环计时器 Unity 3D

使用 c#,我试图每 3 秒发射一次子弹,所以这是我的工作流程:

  1. 按下开火按钮
  2. 仅当 bool fireAgain 为 true 时才触发
  3. set bool fireAgain = false
  4. 启动计时器
  5. 计时器完成 = bool fireAgain = true

调试时似乎一切正常,但当我测试时,我仍然可以每秒射击 10 发子弹。所以不知何故,它只是不关心 bool FireAgain 是假的,即使根据 debug bool fireAgain 在那一刻是假的,它仍然会射击。

 public void Update()
    {
    //If  LEFT MouseButton is pressed,cast yer spells.
            if (fireAgain == true && Input.GetMouseButtonDown(0)) 
    {   
        StartCoroutine("LoopRotation");
        fireAgain = false;
        Debug.Log(fireAgain);
        Debug.Log("1 should be FALSE");
    }
        while (fireAgain == false && timer < bulletTime)
    {
        fireAgain = false;
        timer += Time.deltaTime;
        Debug.Log(timer);
        Debug.Log(bulletTime);
        Debug.Log(fireAgain);
        Debug.Log("2");
    } if (timer >= bulletTime)
    {
        fireAgain = true;
        timer = 0;
        //Debug.Log("Timer is finished");
        //Debug.Log(timer);
        Debug.Log(fireAgain);
        Debug.Log("3 should be true");
        

这是协程的代码

IEnumerator LoopRotation()
{
    pivot.transform.Rotate(triggerAngle,0);
        
        GameObject bullet = ObjectPooler.SharedInstance.GetPooledobject(); 
        if (bullet != null) {
                bullet.transform.position = sspawn.transform.position;
                bullet.transform.rotation = sspawn.transform.rotation;
                bullet.SetActive(true);
         }

    yield return new WaitForSeconds(.1f);
            pivot.transform.rotation = Quaternion.Slerp(transform.rotation,originalRotationValue,Time.deltaTime * rotationResetSpeed); 
    StopCoroutine("LoopRotation");
}

Enumerator LoopRotation 最初只是将武器向前旋转几度,然后向后旋转几度,这样当你施放咒语时它看起来就像一个怪人,但现在它也是射击功能,因为它会产生子弹。

解决方法

您在 while 中有一个 Update 循环 => 此循环将在 单帧 中完全运行 => “立即”将增加 timer 直到它足够大 =>“立即”将您的 bool 标志再次设置为 true

你更愿意做的是例如

public void Update()
{
    //If  LEFT MouseButton is pressed,cast yer spells.
    if (fireAgain && Input.GetMouseButtonDown(0)) 
    {   
        StartCoroutine(LoopRotation());
        fireAgain = false;
        timer = 0;
        Debug.Log(fireAgain);
        Debug.Log("1 should be FALSE");
    }
    else if(timer < bulletTime)
    {
        // Only increase this ONCE per frame
        timer += Time.deltaTime;
        Debug.Log(timer);
        Debug.Log(bulletTime);
        Debug.Log(fireAgain);
        Debug.Log("2");

        if(timer >= bulletTime)
        {
            fireAgain = true;
            timer = 0;
            //Debug.Log("Timer is finished");
            //Debug.Log(timer);
            Debug.Log(fireAgain);
            Debug.Log("3 should be true");
        }
    }
}

作为替代方案,您可以使用 Invoke 并完全跳过 Update 中的计时器:

public void Update()
{
    //If  LEFT MouseButton is pressed,cast yer spells.
    if (fireAgain && Input.GetMouseButtonDown(0)) 
    {   
        StartCoroutine(LoopRotation());
        fireAgain = false;
        Invoke (nameof(AllowFireAgain),bulletTme);
    }
}

private void AllowFireAgain()
{
    fireAgain = true;
}

请注意,您的协程对我来说没有多大意义。您只旋转了一次,而且旋转的次数非常少。

最后的 StopCoroutine 是不必要的。


另请注意:为了调试良好,但稍后您应该避免让 Debug.Log 在构建的应用程序中运行每一帧。即使用户没有看到它,日志仍会被创建到播放器日志文件中,并导致相当多的开销。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。