Click button to load scene while incorporating level

This isn’t for the user, but for me.  I need a version of my game that I can adapt to kid user and pick different levels for them.  (Although I’ll have some sort of main menu for the user, as well.  That’s just not what I’m working on right now.)

This is a great explanation.  The only thing I can see won’t work in Unity 5 is Application.LoadLevel(), which is now deprecated.  Also note that you don’t have to explicitly make a Canvas anymore – UI elements like buttons come with them.  So use this instead (talked about in my post here):

SceneManager.LoadScene(SceneManager.GetActiveScene().buildIndex);

Ah.  It also doesn’t work because Buttons in Unity 5 actually work differently.  Here’s a great official tutorial.  The part I care about now is the Event System, at 8:30 (although the changing color when you put the mouse over it, and changing color when you click it, is great too).  This is kinda all back to the I need to think about things as nouns as opposed to verbs thing.

Sadly, this other tutorial is outdated.  #todo – watch to see if there are things that are still useful.  Probably so!

Alright, so now I’ve got my button taking me back to my Main scene, where all the magic happens.  Lol.  But the problem I’m realizing now – I don’t have separate scenes for separate levels, because I call those elements into the Main scene using my .txt file.   What I really want is buttons corresponding to my .txt file that then take you to that the Main scene with those elements in it.  Uhh so now I need my .txt file to create the buttons.  Um.  Huh.

I am *not* confident that Unity was built with that in mind.  That being said, let’s go for it!

So first I started with my base script for the button changing scene, and just adapted it to make sure I could put whatever name I wanted into it.  Hmmm now that I think about it better that doesn’t fix anything because what I need is to access the .txt file, not to change what the scene name is.

public class ButtonNextLevel : MonoBehaviour 

{

    private string scene;

    public void NextLevelButton() // oh gosh how do I pass through from button to what I want it to load? 
    {
        scene = Main;
        SceneManager.LoadScene(scene); // do I need the .buildIndex part? 

    }

Okay so now to access the dictionary.  Maybe what needs to happen is the dictionary gets accessed in the button, *not* in the level.  (Or in both?)   And then I need to pass through what I got from the dictionary into the level.  I really don’t feel equipped for this.

Do I need to rewrite the function that changes the onset and ending letters so that it’s pulling them?  That way I can pass them through the script on the button, into the script inside the level.  I think?

So to start by making a copy of this, or else I’m at risk of ruining everything. (#todo – set this all up on Git so it’s easier to do this)

OH!  Maybe I could pull from the .txt file to make a different button for each level, and a script makes a new .txt file for each button within that gets used.   That could work.  Right?   Oh!  I wouldn’t even need a .txt file… I can just have a global static variable or list (lol great, really good form there)…

Maybe I could have a blank prefab object that has placeholders for each of these things, then gets filled up by the button, and then gets pulled into the level and the info gets extracted from it there?

This is way more complicated than I thought it’d be.  Huh. Turns out things that are easy-ish in python aren’t easy here…

 

New idea

Can I have multiple loader scripts for my GameManager?

 

This is exactly what I was looking for to change the text of the button:

ThisButton.GetComponentInChildren(Text).text = “testing”;

 

Buuut tha’ts not quite right bc it’s in javascript *and* it doesn’t super work with unity’s new button setting.

http://stackoverflow.com/questions/31220004/unity-5-change-button-text-created-with-unityscript

 

Alright I put my script onto my button explicitly.  This is how I’m changing its text:

using UnityEngine;
using System.Collections;
using UnityEngine.UI;

public class NameButton : MonoBehaviour {

    // Use this for initialization
    void Start () {
        Text thisText = gameObject.GetComponentInChildren<Text>();
        thisText.text = new;
    
    }

Not sure if I like this bc this’ll mean I have to load in the .txt here as well as the “gotolevel()” function.  But I can make this more concise when I have it functioning.  Ugh just realized that this way it’s harder to automate different text for each button.  Would require a different script for each button.  I am not thrilled about this option as it seems stupid.

Okay so I’ve got it in the thing that the button is pulling in, not a separate script.

Interesting note, as I go through each of the buttons in a foreach loop, it’s labelling them from right to left, instead of from right to left.  #todo – reorganize them so they go in that direction?  Or tell it to do left to right.  Huh.

Okay so now I’ve got it iteratively labelling the buttons.

    void Start()
    {
        int buttonCounter = 1;
        buttons = GameObject.FindGameObjectsWithTag(Button);

        foreach (GameObject button in buttons)
        {
            
            Text buttonText = button.gameObject.GetComponentInChildren<Text>();
            Debug.Log(buttonText.text);
            buttonText.text = buttonCounter.ToString();
            buttonCounter += 1; // its really interesting, it does it right to left 

        }

    }

Now I need to have the buttonCounter be the index on the linesplits in the .txt.

Woooo this works below:

 

    void Start()
    {
        int buttonCounter = 0;
        buttons = GameObject.FindGameObjectsWithTag(Button);

        TextAsset csvFile = (TextAsset)Resources.Load(PuzzleBotGoogle, typeof(TextAsset)); //PuzzleBotData2.txt
        string[] levels = csvFile.text.Split(\n); // #todo why does \r not work? 

        foreach (GameObject button in buttons)
        {
            
            Text buttonText = button.gameObject.GetComponentInChildren<Text>();
            Debug.Log(buttonText.text);
            buttonText.text = levels[buttonCounter];           
            buttonCounter += 1; // its really interesting, it does it right to left 

        }

    }

Okay so now it’s pulling in the text components I want.  Now I need it to load the correct level.

For the onbutton click thing, if I try to put “gameObject.name” in there, it returns “Main Camera”.  So how do I access the button that’s being clicked?

Intrigued by writing a separate script instead of using the OnClick() automated function, because I need to specify which button is being clicked.  I like that here.

  1. using UnityEngine;
  2. using UnityEngine.UI; // <-- you need this to access UI (button in this case) functionalities
  3. public class ButtonController : MonoBehaviour {
  4. Button myButton;
  5. void Awake()
  6. {
  7. myButton = GetComponent<Button>(); // <-- you get access to the button component here
  8. myButton.onClick.AddListener( () => {myFunctionForOnClickEvent("stringValue", 4.5f);} ); // <-- you assign a method to the button OnClick event here
  9. myButton.onClick.AddListener(() => {myAnotherFunctionForOnClickEvent("stringValue", 3);}); // <-- you can assign multiple methods
  10. }
  11. void myFunctionForOnClickEvent(string argument1, float argument2)
  12. {
  13. // your code goes here
  14. print(argument1 + ", " + argument2.ToString());
  15. }
  16. void myAnotherFunctionForOnClickEvent(string argument1, int argument2)
  17. {
  18. // your code goes here
  19. print(argument1 + ", " + argument2.ToString());
  20. }
  21. }

Gonna give this a shot.

Next day – Woooo this works.  Also looked at few other sites to wrap my brain around it:

http://answers.unity3d.com/questions/797772/example-of-setting-up-a-button-onclick-event-via-s.html

http://docs.unity3d.com/ScriptReference/UI.Button-onClick.html

Now I have two scripts.  One is “NameButton”, and I put it on my main camera in the Main Menu scene (I might be supposed to make an object for this … #todo – check this?)  This script goes through and finds all the buttons, then populates their text with the level details from the .txt file (this way I know what level I’m going into and its contents, for fast playtesting and switching around difficulties).  Its functionality happens in Awake(), so that everything gets labelled first.

The other script is “GetButtonLevel”.  This one is attached to each button, and has its functionality happen in Start(). That way it acts after the Awake() function in Main Camera’s “NameButton”, and all the buttons already have their text labels.  When I click on a button, it retrieves its text, identifies the level number by splitting the text up, converts the level to an integer, changes the global variable “level” to this level, then loads the Main scene using that level.  WOOOOOO

Text below (not cleaned up yet):

NameButton():

using UnityEngine;
using System.Collections;
using System.Collections.Generic;
using UnityEngine.UI;
using UnityEngine.SceneManagement;
using System.Linq; // so I can convert to int? nah

public class NameButton : MonoBehaviour {

     Button myButton;
 
     void Awake()
     {
//         myButton = GetComponent<Button>(); // < you get access to the button component here
 
//         myButton.onClick.AddListener( () => {myFunctionForOnClickEvent(stringValue, 4.5f);} );  // < you assign a method to the button OnClick event here
//         myButton.onClick.AddListener(() => {myAnotherFunctionForOnClickEvent(stringValue, 3);}); // < you can assign multiple methods

//
//            myButton.onClick.AddListener(() =>
//            {
//                GetLevel(); // dont know this formatting but its cool? 
//            });
//
//        myButton.onClick.AddListener(() => GetLevel());
        int buttonCounter = 0;
        GameObject[] buttons = GameObject.FindGameObjectsWithTag(Button);

        TextAsset csvFile = (TextAsset)Resources.Load(PuzzleBotGoogle, typeof(TextAsset)); //PuzzleBotData2.txt
        string[] levels = csvFile.text.Split(\n); // #todo why does \r not work? 

        foreach (GameObject button in buttons)
        {
            
            Text buttonText = button.gameObject.GetComponentInChildren<Text>();
//            Debug.Log(buttonText.text);
            buttonText.text = levels[buttonCounter];    
//            string buttonTextContent = buttonText.text;
            string[] buttonTextSplit = buttonText.text.Split(\t);
//            string level = buttonTextSplit[0];
//            Debug.Log(level);

            buttonCounter += 1; // its really interesting, it does it right to left 
//            int levelNumber = int.Parse(level); // convert level to integer
//            Debug.Log(levelNumber);

        }
    }

}

 

GetButtonLevel():

using UnityEngine;
using System.Collections;
using System.Collections.Generic;
using UnityEngine.UI;
using UnityEngine.SceneManagement;
using System.Linq; // so I can convert to int? nah

public class GetButtonLevel : MonoBehaviour {

     Button myButton;
     private Text buttonText;
     private int buttonLevel;
 
     void Start()
     {
         myButton = GetComponent<Button>(); // < you get access to the button component here
 
//         myButton.onClick.AddListener( () => {myFunctionForOnClickEvent(stringValue, 4.5f);} );  // < you assign a method to the button OnClick event here
//         myButton.onClick.AddListener(() => {myAnotherFunctionForOnClickEvent(stringValue, 3);}); // < you can assign multiple methods

//
//            myButton.onClick.AddListener(() =>
//            {
//                GetLevel(); // dont know this formatting but its cool? 
//            });
//
        myButton.onClick.AddListener(() => GetLevel());

//        GameObject[] buttons = GameObject.FindGameObjectsWithTag(Button);

        TextAsset csvFile = (TextAsset)Resources.Load(PuzzleBotGoogle, typeof(TextAsset)); //PuzzleBotData2.txt
        string[] levels = csvFile.text.Split(\n); // #todo why does \r not work? 

            
        buttonText = gameObject.GetComponentInChildren<Text>();
//            Debug.Log(buttonText.text);
        Debug.Log(buttonText.text); 
//            string buttonTextContent = buttonText.text;
        string[] buttonTextSplit = buttonText.text.Split(\t);
        string level = buttonTextSplit[0];
//        Debug.Log(level);

//        buttonCounter += 1; // its really interesting, it does it right to left 
//            int levelNumber = int.Parse(level); // convert level to integer
//            Debug.Log(levelNumber);

        
    }

     

     public void GetLevel()
     {
        Text buttonText = gameObject.GetComponentInChildren<Text>();
        string[] buttonTextSplit = buttonText.text.Split(\t);
        string level = buttonTextSplit[0];
//            Debug.Log(buttonText.text);
        buttonLevel = int.Parse(level); // convert level to integer
        Debug.Log(buttonLevel);
        GameManager.instance.levelCounter = buttonLevel; // buttonCounter; // alright this gets to level I need 
        SceneManager.LoadScene(Main); // do I need the .buildIndex part? 
     }
 
//     void myFunctionForOnClickEvent(string argument1, float argument2)
//     {
//         // your code goes here
//         print(argument1 + ,  + argument2.ToString());
//     }
// 
//     void myAnotherFunctionForOnClickEvent(string argument1, int argument2)
//     {
//         // your code goes here
//         print(argument1 + ,  + argument2.ToString());
//     }
 

}

Leave a Reply

Your email address will not be published. Required fields are marked *