2

下面的代码部分让我有点疯狂

  public static readonly float f = 1.25f;
  public static void init(){
     Debug.Log(f); // output: 1.25f
     FLIPPER_CENTERS = new float[,] { 
           { (20*f), (27*f) },    { FLIPPER_WIDTH - (20*f), (27*f)},
           { (6*f), (25*f) },     { MH_FLIPPER_WIDTH- (6*f), (25*f) },
           { (8), (15)},          { (SMALL_FLIPPER_WIDTH - 8), (15)},
           { (8), (20)},          { (67 - 8), (20)},
     };
     Debug.Log(FLIPPER_CENTERS[0,0]); // output: 0, expected 25;
  }

如果我打印该数组的第一个元素的值,我会得到[0, 0]. [59, 20]正如预期的那样,最后两个元素是。

第一个值应该是[25, 33,75]。如果我代替(20*f).(20*1.25f)

        { (20*1.25f), (27*1.25f) },    { FLIPPER_WIDTH - (20*f), (27*f)},

所以这是问题所在:如果我在数组初始化中保留 f 的乘法,则值为 0。但是,如果我更改f1.25fall 是好的。

我试图弄清楚发生了什么,但无济于事。我确定fis1.25f和 not的值0。任何人都可以为我解释一下吗?

编辑:

为了证明f不是0,我尝试20/f了第一个元素。那没有抛出异常,输出仍然是0.

部分解决方案

f从更改readonlyconst解决问题。但是,我真的很想知道为什么会这样。

  public const float f = 1.25f;

这一切都在 Unity 中运行,可能与它有关。

4

1 回答 1

2

我看到这个问题被标记为 Unity3D。

是否有可能f是一个公共变量,可以在 Unity 编辑器中对其进行修改?如果是这样,编辑器中设置的任何值都将覆盖变量声明期间代码中设置的值。声明期间设置的值仅用作 Unity 编辑器的默认值。

如果是这种情况,那么有人可能f在编辑器中设置为 0,导致在您进行数学运算时它为 0。


经过一些测试后编辑的答案:2013 年 8 月 22 日

使用 Unity 时,我能够重复您的问题。Unity 中似乎存在一个错误,不允许在声明时初始化数组期间使用变量。但是,如果它是标准 C# 项目,则一切正常,因此这仅与 Unity 有关。

f这个问题与存在static或无关readonly,只是它是一个变量。以下代码不起作用:

public void init()
{ 
    float f = 1.25f;
    float[,] FLIPPER_CENTERS = new float[,] { 
       { (5+f), (27*f) },    { 30 - (20*f), (27*f)},
       { (6*f), (25*f) },     { 20 - (6*f), (25*f) },
       { (8), (15)},          { (10 - 8), (15)},
       { (8), (20)},          { (67 - 8), (20)},
    };
    Debug.Log(FLIPPER_CENTERS[0,0]); // Outputs 0 | Expected 6.25f
}

在数组初始化中使用变量的任何地方f都将导致 0。更具体地说,它不只是将f = 0整个表达式设置为 0。例如,上面数组中的第一个元素5+f, 将导致 0 - 不是5. 但是,具有常数的元素通常会计算(例如最后几个元素)。似乎 Unity 在遇到变量时会退出评估。

但是,如果我在一行中定义数组,然后稍后设置元素,则一切正常。例如:

public void init()
{ 
    float f = 1.25f;
    float[,] FLIPPER_CENTERS = new float[8, 2];
    FLIPPER_CENTERS[0, 0] = 20*f;
    FLIPPER_CENTERS[0, 1] = 27*f;
    FLIPPER_CENTERS[1, 0] = 30 - (20*f);
    FLIPPER_CENTERS[1, 1] = 27*f;
    FLIPPER_CENTERS[2, 0] = 6*f;
    FLIPPER_CENTERS[2, 1] = 25*f;
    FLIPPER_CENTERS[3, 0] = 20 - (6*f);
    FLIPPER_CENTERS[3, 1] = 25*f;
    FLIPPER_CENTERS[4, 0] = 8;
    FLIPPER_CENTERS[4, 1] = 15;
    FLIPPER_CENTERS[5, 0] = 10 - 8;
    FLIPPER_CENTERS[5, 1] = 15;
    FLIPPER_CENTERS[6, 0] = 8;
    FLIPPER_CENTERS[6, 1] = 20;
    FLIPPER_CENTERS[7, 0] = 67 - 8;
    FLIPPER_CENTERS[7, 1] = 20;
    Debug.Log(FLIPPER_CENTERS[0,0]); // Outputs 25.0f | Expected 25.0f
}

刚刚做了一些进一步的测试,似乎问题只存在于多维数组中。以下给出了预期的输出:

public void init()
{ 
    float f = 1.25f;
    float[] FLIPPER_CENTERS = new float[] {
        (f), (f * 2), (f * 3), (f * 4),
        (f + 1), (f + 2), (f + 3), (f + 5)
    };
    Debug.Log(FLIPPER_CENTERS[0]); // Outputs 1.25f | Expected 1.25f
}

这对我来说似乎是 Unity 中的一个错误。但是,通常建议conststatic readonly. 使用const提供了性能优势(尽管很小),因为它在编译时被转换为文字。此外,使用const将完全避免这个问题。

我知道你已经找到了const作品,只是想给你一些我发现的信息。

于 2013-08-22T01:14:49.883 回答