4

我的一个同事写了一个我不完全理解的声明。不幸的是,他现在不可用,所以就在这里(名称已修改,我们正在 Unity 中开发一款游戏)。

private readonly int FRUIT_LAYERS =
          (1 << LayerMask.NameToLayer("Apple"))
        | (1 << LayerMask.NameToLayer("Banana"));

NameToLayer 接受一个字符串并返回一个整数。我总是看到左移运算符与右侧的常量整数一起使用,而不是左侧,并且我通过 Google 找到的所有示例都遵循这种方法。在这种情况下,我认为他将 Apple 和 Banana 推到了同一个相关层(稍后我将使用它进行过滤)。将来会有更多的“水果”可供过滤。任何出色的stackoverflowers可以给我解释这些行发生了什么?

4

4 回答 4

7

1 << x本质上是在说“给我一个数字,其中第 (x+1) 位为 1,其余数字均为零。

x | y是按位或,因此它将遍历从 1 到 n 的每个位,如果该位在其中一个中为 1,xy该位在结果中将为 1,否则将为 0。

因此,如果LayerMask.NameToLayer("Apple")返回2LayerMask.NameToLayer("Banana")返回,3那么FRUIT_LAYERS将是一个设置了第 3 位和第 4 位的数字,它是1100二进制的,或者以 10 为底的 12。

于 2013-04-05T17:13:58.517 回答
3

您的同事实际上是int在使用 a 代替 abool[32]来尝试节省空间。您显示的代码块类似于

bool[] FRUIT_LAYERS = new bool[32];
FRUIT_LAYERS[LayerMask.NameToLayer("Apple")] = true;
FRUIT_LAYERS[LayerMask.NameToLayer("Banana")] = true;

您可能需要考虑更像这样的模式:

[Flags]
enum FruitLayers : int
{
    Apple = 1 << 0,
    Banana = 1 << 1,
    Kiwi = 1 << 2,
    ...
}

private readonly FruitLayers FRUIT_LAYERS = FruitLayers.Apple | FruitLayers.Banana;
于 2013-04-05T17:15:43.043 回答
2

代码将二进制值 1 向左移动,要移动的二进制位数由 Apple 和 Banana 确定,在两个值移位后,以二进制方式进行 ORed

示例:假设 apple 返回 2,banana 返回 3,您将得到: 1 << 2 即 0100(十进制表示 4) 1 << 3 表示 1000(十进制表示 8)

现在 0100 按位或 1000 是 1100 这意味着 12

于 2013-04-05T17:15:16.343 回答
2

1 << n 基本上相当于 2 n

于 2013-04-05T17:15:49.957 回答