【问题标题】:While loop timer with a bool that doesnt work Unity 3DWhile 循环计时器带有一个不起作用 Unity 3D 的布尔值
【发布时间】:2021-02-20 15:39:44
【问题描述】:

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

  1. 按下触发按钮
  2. 只有当 bool fireAgain 为真时才会触发
  3. 设置 bool fireAgain = false
  4. 启动计时器
  5. 计时器完成 = bool fireAgain = true

调试时似乎一切正常,但是当我测试它时,我仍然可以每秒发射 10 发子弹。所以不知何故,它只是不关心 bool FireAgain 是否为假,并且无论如何都会拍摄,即使根据调试 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,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 最初只是将武器向前旋转几度,然后向后旋转几度,所以当你施法时它看起来像个怪人,但现在它也是射击功能,因为它会产生子弹。

【问题讨论】:

    标签: c# unity3d 3d frame-rate


    【解决方案1】:

    你在Update 中有一个while 循环 => 这个循环将在单帧 中完全运行 => “立即”将增加 timer 直到它足够大 => “立即”会将您的布尔标志再次设置为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 运行每一帧。即使用户看不到它,日志仍然会创建到播放器日志文件中,并会导致相当多的开销。

    【讨论】:

    • 这很有意义!感谢你及时的答复!它总是那么简单,哈哈,但至少在尝试 3 小时后很容易解决。
    • 我试图将这个确切的代码复制到 Input.GetMouseButton(0),所以它被按住而不是被点击,但是当测试 ti 根本不发射任何子弹时,我将计时器更改为timerH,使它成为“else if”语句。以前没有计时器的时候可以正常工作,但是子弹之间没有延迟,以前按住它时只是源源不断的子弹流,但是现在按住鼠标按钮只产生1颗子弹然后它停止了,所以它注册了一次点击,但不知道当它被按住时该怎么做......
    • @eriksprogram 在这种情况下,删除else 并使其成为一个单独的if 块,如if(!fireAgain &amp;&amp; timer &lt; bulletTime) .. 否则在按下按钮时将永远不会调用第二个块;) 还要注意使用 Invoke 的替代方法 .. 对于 GetMouseButtonDownGetMouseButton 应该使用相同的方法
    • 好吧,我会试试的,谢谢,使用 Invoke 似乎更容易,我想知道它是否比 deltaTime 更准确,因为那非常不准确。
    猜你喜欢
    • 2015-05-24
    • 2017-06-04
    • 2011-08-01
    • 1970-01-01
    • 2021-10-04
    • 2020-10-05
    • 2017-11-20
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多