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

本文关键字:意外 返回 函数调用 静态函数 | 更新日期: 2023-09-27 18:04:23

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

下面是我正在构建的结构体的代码。这段代码是"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;
}

基本上,我做了第二个构造函数,它接受浮点数(为了方便),然后想法是使用静态函数从浮点数创建方向,然后用主构造函数初始化类。

我的代码有一些问题。在调试时,我注意到步骤中的方向字段由于某种原因在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显然是一个有效的引用。

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

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

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

MonoDevelop在变量数据进入和退出作用域时加载和卸载它们。不幸的是,这个功能在Unity中并不能很好地发挥作用,而且它经常会卸载那些在范围内的变量。这是MonoDevelop本身的问题,从Unity Answers上的这个问题来看,这似乎不是一个容易解决的问题。