简体   繁体   中英

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:

script 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

    ..//

    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. It does not work as expected.

I have put 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 .

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. Additionally, I am using a Linux version and I do not know if that could be part of the error.

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. In the script 2 it is true, but in the script 1 it is false. Please give me some ideas as to what I am doing wrong.

I solve it

script 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.

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 . 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" .

In your ControladorEstados.getInstancia() method, you should not be creating a new instance of 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.
  2. Make sure the class you describe as "script 2" does not call getInstancia() until after step #1 has occurred.

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). 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. You're basically mixing a singleton with a MonoBehaviour.

Remember that Unity is component-driven. 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.

You can then reference it from there in scripts where you need to use it instead of using a singleton.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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