x


How do I call methods from other scripts using C#?

I'm seriously stuck with this. I have 2 scripts; a Game Manager and a UI Manager. When you hit Esc the 'gamestate' in the Game manager is set to paused and from within it will call a method from the UI manager to display a 'paused' message on the screen.

I have 2 scenes. In the first scene which is the main menu, the Game manager is initialised and continue to exist throughout every scene. In the second scene, there is a empty game object with the UI Manager attached.

When I run the game, move to level 1, and the hit escape, I get the following errors:

NullReferenceException: Object reference not set to an instance of an object
Game_Manager.GamePause () (at Assets/Scripts/Game_/Game_Manager.cs:55)
Game_Manager.Update () (at Assets/Scripts/Game_/Game_Manager.cs:46)

So it's claiming that the UI Manager does not exist and so it crashes. :(

Here are the scripts...

/// Game Manager

using System.Collections;
using UnityEngine;

enum GameState { mainmenu, playing, paused, gameover };

public class Game_Manager : MonoBehaviour
{
    private static Game_Manager thisInstance;
    private static GameState mGameState;
    private UI_Manager mUI;


    void Awake()
    {
        Screen.SetResolution(800, 600, false);

        /// Ensures that the GameManager is persistant through all scenes

        if (thisInstance != null && thisInstance != this) //IF we already has an instance of this class
            Destroy(gameObject);
        else
        {
            thisInstance = this;
            DontDestroyOnLoad(this);
        }
    }

    void Start()
    {
        Debug.Log("Game_Manager initialised");
        mGameState = GameState.mainmenu;
    }

    void Update()
    {
        if (mGameState == GameState.mainmenu)
        {
            GameMainMenu();
        }

        /// Pausing
        if (Input.GetKeyDown(KeyCode.Escape))
        {
            GamePause();
        }
    }

    public void GamePause()
    {
        if (mGameState == GameState.playing)
        {
            mUI.GamePauseGUI();
            Time.timeScale = 0.0f;
            mGameState = GameState.paused;
            Debug.Log("Game Paused");
        }
        else
        {
            Time.timeScale = 1f;
            mGameState = GameState.playing;
            Debug.Log("Game Playing");
        }
    }

    void GameMainMenu()
    {

        if (Input.anyKeyDown)
        {
            Application.LoadLevel(1);
            mGameState = GameState.playing;
        }
    }

    public static Game_Manager Instance
    {
        get
        {
            if (thisInstance == null)
            {
                thisInstance = new GameObject("MySingleton").AddComponent<Game_Manager>();
            }

            return thisInstance;
        }
    }

    public void OnApplicationQuit()
    {
        thisInstance = null;
    }
}




// UI_Manager

using UnityEngine;
using System.Collections;

public class UI_Manager : MonoBehaviour {

    // Use this for initialization
    void Start () {

    }

    void OnGUI()
    {

    }

    void Update()
    {

    }

    public void GamePauseGUI()
    {
        Debug.Log("Game Paused GUI");
    }
}
more ▼

asked Jun 11 '11 at 04:50 PM

AaronG gravatar image

AaronG
261 17 18 22

(comments are locked)
10|3000 characters needed characters left

2 answers: sort voted first

My guess is that it is comming from this line:

mUI.GamePauseGUI();

Unity does not automatically connect references except for built in accessors such as .transform. You need to manually reference the UI_Manager GameObject in order to use it. This can be done a number of ways, here's an example.

public class Game_Manager : MonoBehaviour
{
    private static Game_Manager thisInstance;
    private static GameState mGameState;
    //-------------------------
    private UI_Manager mUI;
    private UI_Manager MUI {
        get {
            if(mUI == null) {
                 mUI = (UI_Manager)FindObjectOfType(typeof(UI_Manager));
                  //^ this is the important line.
            }
            return mUI;
        }
    }
    //-------------------------

    public void GamePause() { /*use the property MUI to call your methods*/ }
}

The important part of the above example is mUI = (UI_Manager)FindObjectOfType(typeof(UI_Manager));. The method finds an object of the given type in the scene and returns it. You need to cast it to its derived type though 95% of the time before you actually use it.

more ▼

answered Jun 11 '11 at 05:07 PM

Peter G gravatar image

Peter G
15.1k 16 44 137

(comments are locked)
10|3000 characters needed characters left

Thanks. Works perfectly!

more ▼

answered Jun 11 '11 at 05:10 PM

AaronG gravatar image

AaronG
261 17 18 22

Make sure to mark it the correct answer then. A checkmark outline should show up under the votes for my answer that you need to click on.

Jun 11 '11 at 06:03 PM Peter G
(comments are locked)
10|3000 characters needed characters left
Your answer
toggle preview:

Up to 2 attachments (including images) can be used with a maximum of 524.3 kB each and 1.0 MB total.

Follow this question

By Email:

Once you sign in you will be able to subscribe for any updates here

By RSS:

Answers

Answers and Comments

Topics:

x4359
x84

asked: Jun 11 '11 at 04:50 PM

Seen: 2825 times

Last Updated: Jun 11 '11 at 06:03 PM