我们有一个变量a
,为了进行for循环,它是通过函数WhatIsA()
计算出来的。 WhatIsA
的值是已知的编译时。有什么我可以做的(也许是属性吗?)让编译器知道它可以擦除变量并在所有引用中放置常量?
for (int i = 0; i < 1343434; i++)
{
int a = WhatIsA(); //retval of WhatIsA does not change after compilation, ever.
DoSomethingWithVariableA(a);
DooooSomethingWithVariableA(a);
DoooooooSomethingWithVariableA(a);
}
最初的问题来自Unity的环境。
private void Update()
{
LayerMask mask = LayerMask.GetMask("Terrarin");
CollidesBottom = Raycast((Vector2)transform.position + colliderBottomLeftOffset, Vector2.right, colliderWidth, mask);
CollidesTop = Raycast((Vector2)transform.position + colliderTopRightOffset, Vector2.left, colliderWidth, mask);
CollidesRight = Raycast((Vector2)transform.position + colliderTopRightOffset, Vector2.down, colliderHeight, mask);
CollidesLeft = Raycast((Vector2)transform.position + colliderBottomLeftOffset, Vector2.up, colliderHeight, mask);
}
GetMask
是已知的或至少应该是编译时。编译器可能会或可能不会对其进行优化。我唯一能做的就是将掩码提升为字段变量,然后在Start
函数中对其进行计算,但是它的作用域超出了需要。
答案 0 :(得分:0)
在a
或Start()
内设置Awake()
并引用变量。
答案 1 :(得分:0)
您可以查看this thread,以获取有关LayerMasks如何工作的更深入的解释。
简而言之:LayerMask基本上是一个int值。它代表一个二进制的32位标记系统,您可以在其中打开(1
)和关闭(0
)某些层索引。所以例如值
0000 0000 0000 0000 0000 0000 0000 0101
| |
| |layer1
|
|layer3
意味着应该启用layer1和layer3,并且十进制的值为5
。
因此,当然有一些选项可以使该图层掩码保持不变。最简单的方法是一次输出
LayerMask mask = LayerMask.GetMask("Terrarin");
Debug.Log(mask.value);
这将为您提供图层蒙版的十进制表示形式。而且比起您可以简单地使用
// 256 e.g. is the layer9
// the first entry after Unity's 8 default layers
LayerMask mask = 256;
或者如果您已经知道所需图层的索引,也可以简单地使用
LayerMask mask = 1 << 9;
或使用那些Binary -> Decimal converter和Decimal -> Binary converter
当然,您也只能在Update
中这样做,但是为什么要在每一帧都重新创建它呢?如果仍要对其进行硬编码,则也可以使用const
或如其他答案中所述,只需在Awake
中获得一次值即可。
我也不理解您对“范围”的担忧。只要它保持私有状态就没关系
..相反:您的Update
解决方案一次又一次地分配和销毁mask
-> GC的更多工作。
这是一个非常糟糕的设计选择,原因有二:
后来的设计更改,您将不得不更改代码。您重命名必须更改代码的图层。您想在必须先重新计算值之后,再向蒙版添加一个图层。等等...
它使您的代码0%灵活且可重复使用!想象一下,您现在已经完成了Raycaster系统。现在,您希望场景中的另一个对象在不同的图层上进行光线投射...因此,您是希望复制整个脚本只是为了更改硬编码图层(我希望不是),还是希望使用相同的脚本并简单地更改图层值。
因此,实际上,我认为最好的解决方案是完全从不硬编码层名称/索引/掩码,而是让开发人员在检查器中对其进行调整。您仍然可以通过以下方式为它提供一个硬编码的默认值:
[SerializeField] private LayerMask mask = 256;
这在检查器中为您提供了一个字段,您可以在其中轻松选择图层。您甚至可以出于调试原因在运行时更改它们。