As you likely noticed when testing the Places scene UI, you can't actually sell a monster just yet. That is because we need to add a few new tables to our database (Inventory). Fortunately, as you may recall that since our database is an ORM (object relational mapping), the work of creating new tables is quite painless.
So, open up the InventoryService
script located in the Assets/FoodyGo/Scripts/Services
folder, in the editor of your choice. Scroll down to the CreateDB
method, and look for the new section following code after the highlighted line to create the new tables in the database:
Debug.Log("DatabaseVersion table created."); //look for this line to start
//create the InventoryItem table
var iinfo = _connection.GetTableInfo("InventoryItem");
if (iinfo.Count > 0) _connection.DropTable<InventoryItem>();
_connection.CreateTable<InventoryItem>();
//create the Player table
var pinfo = _connection.GetTableInfo("Player");
if (pinfo.Count > 0) _connection.DropTable<Player>();
_connection.CreateTable<Player>();
That code just adds the new tables, InventoryItem
, and Player
to the database. Next, scroll down a little further in the same method, and look at the code required to create a new starting player after the highlighted line:
Debug.Log("Database version updated to " + DatabaseVersion);
//start here
_connection.Insert(new Player
{
Experience = 0,
Level =1
});
After adding the new tables in the CreateDB
and populating with a starting Player
, the UpgradeDB
method was updated as well. The old UpgadeDB
was replaced with the following code:
private void UpgradeDB() { var monsters = _connection.Table<Monster>().ToList(); var player = _connection.Table<Player>().ToList(); var items = _connection.Table<InventoryItem>().ToList(); CreateDB(); Debug.Log("Replacing data."); _connection.InsertAll(monsters); _connection.InsertAll(items); _connection.UpdateAll(player); Debug.Log("Upgrade successful!"); }
If a database upgrade is triggered, then the UpgradeDB
method will run. It will first store the values in the current tables in temporary variables, then the CreateDB
method is run to create the new database tables and finally that data is inserted or updated back in the database. Being able to upgrade the database in this manner allows us to add new properties to an object. However, we can never delete or rename existing properties as that would likely break the old objects.
Now that the tables are in place, we can add the CRUD methods for our new tables, InventoryItem
and Player
. Scroll to the bottom of the InventoryService
file and look at the following new methods:
//CRUD for InventoryItem public InventoryItem CreateInventoryItem(InventoryItem ii) { var id = _connection.Insert(ii); ii.Id = id; return ii; } public InventoryItem ReadInventoryItem(int id) { return _connection.Table<InventoryItem>() .Where(w => w.Id == id).FirstOrDefault(); } public IEnumerable<InventoryItem> ReadInventoryItems() { return _connection.Table<InventoryItem>(); } public int UpdateInventoryItem(InventoryItem ii) { return _connection.Update(ii); } public int DeleteInventoryItem(InventoryItem ii) { return _connection.Delete(ii); }
The code is almost the same as the Monster CRUD code we wrote in a previous chapter. Now, look at the CRUD code for the Player
:
//CRUD for Player public Player CreatePlayer(Player p) { var id = _connection.Insert(p); p.Id = id; return p; } public Player ReadPlayer(int id) { return _connection.Table<Player>() .Where(w => w.Id == id).FirstOrDefault(); } public IEnumerable<Player> ReadPlayers() { return _connection.Table<Player>(); } public int UpdatePlayer(Player p) { return _connection.Update(p); } public int DeletePlayer(Player p) { return _connection.Delete(p); }
You may be wondering why we need all the CRUD methods for the Player. We put them there so that our game could be used to handle multiple players later either by allowing a user to choose different characters to play with or perhaps even allowing multiple players to play together.
Next, we want to jump back to the Places scene and run an upgrade to our database so that the new tables are all there. Ensure that you save all your scripts, and go back to the Unity editor. Find the InventoryService
object and select it in the Hierarchy window. In the Inspector window, change the Inventory Service - Database Version to 1.0.1 (assuming the current value is 1.0.0). Run the Places scene in the editor, and check the Console window. Look for the Upgrade Successful log message to ensure that your database is upgrading correctly.
With the InventoryService
code and database updated, now we need to perform the exchange of the player where they will give the monster to the place and receive their experience and items in return. Open up the PlacesSceneUIController
script in your editor and scroll down to the AcceptOffer
method:
public void AcceptOffer() { OfferDialog.SetActive(false); SellButton.SetActive(true); var offer = CurrentOffer; InventoryService.Instance.DeleteMonster(offer.Monster); var player = InventoryService.Instance.ReadPlayer(1); player.Experience += offer.Experience; InventoryService.Instance.UpdatePlayer(player); foreach(var i in offer.Items) { InventoryService.Instance.CreateInventoryItem(i); } }
The top two lines of this method just enable/disable dialog and button. Then, we use those CRUD methods to remove the monster from the inventory. Next, we update the player's experience and then add the items to the new InventoryItem
table. We won't be using those new items in this chapter, but we now have a place to store new inventory.
Return back to the Unity, and run the Places scene. Now, try selling the monsters. You should notice that monsters are getting sold to the place. Verify this by going back and continually selling more monsters. Each time you sell a new monster, they will likely have a new name and other skills.
While you are running the game from the editor, the Inventory Service will make sure that there is always a random monster in the Inventory. This is done for debugging purposes. However, if you do encounter that a place is not able to buy your last monster, this can stall your testing. Consult Chapter 10, Troubleshooting, for tips on how to inspect and modify the database directly.
Our Places scene is complete for now. Feel free to extend the elements in the scene to however you desire. In the next section, we will add the Places scene back into the game and allow the player to visit a place.
18.191.186.72