1
\$\begingroup\$

I have the following problem with my app. I have a scene where the player is adding products with prices, by using strings. They are added to a Global Control file, which saves the data. Then, in this GlobalControl file, I want to add each of this strings in a list, so this way in the next scene I can call them and add them to a ScrollView, similar to order preview. Unfortunately, I can't manage to make it the right way and to add more than one item to the Order Preview.

My code is the following: Scene one:

public void addToOrder()
{


    if (m_currentSelectedModel <= 33)

    {
       GlobalControl.orderContent = 
       menuItemNamesString[m_currentSelectedModel];
       GlobalControl.priceContent = 
       menuItemPriceString[m_currentSelectedModel];
    }

}

My GlobalControl is the following:

public class GlobalControl : MonoBehaviour
{
    public static GlobalControl control;

    //the global variables

    static public string orderContent;
    static public string priceContent;

    //global lists 
    static public List<string> orderItemsList = new List <string>();
    static public List<string> orderPricesList = new List <string>();


    void Awake()
    {
        if (control == null)
        {
            DontDestroyOnLoad(gameObject);
            control = this;
        }

        else if (control != null)

        {
            Destroy(gameObject);
        }

    }

    private void Start()
    {

        //adding the current selection to the respective list
        if (orderContent != null)
        {
            orderItemsList.Add(orderContent);
        }

        if (priceContent != null)
        {
            orderPricesList.Add(priceContent);
        }

    }

And last my OrderPreviewManager, which is in scene 2, is:

void Start () 
{
    //my current solution, which does not retrieve a variable from a list            

    curOrderContent = GlobalControl.orderContent;
    curPricetContent = GlobalControl.priceContent;

    AddSelectedItemToOrder();
    AddSelectedItemPriceToOrder();
}


//the two methods for adding the string to text components into a scroll 
  view

void AddSelectedItemToOrder()
{
    GameObject gameObject = new GameObject("Child");
    gameObject.transform.SetParent(orderContentView.transform);

    gameObject.AddComponent<Text>().text = curOrderContent;
    gameObject.GetComponent<Text>().font = 
    Resources.GetBuiltinResource(typeof(Font), "Arial.ttf") as Font;
    gameObject.GetComponent<Text>().color = Color.black;
    gameObject.GetComponent<Text>().fontSize = 20;
}

  //similar to the previous method but for the prices

void AddSelectedItemPriceToOrder()
{
    GameObject gameObject = new GameObject("Child");
    gameObject.transform.SetParent(pricetContentView.transform);

    gameObject.AddComponent<Text>().text = curPricetContent;
    gameObject.GetComponent<Text>().font = 
    Resources.GetBuiltinResource(typeof(Font), "Arial.ttf") as Font;
    gameObject.GetComponent<Text>().color = Color.black;
    gameObject.GetComponent<Text>().fontSize = 20;
}

My question is: why does this only insert one item in scene 2?

\$\endgroup\$
8
  • \$\begingroup\$ What do you mean by "best?" \$\endgroup\$ Dec 18 '18 at 16:39
  • \$\begingroup\$ By best, I mean which is the right way to call the items from the lists in the second scene. \$\endgroup\$
    – JohnyDony
    Dec 18 '18 at 16:40
  • \$\begingroup\$ Can you describe "best" without resorting to a tautology like "right," "correct," or "best practice?" What does "best" mean to you specifically in this context? \$\endgroup\$ Dec 18 '18 at 16:41
  • \$\begingroup\$ Ok, I am sorry, "best" means for me a working solution, so the app will work and show the same number of selected items from the previous scene. If the player selects 4 items, to show 4 items and their prices in the Order Preview, if he selects 10, to show 10. I am new to this program and language, I searched a lot, unfortunately, could not manage to make it. \$\endgroup\$
    – JohnyDony
    Dec 18 '18 at 16:47
  • \$\begingroup\$ Possible duplicate of Unity 5 - What is the proper way to handle data between scenes? \$\endgroup\$
    – Ruzihm
    Dec 18 '18 at 16:51
2
\$\begingroup\$

You can get rid of quite a bit of extra stuff, and just use a for loop to iterate through the lists.

Scene one

There's no reason to use orderContent or priceContent. Just add to the list directly.

public void addToOrder()
{
    if (m_currentSelectedModel <= 33)
    {
       GlobalControl.orderItemsList.Add( menuItemNamesString[m_currentSelectedModel]);
       GlobalControl.orderPricesList.Add( menuItemPriceString[m_currentSelectedModel]);
    }
}

GlobalControl

control, orderContent, and priceContent are redundant. You can get rid of them. Also, get rid of Awake and Start. Making everything static in GlobalControl makes instantiating it redundant. This also means it does not need to be a MonoBehavior.

As recommended by Olivier Jacot-Descombes, it is good form to make these lists readonly, so that there is a guarantee that any reference to one of these objects is always up-to-date.

public class GlobalControl
{
    public static readonly List<string> orderItemsList = new List <string>();
    public static readonly List<string> orderPricesList = new List <string>();
}    

OrderPreviewManager, which is in scene 2

Add a parameter to the AddxToOrder methods. Then, use a for loop to iterate through the lists in Start:

void Start () 
{
    for (int i = 0 ; i < GlobalControl.orderItemsList.Count ; i++) {
        string item = GlobalControl.orderItemsList[i];
        string price = GlobalControl.orderPricesList[i];

        AddSelectedItemToOrder(item);
        AddSelectedItemPriceToOrder(price);
    }
}


//the two methods for adding the string to text components into a scroll 
 view

void AddSelectedItemToOrder(string item)
{
    GameObject gameObject = new GameObject("Child");
    gameObject.transform.SetParent(orderContentView.transform);

    gameObject.AddComponent<Text>().text = item;
    gameObject.GetComponent<Text>().font = 
    Resources.GetBuiltinResource(typeof(Font), "Arial.ttf") as Font;
    gameObject.GetComponent<Text>().color = Color.black;
    gameObject.GetComponent<Text>().fontSize = 20;
}

//similar to the previous method but for the prices

void AddSelectedItemPriceToOrder(string price)
{
    GameObject gameObject = new GameObject("Child");
    gameObject.transform.SetParent(pricetContentView.transform);

    gameObject.AddComponent<Text>().text = price;
    gameObject.GetComponent<Text>().font = 
    Resources.GetBuiltinResource(typeof(Font), "Arial.ttf") as Font;
    gameObject.GetComponent<Text>().color = Color.black;
    gameObject.GetComponent<Text>().fontSize = 20;
}
\$\endgroup\$
2
  • 2
    \$\begingroup\$ Make the GlobalControl class static (nobody will be able to call new GlobalControl, which is pointless) and the lists public static readonly. For the lists, this means that you will not be able to assign another list after initialization. This ensures that all the scenes will be referencing the same lists. The list content itself remains read/write. \$\endgroup\$ Dec 18 '18 at 17:32
  • \$\begingroup\$ Yeah, that's a good idea. There's nothing to gain from leaving someone with a stale reference. I'll edit my answer to have that. \$\endgroup\$
    – Ruzihm
    Dec 18 '18 at 17:33
0
\$\begingroup\$

In unity, if you want to keep something across multiple scenes, use this:

void Awake(){
DontDestroyOnLoad(this.gameObject);
}

This will make the object its attached to, in this case your globals, remain in any scene called, until either you destroy the object manually or you close the application.

Once this is done, you will need to set it a tag. Then grab it by its tag by using:

GlobalControl globals = GameObject.findObjectWithTag("global").getComponent<GlobalControl>();

Note: I am assuming your tag is global, you will use this in the awake of the OTHER script. any variables you want access to must be public. Then, you can use:

global.orderItemsList.Add("Your new string");

or any other such public method.

Also note that, loading the scene with this object more than once will cause things to work in unexpected ways.

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.