Unable to call a function from another script

Both my programming teacher and the student teacher were unable to solve this problem, so I’m turning to the forums. I’ve written a script where if I call the endgame function, it should also call the screen function from another script.

using UnityEngine;
using UnityEngine.SceneManagement;
using UnityEngine.UI;
public class GameManager : MonoBehaviour
{
   public Text pointsText;
   public GameOverScreen GameOverScreen;
   int maxPlatform = 0;

   void Start()
   {

   }

   public void EndGame ()
   {
      print("GameOver"); 
      GameOverScreen.Screen();
      Debug.Log("GAME OVER");
   }
   void Restart ()
   {
      SceneManager.LoadScene(SceneManager.GetActiveScene().name);
   }
}

And I know that the endgame function is running, because the first print command successfully prints. However, for some reason it gets stuck on the call screen function, because it never happens, and the debug log command never prints. Here’s the script with the screen function:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
using UnityEngine.SceneManagement;

public class GameOverScreen : MonoBehaviour
{
    public Text pointsText;
    // Start is called before the first frame update
    void Start()
    {
        print("GameOverStart");
    }
    
    public void Screen()
    {
        print("GameOver2");
        scoreScript = GameObject.Find("Score").GetComponent<ScoreScript>();
        gameObject.SetActive(true);
        pointsText.text = scoreScript.scoreValue + " POINTS";
    }
    public void Restartbutton()
    {
        SceneManager.LoadScene("SampleScene");
    }
    public void Exitbutton()
    {
        SceneManager.LoadScene("MainMenu");
    }
}

In fact, none of the functions of the GameOverScreen are actually working, since even print(“GameOverStart”) does not print.

All the inspector slots that should be filled are filled, and the funniest part about this is that these scripts used to work just fine, but then when I was cleaning up some lines of code that didn’t do anything, it stopped working, and then after I undid everything, it still wouldn’t work. Anyone know how to fix this?

There are several things to unpack here.

It strikes me that the GameOverScreen class is a sort of Utility class. A Utility class is something that provides a bunch of functions that don’t themselves manipulate the game but provide background methods. The MathF class is such a class. However, every public Method in MathF is “static public” - i.e. it doesn’t need to be instanced and is always available.

Your start() in GameOverSceeen won’t be called automatically unless it sits on a Gameobject. However, I’m assuming that it’s not on a GO because you don’t try and find the GO in GameManager. What’s more, if you don’t need Start or any other MonoBehaviour then don’t inherit from Monobehaviour. There’s no need. Utility Classes don’t inherit from MonoBehaviour. They may inherit from something else but not MonoBehaviour.

I’m surprised you’re not getting an error message “error CS0120: An object reference is required for the non-static field, method, or property xxx”. What that says is, because GameOverScreen.Screen() is not static, you’d need an object to hang it off. If you’re not getting that message then there’s something else you’re not telling us!

So, how to fix? If this is a genuine Utility class, then making its methods static is fine. However making everything static is not good design. The class itself doesn’t have to be static. Ultimately, you might want to consider events as a much better way of removing dependencies and keeping code clean. I gave an example of events to another answer here (scroll down to the answer), which could be adapted. Using an event for GameOver is quite appropriate since you might want to stop animations, stop input, stop enemy AI, play audio, update score and high score, update UI, start a new scene etc, all of which will be in separate classes.

Here are two very simple classes where the first calls the second successfully:

using UnityEngine;

public class Test1 : MonoBehaviour
{
    void Start()
    {
        Test2.ABC();
    }
}

And the second:

  using UnityEngine;
    
    public class Test2
    
    {
        static public void ABC()
        {
            Debug.Log("From ABC");
        }
    }