将 bool 设置为 false VS 在设置之前检查它是否已经为 false

发布于 2025-01-10 14:35:20 字数 358 浏览 3 评论 0原文

我知道这可能是过度优化,但我仍然想知道什么是更好的。

所以让我们添加一些背景信息。 我正在 Unity 上开发一款游戏,它使用 C# 编写游戏脚本,并且 Unity 制定了在游戏的每一帧运行的方法。 对于我正在开发的游戏,我在代码中使用触发器。它们是简单的布尔值,以 false 开头。当游戏中发生特定事件时,特定触发器将设置为 true,将立即激活事件并再次设置为 false。这一切都发生在一个帧中。

所以这意味着在每一帧结束时我必须将触发器重置为 false。 这就是我的疑问所在。我应该将所有触发器设置为 false,与它们的当前值无关,还是应该添加 IF 条件来检查它们是否尚未为 false?

I know that this may be over-optimizationbut still I'd like to know what's better.

So let's add a bit of context.
I'm working on a game on Unity which uses C# to write the game scripts and there are methods made by Unity that run at every frame of the game.
For the game I'm working on I'm using triggers in my code. They are simple bool values that start as false. When something specific happens in the game the specific trigger will be set to true, will activate an event instantaneously and be set to false again. This all happens in a single frame.

So it means that at the end of every frame i have to reset my triggers to false. This is where my doubt is. Should I just set all the triggers to false indifferently to their current value or should I add an IF condition to check if they aren't already false?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

往日情怀 2025-01-17 14:35:20

一般来说,我建议您在设置之前检查布尔值。我没有任何关于哪个性能更高的数据,但它具有功能优势。如果您正在使用字段,检查和设置布尔值没有副作用。但是,如果您正在使用属性,则 getter 和 setter 可能会产生一些副作用,如果您每帧都设置它们,可能会导致不良行为。如果您只是使用该布尔值,则并不总是立即清楚您正在使用字段还是属性。

我建议您不要在 Update 方法中使用标志布尔值。 Update 方法应该只执行对象处于活动状态时必须执行的操作。我假设您有一些代码在发生某些情况时设置标志,并且在您的 Update 方法中执行某些操作,直到满足另一个条件并重置该标志。

// This is my flag variable.
public bool isCounting;
public int maximum;
private int _currentCount;

private void Update()
{
    if (IsConditionMet()) {
        // Should I check if isCounting is already false before setting?
        isCounting = false;
    }

    if (isCounting) {
        DoWork();
    }
    else
    {
        return;
    }
}

private bool IsConditionMet()
{
    return _currentCount >= maximum;
}

private void DoWork()
{
    _currentCount++;
}

当某些其他代码将标志 isCounting 设置为 true 时,_currentCount 将增加,直到达到最大值并停止计数。计数开始时恰好有一帧,计数停止时正好一帧。在所有其他帧期间,Update 方法检查标志变量并且不执行任何其他操作。

相反,您可以使用协程并调用方法:

public void StartCounting()
{
    StartCoroutine(Count());
}

private IEnumerable Count()
{
    while (!IsConditionMet())
    {
        DoWork();
        yield new WaitForSeconds(1);
    }
}

此代码公开了一个名为 StartCounting 的公共方法。要开始计数,您可以调用 StartCounting,而不是设置公共字段 isCounting。然后,该方法启动一个在 Update 代码外部执行的协程。协程 Count 检查条件是否满足,如果不满足则继续工作。完成工作后,协程会等待一秒钟并再次尝试,直到 _currentCount 达到最大值。这样,您就不必担心检查和设置标志值,而是调用 StartCounting 方法一次并让它工作直到完成。

Generally speaking, I suggest you check a boolean before setting it. I don't have any data on which is more performant, but it has a functional advantage. If you're working with a field, checking and setting a boolean value has no side effects. However, if you're working with a property, the getter and setter can have some side effects that can lead to unwanted behaviour if you set them every frame. It's not always immediately clear if you're working with fields or properties if you're just using that boolean.

I would advise you not to use flag booleans inside the Update method. The Update method should only do things that have to be done whenever the object is active. I assume you have some code that sets the flag if something happens and in your Update method you do something until another condition is met and you reset that flag.

// This is my flag variable.
public bool isCounting;
public int maximum;
private int _currentCount;

private void Update()
{
    if (IsConditionMet()) {
        // Should I check if isCounting is already false before setting?
        isCounting = false;
    }

    if (isCounting) {
        DoWork();
    }
    else
    {
        return;
    }
}

private bool IsConditionMet()
{
    return _currentCount >= maximum;
}

private void DoWork()
{
    _currentCount++;
}

When some other code sets the flag isCounting to true, _currentCount will be increased until it hits the maximum and stops counting. There is exactly one frame when the counting starts and one frame when the counting stops. During all other frames, the Update method checks the flag variable and does nothing else.

Instead you could be working with coroutines and calling methods:

public void StartCounting()
{
    StartCoroutine(Count());
}

private IEnumerable Count()
{
    while (!IsConditionMet())
    {
        DoWork();
        yield new WaitForSeconds(1);
    }
}

This code exposes a public method called StartCounting. To start counting, you call StartCounting instead of setting the public field isCounting. The method then starts a coroutine that executes outside of the Update code. The coroutine Count checks if the condition is met and continues to do work if not. When it's done working, the coroutine waits for a second and tries again until _currentCount reaches maximum. This way, you don't have to worry about checking and setting a flag value and instead call the StartCounting method once and let it work until it finishes.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文