简体   繁体   English

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

[英]Static instance does not work like I expect

I'm doing some tests for the states of a game built using Unity, using something like the following:我正在对使用 Unity 构建的游戏的状态进行一些测试,使用如下内容:

script 1脚本 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;
    }
}

script 2脚本 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);
    }   
}

In the test gameOver () log I can see that the variable is set to true , but the script ControladorEstados does not work as I expect when doing the update.test gameOver ()日志中,我可以看到该变量设置为true ,但是脚本ControladorEstados在进行更新时没有按预期工作。 It does not work as expected.它没有按预期工作。

I have put Debug.Log("Update");我已经把Debug.Log("Update"); To see if it was running the Update , and it is running, but it does not branch into the if statement when it is true .查看它是否正在运行Update ,并且它正在运行,但是当它为true时它不会分支到if语句中。

I have no experience in C # or Unity, even though it seems embarrassing for me to ask this question, but I have been at this for a while and I do not see the error.我没有 C# 或 Unity 方面的经验,尽管问这个问题对我来说似乎很尴尬,但我已经研究了一段时间,我没有看到错误。 Additionally, I am using a Linux version and I do not know if that could be part of the error.此外,我使用的是 Linux 版本,我不知道这是否可能是错误的一部分。

Update:更新:

I just added this code change:我刚刚添加了此代码更改:

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

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

Its output is False so I can see it is not changing.它的输出是False所以我可以看到它没有改变。 In the script 2 it is true, but in the script 1 it is false.脚本 2 中它是真的,但在脚本 1 中它是假的。 Please give me some ideas as to what I am doing wrong.请给我一些关于我做错了什么的想法。

I solve it我解决了

script 1脚本 1

void Awake () {

    //controladorEstados = new ControladorEstados ();       

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

..//

public static ControladorEstados getInstancia () {
    return controladorEstados;
}

With the response of Peter Duniho I create the code above, You can see the changes and I also knew the use of Script Execution Order To use an order among them.根据 Peter Duniho 的响应,我创建了上面的代码,您可以看到更改,我也知道使用Script Execution Order来使用其中的一个命令。

I do not know if it's the best way, but it seems to work, I post it in case someone helps with something similar.我不知道这是否是最好的方法,但它似乎有效,我发布它以防有人帮助解决类似的问题。

Without a good, Minimal, Complete, and Verifiable code example that reliably reproduces the problem, it's impossible to say for sure what you need to change to fix the problem.如果没有一个可靠地重现问题的好的、最小的、完整的和可验证的代码示例,就不可能确定您需要更改什么来解决问题。

But, it's clear you are dealing with two different instances of ControladorEstados .但是,很明显您正在处理ControladorEstados两个不同实例。 The instance that is running (and so the one for which Unity3d is calling the ControladorEstados.Update() method) is not the same instance that is being referenced by the controladorEstados variable in whatever class you are describing as "script 2" .运行(因此对于该Unity3d被调用的一个实例ControladorEstados.Update()方法)是不是正在被引用的同一个实例controladorEstados在任何类,你所描述为“脚本2”的变量。

In your ControladorEstados.getInstancia() method, you should not be creating a new instance of ControladorEstados .在您的ControladorEstados.getInstancia()方法中,您不应创建ControladorEstados的新实例。 Instead, you need to do two things:相反,您需要做两件事:

  1. Set ControladorEstados.controladorEstados in the ControladorEstados class when it's created, eg in the Start() method.创建ControladorEstados类时,例如在Start()方法中,在ControladorEstados类中设置ControladorEstados.controladorEstados
  2. Make sure the class you describe as "script 2" does not call getInstancia() until after step #1 has occurred.确保您描述为“脚本 2”的类在第 1 步发生之前不会调用getInstancia()

Note that the above is just the most minimal steps you can take to resolve the issue.请注意,以上只是您可以用来解决问题的最少步骤。 In all likelihood, there is a better way to query the Unity3d API to allow "script 2" to retrieve the instance of ControladorEstados that you want (eg to return the current, correct controller instance from a scene, or something like that).在所有的可能性,有一个更好的方式来查询Unity3d API,允许“脚本2”检索实例ControladorEstados要(如返回当前,正确的控制器实例从一个场景,或类似的东西)。 But without a more complete code example, it's impossible to say for sure what that better approach would look like, exactly.但是如果没有更完整的代码示例,就不可能确切地说更好的方法会是什么样子。

Your approach is not exactly the Unity way.您的方法不完全是 Unity 方式。 You're basically mixing a singleton with a MonoBehaviour.您基本上是将单例与 MonoBehaviour 混合在一起。

Remember that Unity is component-driven.请记住,Unity 是组件驱动的。 If you want a single instance of an object that extends MonoBehaviour just create an object that's always in the scene (like a GameManager) and add ControladorEstados to it.如果您想要扩展 MonoBehaviour 的对象的单个实例,只需创建一个始终在场景中的对象(如 GameManager)并向其添加ControladorEstados

You can then reference it from there in scripts where you need to use it instead of using a singleton.然后,您可以在需要使用它而不是使用单例的脚本中从那里引用它。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM