Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. Dismiss Notice

Creating A Proper Game Manager

Discussion in 'Scripting' started by SimpleGiant, Jan 9, 2016.

  1. SimpleGiant

    SimpleGiant

    Joined:
    Dec 22, 2013
    Posts:
    47
    I am trying to learn how to use a game manager properly. From what I understand, I store things in it that are not just variable to the one scene, or may want to be recapped latter. From what I get out of the Roeg Like tutorial, I also am storing the scene management tools inside the game manager. For example, the scene load scripts.

    I have been using a game manager to load between scenes, but I cant find any answer on how to rig the GUI up to the game manager properly. In order to rig the buttons to the game manager I created a prefab of the game manager, and dropped it into each scene, then rigged the buttons up to the prefab. Example, Restart and main menu. Then when the first Game Manager loads the screen, the second one will look for an instance of it, and delete the extra one. The buttons stop working when I do this, but if I fire the scene up without in-game scene loading, they work fine.

    How do I work around this? This seems to not be a common topic of discussion. Am I going about this the wrong way? Should I be using a separate Scene Manager for level loading? What is the proper way to do this, because I understand that their are many ways to get the job done. What way is the best?

    I am using C#, MonoDevelop, and the most recent version of Unity3D.
     
  2. SimpleGiant

    SimpleGiant

    Joined:
    Dec 22, 2013
    Posts:
    47
    Still looking for this, anyone have any information?
     
  3. apsdsm

    apsdsm

    Joined:
    Sep 26, 2013
    Posts:
    56
    It's just my opinion, but I believe using a Game Manager in your code is going to make it harder to maintain in the long run. From an OOP perspective, "Game Manager" is way too broad a description for what a class should be doing. You're running into an example of that currently - you want to replicate what is essentially an entry point into the code (like you'd find in, say, Cocos2d), but Unity doesn't allow for that, so the 'Game Manager' needs to live as a behavior on an in game object. You end up running into these kinds of issues - you're now spending time worrying about managing your game logic as though it were an object in the game - and it isn't...

    Unfortunately, there is no "proper way" to do this, in large part because Unity basically puts you into a position where there isn't really a good option from the start. The way I've done this in the past, and the way that many other people get around the limitation, is to use singleton objects (yuck) that spawn at the very start of the game, then prohibit anything else from taking them over once they've spawned.

    You can also take advantage of DontDestroyOnLoad to make sure that your singleton stays around.

    This will mean you're always using one manager, and your settings will not be deleted.

    Other than this, yes, I would totally suggest splitting out any logic that doesn't need to be around for longer than the scene where it's used. I'd also encourage you to move away from 'manager' classes towards actual 'thing' classes - so not a 'scene manager' class but a 'scene' class - but that's just my own preference in programming.
     
    mickmarona likes this.
  4. SimpleGiant

    SimpleGiant

    Joined:
    Dec 22, 2013
    Posts:
    47
    So this method that you have proposed, using singletons. Using do not destroy, and what not. I have done this, and am now running what I called the scene manager and the game manager. The scene deals with events and the game manager is a log for information like inventory, credits, and player settings. I want to refer to my game manager to load between scenes, but Im having trouble rigging my buttons to the Singleton object. Any ideas?
     
  5. mickmarona

    mickmarona

    Joined:
    Apr 7, 2015
    Posts:
    44
    Can you post your code?
     
  6. sngdan

    sngdan

    Joined:
    Feb 7, 2014
    Posts:
    1,131
    Code or more specific description of your issue would help.

    Just guessing, you might need to create (depending on how you did your game manager) a script that exists in the same scene as your gui.

    Say call it "manageInput" - create a public function in it "callGM" which contains the code that accesses the game manager.

    Then you drag "manageInput"to the gui element and call the "callGM" function - you can also pass parameters.

    I am fairly new to unity and better ways may exist. The above worked for me in a setup with game manager where I also run into some issues in linking it with gui
     
  7. SimpleGiant

    SimpleGiant

    Joined:
    Dec 22, 2013
    Posts:
    47
    Thank you, sngdan.

    This is the method that I have turned to. My question is, how do i not use a third party script to make this communication happen? My script works, my singletons are fine, but I cant rig the buttons to a GameManager that is not is the scene yet. (Using the Unity 5 UI methods.)

    Example.
    GM is on main menu, and I rig the buttons to the object to let me to load the next scene.

    The character select scene has a gui that needs to communicate with the GM, but being that the GM was not in that scene tell now the buttons are not rigged to it.

    How do I have the seconds scenes buttons work without a third party script?
    Would it be a better practice to not store scene loads withing the GM. Putting them in the Scenes event system instead?
     
  8. sngdan

    sngdan

    Joined:
    Feb 7, 2014
    Posts:
    1,131
    I don't have access to my computer until later this week. If you have not figured it out till then, I can send an example.

    For now I am kind of repeating, what I wrote earlier, as it does not require 3rd party scripts.

    There are always various ways of achieving something and for arguments sake, let me just stick with your initial request, I.e. A singleton game manager that manages scene loading + it seems that each scene has buttons (new ui system) that allow navigation between scenes.

    Problem: the game manager exists only in one scene (or in none if lazy init) but you need to call a function of it in the "onClick" method of the button.

    Solution (the one I know of): create a script "manageInput" with a public function "callGM" that you attach to a game object in each scene (it could be the ui canvas) that calls the function in the game manager. You can then drag this game object (ui canvas) into the "onClick" editor interface (of the button) and you will have access to the "manageInput" function, which will have access to the game manager.

    Confusing?
     
  9. SimpleGiant

    SimpleGiant

    Joined:
    Dec 22, 2013
    Posts:
    47
    So when it comes down to it, i have to have a script that looks for and finds the GameManager after the scene has leaded, then assign the game manager to be called when the onClick function is called by the button being clicked. no exceptions?
     
  10. orb

    orb

    Joined:
    Nov 24, 2010
    Posts:
    3,032
    Just create your game manager according to a decent singleton pattern, and get its instance. That's all there is to it.

    Here's the one I prefer:
    Code (CSharp):
    1. // Singleton
    2. // Survives across scenes
    3. using UnityEngine;
    4.  
    5. namespace Whatever
    6. {
    7.     public class Singleton<T> : MonoBehaviour where T:Singleton<T>
    8.     {
    9.         private static volatile T _instance = null;
    10.         private static object _lock = new object();
    11.  
    12.         public static T instance
    13.         {
    14.             get
    15.             {
    16.                 if(_instance == null)
    17.                 {
    18.                     lock(_lock)
    19.                     {
    20.                         if(_instance == null)
    21.                         {
    22.                             GameObject go = new GameObject();
    23.                             _instance = go.AddComponent<T>();
    24.                             go.name = typeof(T).ToString() + " singleton";
    25.                             DontDestroyOnLoad(go);
    26.                         }
    27.                     }
    28.                 }
    29.                 return _instance;
    30.             }
    31.         }
    32.     }
    33. }
    A game manager stub looks like this:
    Code (CSharp):
    1. using UnityEngine;
    2. using Whatever;
    3.  
    4. public class GameManager : Singleton<GameManager>
    5. {
    6.         // Insert code for maximum fun, like Awake(), Start(), Update() and management methods
    7. }
    Getting the reference to this manager is as simple as this:
    Code (CSharp):
    1. GameManager gm = GameManager.instance;
    The first time you use it, it exists. Put that line in the Awake() method of a script to initialise early, and stick all the generic logic in your GM. The game manager would be a good place to put logic that depends on scene change, via the OnLevelWasLoaded() method.
     
    Jroel and bowserscastle like this.
  11. sngdan

    sngdan

    Joined:
    Feb 7, 2014
    Posts:
    1,131
    @orb: if I am not mistaken, he got this far
    @SimpleGiant: as mentioned, I am new to unity, but found no way (other than described above) to access a game manager, set up this way, directly from the ui - on click inspector window

    Ping me if you need an example - will be able to do it Thursday.
     
  12. orb

    orb

    Joined:
    Nov 24, 2010
    Posts:
    3,032
    It looked to me as if he didn't get the persistence down, and his explanation of what he was doing looked a tad convoluted ;)