【问题标题】:Unity - if block is executed even when condition is falseUnity - 如果即使条件为假也执行块
【发布时间】:2017-04-19 04:11:47
【问题描述】:

这是我的代码:

void Update () {
    //------------ CHECKING "IF RUNNING" FOR ALL ACTIONS FROM LOCAL PLAYER ---------------------- 
    if (MatchManager.GetMMInstance().Running)
    {
        Debug.Log("I Am Running");
        // ---------- orbiting and sending it -------------
        //if (Input.GetKeyDown(KeyCode.D))
        ClockwiseOrbitButton.GetComponent<Button>().onClick.AddListener(() =>
        {
            if (ClockwiseOrbitPressPermit)
            {
                ClockwiseOrbitPressPermit = false;
                if (MatchManager.GetMMInstance().NearCabin.Local)
                {
                    // we send this before we start our orbit that maybe it compensate possibly delay of internet. also we send it once again in the end of continousorbit with speed value of zero.
                    Network.GetNetInstance().SendOrbit(1, MatchManager.GetMMInstance().NearCabin.Center.transform.rotation.eulerAngles, 1, InitialOrbitSpeed);
                    Orbit(1, MatchManager.GetMMInstance().NearCabin.Center.transform.rotation.eulerAngles, 1, InitialOrbitSpeed, BaseDeceleratorAmount);
                }
                else if (MatchManager.GetMMInstance().MidCabin.Local)
                {
                    // we send this before we start our orbit that maybe it compensate possibly delay of internet. also we send it once again in the end of continousorbit with speed value of zero.
                    Network.GetNetInstance().SendOrbit(2, MatchManager.GetMMInstance().MidCabin.Center.transform.rotation.eulerAngles, 1, InitialOrbitSpeed);
                    Orbit(2, MatchManager.GetMMInstance().MidCabin.Center.transform.rotation.eulerAngles, 1, InitialOrbitSpeed, BaseDeceleratorAmount);
                }
                else if (MatchManager.GetMMInstance().FarCabin.Local)
                {
                    // we send this before we start our orbit that maybe it compensate possibly delay of internet. also we send it once again in the end of continousorbit with speed value of zero.
                    Network.GetNetInstance().SendOrbit(3, MatchManager.GetMMInstance().FarCabin.Center.transform.rotation.eulerAngles, 1, InitialOrbitSpeed);
                    Orbit(3, MatchManager.GetMMInstance().FarCabin.Center.transform.rotation.eulerAngles, 1, InitialOrbitSpeed, BaseDeceleratorAmount);
                }
                StartCoroutine(ReactiveOrbit(OrbitCoolDown));
            }
        });
        //if (Input.GetKeyDown(KeyCode.A))
        CoClockwiseOrbitButton.GetComponent<Button>().onClick.AddListener(() =>
        {
            if (CoClockwiseOrbitPressPermit)
            {
                CoClockwiseOrbitPressPermit = false;
                if (MatchManager.GetMMInstance().NearCabin.Local)
                {
                    // we send this before we start our orbit that maybe it compensate possibly delay of internet. also we send it once again in the end of continousorbit with speed value of zero.
                    Network.GetNetInstance().SendOrbit(1, MatchManager.GetMMInstance().NearCabin.Center.transform.rotation.eulerAngles, 2, InitialOrbitSpeed);
                    Orbit(1, MatchManager.GetMMInstance().NearCabin.Center.transform.rotation.eulerAngles, 2, InitialOrbitSpeed, BaseDeceleratorAmount);
                }
                else if (MatchManager.GetMMInstance().MidCabin.Local)
                {
                    // we send this before we start our orbit that maybe it compensate possibly delay of internet. also we send it once again in the end of continousorbit with speed value of zero.
                    Network.GetNetInstance().SendOrbit(2, MatchManager.GetMMInstance().MidCabin.Center.transform.rotation.eulerAngles, 2, InitialOrbitSpeed);
                    Orbit(2, MatchManager.GetMMInstance().MidCabin.Center.transform.rotation.eulerAngles, 2, InitialOrbitSpeed, BaseDeceleratorAmount);
                }
                else if (MatchManager.GetMMInstance().FarCabin.Local)
                {
                    // we send this before we start our orbit that maybe it compensate possibly delay of internet. also we send it once again in the end of continousorbit with speed value of zero.
                    Network.GetNetInstance().SendOrbit(3, MatchManager.GetMMInstance().FarCabin.Center.transform.rotation.eulerAngles, 2, InitialOrbitSpeed);
                    Orbit(3, MatchManager.GetMMInstance().FarCabin.Center.transform.rotation.eulerAngles, 2, InitialOrbitSpeed, BaseDeceleratorAmount);
                }
                StartCoroutine(ReactiveOrbit(OrbitCoolDown));
            }

        });


        // ---------- Shooting and sending it ------ - - - - - - -

        ShootButton.GetComponent<Button>().onClick.AddListener(() =>
        {
            if (ShootPressPermit)
            {
                ShootPressPermit = false;
                if (MatchManager.GetMMInstance().NearCabin.Local)
                {
                    // we send this before we Shoot, maybe it compensate possibly delay of internet.
                    Network.GetNetInstance().SendProduceBullet(1);
                    Shoot(1);
                }
                else if (MatchManager.GetMMInstance().MidCabin.Local)
                {
                    // we send this before we Shoot, maybe it compensate possibly delay of internet.
                    Network.GetNetInstance().SendProduceBullet(2);
                    Shoot(2);
                }
                else if (MatchManager.GetMMInstance().FarCabin.Local)
                {
                    // we send this before we Shoot, maybe it compensate possibly delay of internet.
                    Network.GetNetInstance().SendProduceBullet(3);
                    Shoot(3);
                }
                StartCoroutine(ReactiveShooting(MatchManager.GetMMInstance().LocalShootCoolDown));
            }
        });

        // ------------------ switching target and send it ----------------

        SwitchTargetButton.GetComponent<Button>().onClick.AddListener(() =>
        {
            if (SwitchTargetPressPermit)
            {
                SwitchTargetPressPermit = false;
                if (MatchManager.GetMMInstance().NearCabin.Local)
                {
                    // we send this before we Switch, maybe it compensate possibly delay of internet.
                    Network.GetNetInstance().SendSwitchTarget(1);
                    SwitchTarget(1);
                }
                else if (MatchManager.GetMMInstance().MidCabin.Local)
                {
                    // we send this before we Switch, maybe it compensate possibly delay of internet.
                    Network.GetNetInstance().SendSwitchTarget(2);
                    SwitchTarget(2);
                }
                else if (MatchManager.GetMMInstance().FarCabin.Local)
                {
                    // we send this before we Switch, maybe it compensate possibly delay of internet.
                    Network.GetNetInstance().SendSwitchTarget(3);
                    SwitchTarget(3);
                }
                StartCoroutine(ReactiveSwitchTarget(SwitchTargetCoolDown));
            }
        });

        //-----------------------  END OF ACTION SCOPE -----------------------------

        // ----------------- WAITING AND CHECKING SOME EVENT -----------------------
        // ** these events can happen only during running state

        WaitingForCrippling();

        // ---------------------- END OF WAIT AND CHECK ----------------------------
    }

    // --------------- SOME CONTINUOUS UPDATING METHODS ---------------------
    // these actions don't need to be in running block and don't depend on running state. can happen in any moments. 
    UpdateTargetPosition();
    Debug.Log(MatchManager.GetMMInstance().Running.ToString());
}

当场景运行时,“Running”值会在几秒钟内变为“false”,然后它会变为“true”。它将一直保持这种状态,直到玩家的生命值变为 0,此时它将再次变为“false”(这是一个多人游戏,有 3 名玩家)。

if 块包含一些在按下 UI 按钮时运行的代码。在开始时“正在运行”为假的那几秒钟,一切正常(按下按钮不起作用)。

当它变为 true 时,它​​再次正常工作(按下按钮将遵循正确的操作)。但是,当玩家的生命值达到 0 并且“Running”变量变为“false”时,我仍然可以按下按钮以及动作和事件 还会发生!

我不知道问题是什么。我将Debug.Log("I Am Running");Debug.Log(MatchManager.GetMMInstance().Running.ToString()); 放入代码中,正如您所见并观察每帧“Running”变量的值。

我已经看到它是“假”的,按下按钮仍然会执行诸如环绕和切换目标之类的操作!

【问题讨论】:

  • if(MatchManager.GetMMInstance().Running==true){} 用这个检查
  • 你能有一个竞争条件,在方法开始时Runningtrue,但到最后更改为falseGetMMInstance 也只是返回一个本地字段还是首先创建/改变返回值?
  • @Joji Thomas Eapen:检查过。但还是一样。
  • @juharr:非常抱歉。我想也许我听到了“比赛条件”,但我不知道它是什么?(请注意,跑步在“少数”地方发生了变化:1)当玩家的健康状况达到 0 时,它变为“假””(由“WaitingForCrippling();”你可以在我的代码底部看到。(运行不会通过更新中的任何东西变为真。(很确定)2)它在匹配结束时在另一个脚本中变为假。3)它仅在 Start() 处更改为“true”一次,其他任何地方都没有。此外,关于“GetMMInstance”,它是一个单例,我在代码中的许多地方都使用它,到目前为止它运行良好。

标签: c# android unity3d unity5


【解决方案1】:

您需要保存所有按钮的操作 (Events.UnityAction) 并在“正在运行”为 false 时将其删除,即:

void Update () {
//------------ CHECKING "IF RUNNING" FOR ALL ACTIONS FROM LOCAL PLAYER ---------------------- 
    if (MatchManager.GetMMInstance().Running)
    {
        //...your previous code
        //save references to Events.UnityActions
    } 
    else
    {
        ClockwiseOrbitButton.GetComponent<Button>().onClick.RemoveListener(referenseToTheAction1);
        CoClockwiseOrbitButton.GetComponent<Button>().onClick.RemoveListener(referenseToTheAction2);

        // etc.; remove all Events.UnityAction listeners from other buttons.
    }
}

或者您可以为每个按钮调用else 语句SomeButton.GetComponent&lt;Button&gt;().onClick.RemoveAllListeners();,而无需保存对Events.UnityActions 的引用。

【讨论】:

  • 嘿谢尔盖,我想你真的不知道有多少......但我非常爱你。我在这个问题上挣扎了几天。并且经常睡在笔记本电脑前的桌子上。现在你帮我回来工作了。非常感谢。
  • Armamedia,很高兴为您提供帮助。
  • @Armamedia,如果对您有帮助,请您标记答案,谢谢。
  • 我试过了,当我意识到它很有帮助时,但这个错误:感谢您的反馈!声望低于 15 人的投票将被记录,但不会更改公开显示的帖子分数。 ?!
【解决方案2】:

当您为按钮添加 onClick 侦听器时按下按钮时发生该操作是正常的,该按钮将始终执行您在侦听器中指定的操作。

如果你想让它停止,你应该在你的值为 false 时移除监听器。您可以使用 RemoveAllListeners. 将它们全部删除

添加点击侦听器的意义在于,您只需指定一次按钮点击应该执行的操作,并且每次按钮点击都会执行完全相同的操作。


我建议您只在启动函数中添加一次 onClick 侦听器,当您需要按钮停止工作时,您可以禁用该按钮。这样你就不会总是在每一帧都设置一个新的 onClick 监听器。

要禁用该按钮,您可以将 interactable property 设置为 false

ClockwiseOrbitButton.GetComponent<Button>().interactable = false;

然后,当您需要再次交互时,您可以随时将其设置回true

ClockwiseOrbitButton.GetComponent<Button>().interactable = true;

【讨论】:

  • 您的解释对我的新项目帮助很大。我希望我可以标记答案。你对这个项目更有帮助。
  • @Armamedia 没关系,别担心,我很高兴能为您提供帮助。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-03-05
  • 2019-04-05
相关资源
最近更新 更多