Is this correct for a game manager script?

Am I missing something or is this correct for a game manager script or am I overcomplicating it?

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

public class GameManager : MonoBehaviour
{
public static GameManager instance; // Singleton instance
public bool isGameStarted = false; // Flag for checking if game has started
public bool isGamePaused = false; // Flag for checking if game is paused
public string savedGameTimestamp; // Time stamp for saved game
public List cutSceneNames = new List(); // List of cut scene names
public CinemachineVirtualCamera cutSceneCamera; // Reference to the cut scene camera

private void Awake()
{
if (instance == null)
{
instance = this; // Set instance to this object
DontDestroyOnLoad(gameObject); // Don’t destroy this object when changing scenes
}
else
{
Destroy(gameObject); // Destroy any duplicate instances of this object
}
}

private void Start()
{
LoadGame(); // Load the saved game
}

private void Update()
{
if (!isGameStarted)
{
if (Input.GetKeyDown(KeyCode.Space))
{
StartGame(); // Start the game when space bar is pressed
}
}

if (Input.GetKeyDown(KeyCode.Escape))
{
QuitGame(); // Quit the game when escape key is pressed
}
}

public void StartGame()
{
isGameStarted = true; // Set game started flag to true
}

public void QuitGame()
{
Application.Quit(); // Quit the application
}

public void SaveGame()
{
savedGameTimestamp = System.DateTime.Now.ToString(“yyyy-MM-dd_HH-mm-ss”); // Set saved game time stamp to current date and time
}

public void LoadGame()
{
// Load saved game if there is one
if (!string.IsNullOrEmpty(savedGameTimestamp))
{
Debug.Log("Loading saved game from " + savedGameTimestamp);
}
}

public void LoadScene(string sceneName)
{
SceneManager.LoadScene(sceneName); // Load the specified scene
}

public void PlayCutScene(string cutSceneName)
{
// Play the specified cut scene
if (cutSceneNames.Contains(cutSceneName))
{
cutSceneCamera.gameObject.SetActive(true); // Enable the cut scene camera
Debug.Log("Playing cut scene " + cutSceneName);
}
else
{
Debug.LogError(“Cut scene " + cutSceneName + " not found!”);
}
}

public void StopCutScene()
{
cutSceneCamera.gameObject.SetActive(false); // Disable the cut scene camera
}
}

Steps to success:

  • identify the functions you want out of a game manager

  • test your software (run it) and see if the above script meets those needs

This is software engineering, not proofreading college term papers.

If you have absolutely no idea what is going on in the above code, fix that first. Here’s how:

Time to start debugging! Here is how you can begin your exciting new debugging adventures:

You must find a way to get the information you need in order to reason about what the problem is.

Once you understand what the problem is, you may begin to reason about a solution to the problem.

What is often happening in these cases is one of the following:

  • the code you think is executing is not actually executing at all
  • the code is executing far EARLIER or LATER than you think
  • the code is executing far LESS OFTEN than you think
  • the code is executing far MORE OFTEN than you think
  • the code is executing on another GameObject than you think it is
  • you’re getting an error or warning and you haven’t noticed it in the console window

To help gain more insight into your problem, I recommend liberally sprinkling Debug.Log() statements through your code to display information in realtime.

Doing this should help you answer these types of questions:

  • is this code even running? which parts are running? how often does it run? what order does it run in?
  • what are the names of the GameObjects or Components involved?
  • what are the values of the variables involved? Are they initialized? Are the values reasonable?
  • are you meeting ALL the requirements to receive callbacks such as triggers / colliders (review the documentation)

Knowing this information will help you reason about the behavior you are seeing.

You can also supply a second argument to Debug.Log() and when you click the message, it will highlight the object in scene, such as Debug.Log("Problem!",this);

If your problem would benefit from in-scene or in-game visualization, Debug.DrawRay() or Debug.DrawLine() can help you visualize things like rays (used in raycasting) or distances.

You can also call Debug.Break() to pause the Editor when certain interesting pieces of code run, and then study the scene manually, looking for all the parts, where they are, what scripts are on them, etc.

You can also call GameObject.CreatePrimitive() to emplace debug-marker-ish objects in the scene at runtime.

You could also just display various important quantities in UI Text elements to watch them change as you play the game.

Visit Google for how to see console output from builds. If you are running a mobile device you can also view the console output. Google for how on your particular mobile target, such as this answer or iOS: How To - Capturing Device Logs on iOS or this answer for Android: How To - Capturing Device Logs on Android

If you are working in VR, it might be useful to make your on onscreen log output, or integrate one from the asset store, so you can see what is happening as you operate your software.

Another useful approach is to temporarily strip out everything besides what is necessary to prove your issue. This can simplify and isolate compounding effects of other items in your scene or prefab.

Here’s an example of putting in a laser-focused Debug.Log() and how that can save you a TON of time wallowing around speculating what might be going wrong:

“When in doubt, print it out!™” - Kurt Dekker (and many others)

Note: the print() function is an alias for Debug.Log() provided by the MonoBehaviour class.

If you post a code snippet, ALWAYS USE CODE TAGS:

How to use code tags: Using code tags properly

Once you have a handle on what your code is doing, if you have an issue, here is how to report your problem productively in the Unity3D forums:

http://plbm.com/?p=220

This is the bare minimum of information to report:

  • what you want
  • what you tried
  • what you expected to happen
  • what actually happened, log output, variable values, and especially any errors you see
  • links to documentation you used to cross-check your work (CRITICAL!!!)
1 Like

One thing you are missing for sure… and that is to wrap your code into a nice format (look in the text editor, there is an option to insert code). Otherwise no one will read it :wink:
And to your question: it depends on what you want to do an why you think it is overcomplicated.

Thank you for the help. I can do everything in game design besides code, so this is really helpful thank you. I was not sure how to approach this and didn’t expect it to be proof read. Thanks again.

I did take some time to think about the complexity and thought maybe a “master control” script would be better and take a modular approach. Since I am more artistic than logical this was quite a stretch for me. I am working on a script that has the following:

  • A slot to put a sceneManager.cs script - Public

  • A slot to put a audioManager.cs script - Public

  • A slot to put a UIManager.cs script - Public

  • A slot to put a playerManager.cs script - Public

  • A slot to put a itemManager.cs script - Public

  • A slot to put a enemyManager.cs script – Public

  • A slot to put a cutsceneManager.cs script - Public

  • A slot to put a gameOptionsManager.cs script – Public

  • A slot to put a saveLoadManager.cs script – Public

  • A slot to put the dialogManager.cs that links up with the plot.cs script that drives story progression. - public

  • A slot to put the plot.cs script that inherits from the cutsceneManager.cs script and the sceneManager.cs script.

So hopefully that would cover all my bases. Obviously there would be a lot of sub classes, but if I take it slow and keep things neat and modular it could work out

I think your plan and manager script is a good idea and will most likely meet your needs.

My only suggestion would be to put all your references in a ManagerLocator.cs class whose job is to ONLY hold references to your other managers.

If your GameManager class becomes too large and difficult to work with, it might a good idea to start breaking off some of it’s functionality:

  • SceneManager
  • CutSceneManager
  • ApplicationLifeCycleManager

etc.

However I think a good approach to game design is only make what you need (KISS, YANGI) and only expand it if and when you need to.

1 Like

Thank you for the advice sir, it is greatly appreciated.

It looks like a good separation. Instead of having one master control script that links to all managers would be to make every manager class a singleton which is often found for Unity manager classes. That way you can access a manager directly by calling ItemManager.Instance.DoSomeStuff().
Having a master class or a ManagerLocator has the advantage though, that every access to the managers is channeled through one point in your code which can make changes later on a bit easier (for example you change the ItemManager to a much better ItemManager). But don’t concern yourself too much at this point about this.

1 Like

Yeah I think managerLocator might be a good idea, I am good at asset creation wether its models or music but when it come to coding my artistic brain falls a bit flat. Thanks for the advice.