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. We have updated the language to the Editor Terms based on feedback from our employees and community. Learn more.
    Dismiss Notice

Programmatically creating UI buttons from a database?

Discussion in 'Scripting' started by idameyer8, Mar 17, 2022.

  1. idameyer8

    idameyer8

    Joined:
    Feb 7, 2022
    Posts:
    16
    I developed a browser-based resource management game last year and I want to recreate it in 3d. I am new at Unity and have taken some courses through Unity Learn. I have a mysql database up and running and I want to make a list of users with clickable buttons to go to their profile pages. So far I have been able to grab a list of usernames and show them in the game window, but how can I make a clickable button for each user? At the moment all of the users are just mashed together and I can't separate them out into different "items" to put in a button text

    Code (CSharp):
    1.    
    2.     public Text userList;
    3.     public GameObject buttonPrefab;
    4.     public RectTransform ParentPanel;
    5.  
    6.     void Start()
    7.     {
    8.         GenerateButtons();
    9.         GetUsers();
    10.     }
    11.  
    12.     void GenerateButtons()
    13.     {
    14.         for (int i = 0; i < 5; i++) //this isn't helping, this code has no way of knowing how many users there are
    15.         {
    16.             GameObject goButton = (GameObject)Instantiate(buttonPrefab);
    17.             goButton.transform.SetParent(ParentPanel, false);
    18.             goButton.transform.localScale = new Vector3(1, 1, 1);
    19.  
    20.             Button tempButton = goButton.GetComponent<Button>();
    21.             int tempInt = i;
    22.         }
    23.     }
    24.     void GetUsers()
    25.     {
    26.         using (UnityWebRequest www = UnityWebRequest.Get("link to the php code below"))
    27.         {
    28.             yield return www.Send();
    29.             if (www.isNetworkError || www.isHttpError)
    30.             {
    31.                 Debug.Log(www.error);
    32.             }
    33.             else
    34.             {
    35.                 //show results as text
    36.                userList.text = www.downloadHandler.text;
    37.             }
    38.         }
    39.     }
    40.  
    php code:

    include("config.php");
    $result = mysqli_query($mysqli,"SELECT * FROM users ");
    while ($row = mysqli_fetch_array($result)) {
    echo $row["username"];
    echo "<br>";
    }
     
  2. Chris-Trueman

    Chris-Trueman

    Joined:
    Oct 10, 2014
    Posts:
    1,256
    Depending on how the list is separated, which looks like its one per line, you could do.

    Code (CSharp):
    1. string[] usernames = www.downloadhandler.text.Split('\n');
     
  3. idameyer8

    idameyer8

    Joined:
    Feb 7, 2022
    Posts:
    16
    Ok! I was watching a tutorial about this and thought it may be a solution. I will be fetching data from the database pretty often, is it necessary to make a new php document for each thing I want to do or can I make methods within the php that I call from C#?

    After finding the usernames and attaching them to the buttons, I want to also attach an ID number to the button that I can use to populate fields in a profile page scene.
     
  4. Chris-Trueman

    Chris-Trueman

    Joined:
    Oct 10, 2014
    Posts:
    1,256
    Try to avoid lots of calls to the server, especially when your creating new objects on the heap that will be discarded to be collected by the garbage collector.

    You can actually send more information than just a username each time. Each entry can be separated by line, while each piece of data for the user can be separated by comas. You can make a c# class that holds this information for you

    Code (CSharp):
    1. public class UserData {
    2.     public string username;
    3.     public int id;
    4. }
    5.  
    6. string[] users = www.downloadhandler.text.Split('\n');
    7. UserData[] usersData = new UserData[users.length];
    8. for (int i = 0; i < users.Length; i++)
    9. {
    10.     string[] data = users.Split(',');
    11.     UserData uData = new UserData();
    12.     uData.username = data[0];
    13.     uData.id = System.Int32.Parse(data[1]);
    14.     usersData[i] = uData;
    15. }
    16.  
    Based on your php code, which is probably wrong as I have never done php before.
    include("config.php");
    $result = mysqli_query($mysqli,"SELECT * FROM users ");
    while ($row = mysqli_fetch_array($result)) {
    echo $row["username"],$row["id"];
    echo "<br>";
    }

    Once you have the data you want for the users, its just a matter of instantiating your buttons and associating the data with that button. This is quite open ended as it is based on how your buttons are setup and which UI you are using.
     
  5. idameyer8

    idameyer8

    Joined:
    Feb 7, 2022
    Posts:
    16
    Thanks for this explanation! Things are starting to make more sense. I'll work on this a bit and let you know how it goes. So grateful that there are helpful people willing to assist!
     
  6. Kurt-Dekker

    Kurt-Dekker

    Joined:
    Mar 16, 2013
    Posts:
    36,970
    For instantiating dynamic amounts of UI thingies, I always leave "Examples" in the UI hierarchy and duplicate them as many times as necessary, always making sure they are Instantiate<T>ed with a parent argument.

    See example attached.
     

    Attached Files:

  7. Stardog

    Stardog

    Joined:
    Jun 28, 2010
    Posts:
    1,890
  8. idameyer8

    idameyer8

    Joined:
    Feb 7, 2022
    Posts:
    16
    I get an error at "Split" here:
    Code (CSharp):
    1. string[] data = users.Split(',');
    the previous split worked fine, tried for ages to make it work but it should be able to do the splitting bit... I haven't even gotten to instantiating buttons yet :p
     
  9. idameyer8

    idameyer8

    Joined:
    Feb 7, 2022
    Posts:
    16
    Woah, ok so I can just connect directly to mysql from the C# script? This is blowing my mind, I feel like a complete pleb :p. Soo I fill in the server name and username and things in the unity editor and then just carry on as if I were working with mysql and PHP!
     
    Last edited: Mar 18, 2022
  10. WallaceT_MFM

    WallaceT_MFM

    Joined:
    Sep 25, 2017
    Posts:
    394
    Yes you can! In fact, C# has a language feature that is specifically designed to make this easier to deal with, check out LINQ (https://docs.microsoft.com/en-us/dotnet/csharp/programming-guide/concepts/linq/). It's a part of the standard library. You can use LINQ by adding a using statement to your script:
    using System.Linq;

    I often use LINQ even without a database because the list/collection extensions are so nice.
     
  11. Stardog

    Stardog

    Joined:
    Jun 28, 2010
    Posts:
    1,890
    I have never done it, but C# is used a lot for web development.

    Also, LINQ uses SQL naming conventions.
     
  12. idameyer8

    idameyer8

    Joined:
    Feb 7, 2022
    Posts:
    16
    I have to just sit a while and let this sink in. So many possibilities have opened up! Going to try this and let you know if I am eventually able to create those buttons :D
     
  13. Stardog

    Stardog

    Joined:
    Jun 28, 2010
    Posts:
    1,890
    You just need to try and fetch your data from the DB so that it arrives into a List or Array object. Splitting a string by lines seems a bad way to do it.
     
  14. idameyer8

    idameyer8

    Joined:
    Feb 7, 2022
    Posts:
    16
    Yeah, that's how I'm used to doing it from my browser based game
     
  15. idameyer8

    idameyer8

    Joined:
    Feb 7, 2022
    Posts:
    16
    I only post again because I have tried for hours now but this is giving me a CS0246 error:
    Code (CSharp):
    1. using MySql.Data;
    2. using MySql.Data.MySqlClient;
    I tried installing a nuGet for MySql but still have an error? any ideas?