静态实例不像我预期的那样工作

Static instance does not work like I expect

我正在对使用 Unity 构建的游戏的状态进行一些测试,使用如下内容:

脚本 1

public class ControladorEstados : MonoBehaviour {
    private static ControladorEstados controladorEstados = null;
    //public bool pause { get; set;} = false; //¿ usa c# 4? 
    private bool pause; 
    public bool Pause { 
        get { return pause;  } 
        set { pause = value; }
    }

    private bool gameOver;
    public bool GameOver {
        get { return gameOver;  }
        set { gameOver = value; }
    }

    //protected ControladorEstados () {}    
    private ControladorEstados () {}

    void Start () {
        pause = false;
        gameOver = false;
    }

    void Update () {
        Debug.Log("Update");

        if (gameOver == true) {
            Debug.Log("GameOver Game");
        }

        if (pause) {
            Debug.Log("Pause Game");
        }
    }

    public static ControladorEstados getInstancia () {
        if (controladorEstados == null) {
            controladorEstados = new ControladorEstados ();
        }
        return controladorEstados;
    }
}

脚本 2

    ..//

    private ControladorEstados controladorEstados = null;

    void Awake() {
        rb = GetComponent<Rigidbody>();
        controladorEstados = ControladorEstados.getInstancia ();
    }

    void Start() {
    }


    void Update () {
        // test
        gameOver ();
    }

    private void gameOver (){
        controladorEstados.GameOver = true;
        Debug.Log("test gameOver () " + controladorEstados.GameOver);
    }   
}

test gameOver () 日志中我可以看到变量设置为true,但是脚本ControladorEstados 在执行更新时没有像我预期的那样工作。它没有按预期工作。

我已经把Debug.Log("Update");看成是运行了Update,是运行,但是没有分支到if ] 语句时为 true.

我没有 C# 或 Unity 的经验,尽管问这个问题对我来说似乎很尴尬,但我已经这样做了一段时间,但我没有看到错误。此外,我使用的是 Linux 版本,我不知道这是否是错误的一部分。

更新:

我刚刚添加了这个代码更改:

void Update () {
        Debug.Log("Update" + gameOver);

        if (gameOver == true) {
            Debug.Log("GameOver Game");
        }
..//

它的输出是 False 所以我可以看到它没有改变。在 script 2 中为真,但在 script 1 中为假。请给我一些关于我做错了什么的想法。

我解决了

脚本 1

void Awake () {

    //controladorEstados = new ControladorEstados ();       

    if (controladorEstados == null) {
        controladorEstados = this;
    }
}

..//

public static ControladorEstados getInstancia () {
    return controladorEstados;
}

根据 Peter Duniho 的回复,我创建了上面的代码,您可以看到更改,我也知道使用 Script Execution Order 来使用它们之间的顺序。

我不知道这是否是最好的方法,但它似乎有效,我 post 它以防有人帮助解决类似的问题。

如果 a good, Minimal, Complete, and Verifiable code example 无法可靠地重现问题,则无法确定您需要更改哪些内容才能解决问题。

但是,很明显您正在处理 ControladorEstados 的两个不同实例。 运行 的实例(以及 Unity3d 为其调用 ControladorEstados.Update() 方法的实例)是 而不是 [=] 引用的同一实例12=] 变量在任何 class 你描述为 "script 2".

在您的 ControladorEstados.getInstancia() 方法中,您不应创建 ControladorEstados 的新实例。相反,您需要做两件事:

  1. 创建时在ControladorEstados class中设置ControladorEstados.controladorEstados,例如在 Start() 方法中。
  2. 确保您描述为 "script 2" 的 class 在第 1 步发生之前不会调用 getInstancia()

请注意,以上只是解决问题可以采取的最少步骤。很可能有更好的方法来查询 Unity3d API 以允许 "script 2" 检索 the 实例ControladorEstados 您想要的(例如 return 来自场景的当前正确的控制器实例,或类似的东西)。但是,如果没有更完整的代码示例,就无法确定更好的方法到底是什么样子。

您的方法不完全是 Unity 的方法。您基本上是将单例与 MonoBehaviour 混合在一起。

请记住,Unity 是 component-driven。如果您想要扩展 MonoBehaviour 的对象的单个实例,只需创建一个始终在场景中的对象(如 GameManager)并向其添加 ControladorEstados

然后您可以在需要使用它而不是使用单例的脚本中从那里引用它。