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

Save the inventory items to the database

Discussion in 'Scripting' started by Yunnan, Mar 14, 2015.

  1. Yunnan

    Yunnan

    Joined:
    Jan 9, 2015
    Posts:
    10
    Hi guys, I am making a RPG which can save and load from the database, I can retrieve other values (such as Character Status, Health Point, Maximum Health Point, Exp, Next Exp and so on (it is only single value, which I am not show it here both for the C# and PHP code, I apologize). However, Inventory comes with multiple values (for example: Inventory have items more than 1), I can save and load that Inventory, but it is only returns the last value which is absolutely wrong. So I changed it from single int getter and setter value to List getter and setter instead, but when I run and save it, it gives me an error which is null in the for loop in GameManager class and "Failed to save items to the database" in SaveItem function in UserInventory class:

    Here is the code that I am using:

    ItemManager class contains the informations which required for the each item (buy value, sell value, name, description and so on)

    Save and Load function in UserInventory class:

    Code (CSharp):
    1.     public static List<ItemManager> inventory= new List<ItemManager>();
    2.    
    3.     public static void SaveItem()
    4.         {
    5.             try
    6.             {
    7.                 for (int i = 0; i < inventory.Count; i++)
    8.                 {
    9.                     ItemManager.SavedInventory[i] = inventory[i].itemID;
    10.                 }
    11.             }
    12.    
    13.             catch
    14.             {
    15.                 Debug.LogError("Failed to save items to the database!");
    16.             }
    17.         }
    18.    
    19.     public static void LoadItem()
    20.         {
    21.             try
    22.             {
    23.                 for (int i = 0; i < inventory.Count; i++)
    24.                 {
    25.                     inventory[i] = ItemManager.SavedInventory[i] >= 0 ? ItemDatabase.items[ItemManager.SavedInventory[i]] : new ItemManager();
    26.                 }
    27.             }
    28.    
    29.             catch
    30.             {
    31.                 Debug.LogError("Failed to load items from the database!");
    32.             }
    33.         }
    34.  
    Here is where I cast the PHP code from the website in GameManager class:

    Code (CSharp):
    1.     public static void WebsiteConnect(string link)
    2.     {
    3.         WWW www = null;
    4.    
    5.         wwwForm = new WWWForm();
    6.    
    7.         for (int i = 0; i < UserInventory.inventory.Count; i++)
    8.         {
    9.            wwwForm.AddField("Inventory", ItemManager.SavedInventory[i]);
    10.         }
    11.    
    12.         www = new WWW(link, wwwForm);
    13.     }
    14.  
    Here is where I call it:

    Code (CSharp):
    1.     private void OnGUI()
    2.     {
    3.     if (GUILayout.Button("Save", customStartButton.customStyles[0]))
    4.     {
    5.        GameManager.WebsiteConnect("WEBSITE_ADDRESS/Save.php");
    6.    
    7.        UserInventory.SaveItem();
    8.     }
    9.    
    10.     if (GUILayout.Button("Continue", customStartButton.customStyles[0]))
    11.     {
    12.        GameManager.WebsiteConnect("WEBSITE_ADDRESS/Load.php");
    13.    
    14.        for (int i = 0; i < UserInventory.inventory.Count; i++)
    15.        {
    16.           ItemManager.SavedInventory[i] = int.Parse(jsonObject["Inventory"].Value);
    17.        }
    18.    
    19.        UserInventory.LoadItem();
    20.     }
    21.     }
    22.  
    Here is the PHP code for the Save.php and Load.php:

    Save.php:

    Code (CSharp):
    1.     <?PHP
    2.    
    3.     $Inventory = $_POST['Inventory'];
    4.    
    5.     $con = mysql_connect("WEBSITE_ADDRESS","DATABASE_NAME","PASSWORD") or ("Cannot connect!"  . mysql_error());
    6.    
    7.     if (!$con)
    8.         die('Could not connect: ' . mysql_error());
    9.    
    10.     mysql_select_db("DATABASE_NAME" , $con) or die ("Could not load the database" . mysql_error());
    11.    
    12.     $check = mysql_query("SELECT * FROM Information WHERE `Username`='".$Username."'");
    13.    
    14.     $numrows = mysql_num_rows($check);
    15.    
    16.     if ($numrows > 0)
    17.     {
    18.         $ins = mysql_query("UPDATE `Information` SET Inventory = '".$Inventory."'WHERE Username = '".$Username."'");
    19.    
    20.         if ($ins)
    21.             die ("Successfully Saved!");
    22.    
    23.         else
    24.             die ("Error: " . mysql_error());
    25.     }
    26.    
    27.     else
    28.     {
    29.         die("Data does not exist!");
    30.     }
    31.    
    32.    
    33.     ?>
    34.  
    Load.php:

    Code (CSharp):
    1.     <?PHP
    2.    
    3.     $Inventory = $_POST['Inventory'];
    4.    
    5.     $con = mysql_connect("WEBSITE_ADDRESS","DATABASE_NAME","PASSWORD") or ("Cannot connect!"  . mysql_error());
    6.    
    7.     if (!$con)
    8.         die('Could not connect: ' . mysql_error());
    9.    
    10.     mysql_select_db("DATABASE_NAME" , $con) or die ("Could not load the database" . mysql_error());
    11.    
    12.     $check = mysql_query("SELECT * FROM Information WHERE `Username` = '".$Username."'");
    13.    
    14.     $numrows = mysql_num_rows($check);
    15.    
    16.     if ($numrows > 0)
    17.     {
    18.         while($row = mysql_fetch_assoc($check))
    19.         {
    20.             if ($Username == $row['Username'])
    21.             {
    22.                 echo json_encode($row);
    23.             }
    24.    
    25.             else
    26.             {
    27.                 die ("Saved data does not match!");
    28.             }
    29.         }
    30.    
    31.         die();
    32.     }
    33.    
    34.     else
    35.     {
    36.         die ("Data does not exist!");
    37.     }
    38.    
    39.    
    40.     ?>
    41.  
    The reason why I did not use PlayerPerfs is because I have Login and Register feature (I am not sure if PlayerPerfs can compare the LoggedInUser or not, so I decided not to use PlayerPerfs), so each player will have it is own Inventory, Character Status and so on, which you can imagine like RPG.

    Your answer much appreciated!

    Thank you so much!
     
  2. Glockenbeat

    Glockenbeat

    Joined:
    Apr 24, 2012
    Posts:
    669
    In our WebsiteConnect you are posting formdata. Your loop actually does exactly what you describes - it sets a form field "Inventory" with the current loop's value, which will in the end result in one "Inventory" post form field with the last value of the loop.

    Try to set
    Code (CSharp):
    1. wwwForm.AddField("Inventory_" + i, ItemManager.SavedInventory[i]);
    and see what happens.

    (Didn't have a too close look at the rest of the code)
     
  3. Yunnan

    Yunnan

    Joined:
    Jan 9, 2015
    Posts:
    10
    Thank you for replying this question sir @Glockenbeat. However, I have changed based on what have you suggested, and also I have changed the $Inventory = $_POST['Inventory'] to $Inventory = $_POST['Inventory_'] in Save.php and Load.php, but it still gives me null and "Failed to save items to the database" sir.
     
  4. Glockenbeat

    Glockenbeat

    Joined:
    Apr 24, 2012
    Posts:
    669
    What the loop does is that it creates a couple of fields, depending on the loop variable i.
    So you will never get "Inventory_", but instead "Inventory_0", "Inventory_1", "Inventory_2"... and so on. You'll need to reflect that in your PHP methods.

    However as you can see from this example, you might potentially never know what you will save and what you will load and thus you will need to somehow handle the request body in a more generic way than just iterating over the wwwform. That is not what you want.

    Instead you should have a look at serializing data to JSON and use that to handle the exchange of post data. I personally prefer Json.Net, there's an implementation for Unity as well on the asset store. That's help de/serializing data in Unity. If you want to stick to PHP you'll need to find a way to de/serialize the stuff there as well, haven't used PHP too much. For .Net or NodeJs and alike you'll find many many serializers around, and I strongly assume that is the same for PHP (if you don't want to build your own serializer, which should not be necessary).
     
    Last edited: Mar 14, 2015
  5. Yunnan

    Yunnan

    Joined:
    Jan 9, 2015
    Posts:
    10
    Thank you sir for your replying and info.. I will try to find another way, and I just thinking about this from yesterday, there is no other way to achieve this instead of cast every slots in the inventory and save it to the database.