从构造函数调用时,静态函数意外返回

时间:2014-05-20 09:48:10

标签: c# constructor unity3d static-methods

我不知道为什么,但在构建它时我的结构中遇到了奇怪的行为。

这是我正在构建的结构的代码。这段代码是“Step”类的一部分,我用它来表示游戏中角色的“Step”(我的游戏是基于网格的)。方向和长度是结构中只有2个字段,它们只是readonly,使结构不可变(我希望)

public Step(Direction d, int l)
{
    direction = d;
    if(l < 0) l = 0;
    length = l;
}

public Step(float horizontal, float vertical, int l) : this(getDirectionFromInputAxes(horizontal, vertical), l){
}

public static Direction getDirectionFromInputAxes(float horizontal, float vertical)
{
    int x = 0, y = 0;

    if(horizontal < -0.5f){
        x += -1;
    }else if(horizontal > 0.5f){
        x += 1;
    }
    if(vertical > 0.5f){
        y += -1;
    }else if(vertical < -0.5f){
        y += 1;
    }

    switch(x){
    case -1:
        switch(y){
        case -1:
            return Direction.Northwest;
        case 0:
            return Direction.West;
        case 1:
            return Direction.Southwest;
        }
        break;
    case 0:
        switch(y){
        case -1:
            return Direction.North;
        case 0:
            return Direction.None;
        case 1:
            return Direction.South;
        }
        break;
    case 1:
        switch(y){
        case -1:
            return Direction.Northeast;
        case 0:
            return Direction.East;
        case 1:
            return Direction.Southeast;
        }
        break;
    }

    // Should never happen
    return Direction.None;
}

基本上,我创建了第二个带浮点数的构造函数(为了方便起见),然后想法是使用静态函数从浮点数创建一个Direction,然后使用主构造函数初始化该类。

我的代码中遇到了一些问题。在调试时,我注意到Step中的方向字段在尝试读取Monodevelop中的值时出于某种原因“卸载”。在构造函数和getDirectionFromInputAxes()函数中放入一些断点后,我注意到静态函数是从第二个构造函数输入的,但是一旦我执行,函数就会退出并且它似乎跳转到主构造函数,就好像该函数已返回。在主构造函数中,d未定义,但定义了l。这导致Step对象没有定义的方向,但是定义了长度,这导致代码中的其他问题

我不确定为什么会这样。我的理论是从构造函数中调用静态函数是错误的。但为什么会这样呢?也许我错误地使用枚举?

(对我的风格有任何建设性的评论将不胜感激)

编辑:修正了一个错误。 Step实际上是一个结构,而不是一个类。虽然我已经尝试将其更改为一个类,但问题仍然存在。

EDIT2:抛出NullReferenceException的代码是以下第二行:

Step step = new Step(Input.GetAxis("Horizontal"), Input.GetAxis("Vertical"), 1);
if((step.direction == Step.Direction.None && step.length == 0) || 
   (!FieldData.player.isValidStep(step))
  ){
    // We can't take this step. Ignore.
    break;
}

此代码位于另一个类中。我猜测NullReferenceException发生是因为step.direction在if语句中是未定义的,至少从我在调试器中可以看到的情况来看。 step显然是一个有效的参考。

1 个答案:

答案 0 :(得分:1)

Unity会在发生异常时暂停代码并从当前函数返回,而不是完全崩溃。他们这样做是为了记录错误,而不是每次都关闭Unity。此行为不仅限于构造函数或静态方法,并且可能是缺乏经验(甚至经验丰富)Unity程序员混淆的常见原因。

当发生这种情况时,您应该在代码中查找给定异常的原因。控制台输出中会有提示。在您的情况下,它是NullReferenceException,这是由尝试访问空值的字段,属性或方法引起的。在您的情况下(来自评论),它是由player为空引起的。

MonoDevelop在进出范围时加载和卸载变量数据。不幸的是,这个功能根本不适合Unity,并且通常它会卸载最明确的范围内的变量。这是MonoDevelop本身的一个问题,而且从Unity Answers的this question来看,这似乎不是一个简单的修复。