我不确定为什么,但是在构造它时,我在结构中遇到了奇怪的行为。

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

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,然后使用主构造函数初始化该类。

我的代码中遇到了一些问题。调试时,我注意到在尝试在Monodevelop中读取它的值时,由于某种原因,Step中的direction字段已“卸载”。在构造函数和getDirectionFromInputAxes()函数中放置了一些断点之后,我注意到静态函数是从第二个构造函数输入的,但是一旦我踏上一步,该函数就会退出并且似乎跳到主构造函数,就好像该函数已返回。在主构造函数中,d是未定义的,而l是已定义的。这将导致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的原因是,至少在调试器中可以看到,在if语句中未定义step.direction。但是,step显然是有效的参考。

最佳答案

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

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

当它们进入和超出范围时,MonoDevelop会加载和卸载变量数据。不幸的是,此功能根本无法与Unity一起很好地使用,并且经常会卸载最确定范围内的变量。这是MonoDevelop本身的问题,从Unity Answers的this question看来,这不是一个容易解决的问题。

关于c# - 从构造函数调用时,静态函数意外返回,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/23756376/

10-08 22:47
查看更多