Search Unity

What's the best way to link scene buttons to a dontdestroyonload singleton?

Discussion in 'UGUI & TextMesh Pro' started by Reverend-Speed, Sep 6, 2016.

  1. Reverend-Speed

    Reverend-Speed

    Joined:
    Mar 28, 2011
    Posts:
    284
    Hey folks, idle best-practices question here:

    Say I want to have a singleton that handles most of my Scenemanager stuff with a public function that contains SceneManager.LoadScene(string parameter that gets passed in).

    I obviously can't hook this up to a button in a different scene than the one that launches the singleton as the code/object won't be in the scene for me to connect the button to it.

    Do I create a dummy object / code that I hook the button up to, which then passes the scene string to the static access variable instance of the GameManager/singleton?

    In which case, should I just scrap any attempt to make a singleton connection here and just use a once-off script w/object for loading scenes and attach any relevant buttons to it, making the loading object a prefab for every scene that needs this interaction?

    Or is there a magical yet OBVIOUS solution I haven't thought of here? I bet it's this one. =)

    Looking forward to your responses,

    --Rev
     
    awsapps and NEVER-SETTLE like this.
  2. takatok

    takatok

    Joined:
    Aug 18, 2016
    Posts:
    1,496
    Just to make sure i'm clear. You have a SceneManager singleton that is instantiated at Game Startup. Then later on say in scene 3, You have a button that is suppose to take us take Scene 4. And you need to know how to connect this button's OnClick to SceneManager.LoadScene("Scene4 Name");
     
    SimonePellegatta likes this.
  3. IgnoranceIsBliss

    IgnoranceIsBliss

    Joined:
    Aug 8, 2012
    Posts:
    3
    As far as I'm aware, you've pretty much got the solution.

    If you really need to persist something - such as a network connection - between your scenes, and you want to be able to set up your OnClick events in the Unity UI, I'd stick to the dummy/proxy object.

    You can also set up the events in script if you like - rather than needing a dedicated object to pass messages through to your singleton, it could add the OnClick listeners yourself.
     
  4. Reverend-Speed

    Reverend-Speed

    Joined:
    Mar 28, 2011
    Posts:
    284
    @Tak, sorry 'bout the delay in responding. Yup, you have the rights of that, clearly rephrased. =)

    @ign, Excellent - and thanks for the additional info to chew over.

    Thanks folks,

    --Rev
     
  5. takatok

    takatok

    Joined:
    Aug 18, 2016
    Posts:
    1,496
    The way I tend to do this is Tag the Game Object that SceneManager is on with say the tag "SceneManager" then in your button code:
    Code (CSharp):
    1. SceneManagerScriptName  sceneManager;
    2. Button thisButton;
    3.  
    4. void Start()
    5. {
    6.     sceneManager = GameObject.FindWithTag("SceneManager").GetComponent<SceneManagerScriptName>();
    7.      thisButton = GetComponent<Button>();
    8.      thisButton.onClick.AddListener(sceneManger.FunctionYouNeed);
    9. }
     
  6. Reverend-Speed

    Reverend-Speed

    Joined:
    Mar 28, 2011
    Posts:
    284
    That's a smart answer to that problem - have the button find the manager and hook itself up. Will have a think about that, thanks. =)

    --Rev
     
  7. HanSoloYolo

    HanSoloYolo

    Joined:
    May 22, 2017
    Posts:
    19
    Hello there,

    This is what I did in order to solve the problem. I created another Empty GameObject in each Scene and created a new script called "ClickHandler" which does the following:

    Code (CSharp):
    1. using UnityEngine;
    2.  
    3. public class ClickHandler : MonoBehaviour
    4. {
    5.     private LevelManager levelManager;
    6.    
    7.     void Start ()
    8.     {
    9.         levelManager = LevelManager.instance;
    10.     }
    11.  
    12. #region ButtonCalls
    13.  
    14.     public void StartGame()
    15.     {
    16.         levelManager.StartSavedGame();
    17.     }
    18.  
    19.     public void GoToNextLevel ()
    20.     {
    21.         levelManager.StartNextLevel();
    22.     }
    23.  
    24.     public void RetryLevel()
    25.     {
    26.         levelManager.RetryLevel();
    27.     }
    28.  
    29. #endregion
    30. }
    Create a Field for your Scene Manager or Level Manager, then in the Start() have it find the instance of the Level or Scene Manager object, then simply create Methods to call the method in the Level or Scene Manager.

    Savvy??
     
  8. georgy28

    georgy28

    Joined:
    Feb 4, 2016
    Posts:
    1
    Hi,

    I have done exactly what InventorDerek did (actually without even instantiating in Start() )
    and I was searching the internet to check whether it is an "acceptable" approach or not (it seems a bit redundant).
    Good to know that it is!