Uncommon Data Collections in C# and Unity

In this article, I will introduce two C# collections which can be quite handy for game development

Omid Reza Izadi
The Startup
5 min readDec 29, 2020

--

an inventory sample, from the Genshin Impact game

Article’s repository: https://github.com/omidizadi/sorted-observable-inventory

I was playing Genshin Impact the other day and noticed that my items in the inventory are always sorted by their tier, star, or level. I thought that it should be easy to implement. But I always like to know my options.

These two collections that I will talk about, has been used more often by .Net developers than Unity programmers.

SortedList

Almost all common data structures such as list, dictionary, or hash set has an equivalent sorted type.

SortedList, SortedDictionary, and SortedSet are all built-in C# collections. As you can guess, their job is to sort the elements each time you add or remove them. But the important thing here is the way a SortedList compares the elements. What happens if we try to store GameObjects? How a GameObject comparison is handled?

Let's find out with an example.

Sorted Inventory

I created a super simple scene with a bunch of balls as collectible items, a canvas to show the inventory UI, and a terrain to hold the balls (didn’t want it to look too simple!)

Then I implemented two interfaces for my collectibles and inventory:

First I implemented an abstract inventory to be able to retrieve its instance in the scene:

I used the Singleton pattern here for ease of use, but I will be cautious about not letting my dependencies hide between codes because of that.

Then I implemented a concrete version of ICollectible for the balls and defined three tiers (T1 for grey, T2 for purple, and T3 for purple).

Now by each click on the balls, they add themselves to the inventory and disappear.

The sorted inventory would be like this:

As you can see I used a SortedList to store the items. I forgot to mention that all sorted collections receive a key-value pair as an element and sort them by the key. If you give an int, float, enum, string, or char as a key, by default it will sort them in ascending order. But there is a problem! SortedList doesn’t accept duplicated keys! We know that in some circumstances, we must store duplicated items in a sorted collection, like this example that I want to store different items with the same tier. The solution is to give the SortedList your own implementation of IComparer!

With this, my SortedList will sort items in descending order (because T3 items are more important thus should be seen first) and treat the same tiers as greater.

Note that IComparer interface is generic, therefore you can implement the comparison for anything you desire such as GameObjects, Vectors, Raycasts, absolutely anything.

in the SortedInventory class, I stored the OnItemCollected event for any class that wants to get notified when something is being collected.

So I created a UI class to show my inventory:

Now everything is set and ready:

ObservableCollection

In the previous section, you saw that I used the OnItemCollected to let other classes subscribe to my inventory events. But now I want to use a collection that has the same built-in functionality. ObservableCollection gives us the ability to subscribe to its changes.

Same as the previous example, I made a scene with a bunch of GameObjects (this time cubes in two colors)

I want to collect cubes with a single click and add them to my collection. I also need to update my UI whenever something is collected but this time I won’t use a C# event. First my CubeCollectible class:

It’s almost the same as the SphereCollectible with different Type enum.

Now for the inventory, I use an encapsulated ObservableCollection:

Other classes can subscribe to this collection by adding an event to its CollectionChanged. like this:

This script adds the UpdateInventoryUI to our ObservableCollection to show equivalent UI items when an item is collected. I attach this script to two components for each color inside my canvas:

Now we play the scene:

As you can see those two UI components are notified by the ObservableCollection and update the UI if the collected cube color is the one they’re looking for.

You can find the source code at this Github repository. Make sure to check out my website and follow me on Linkedin and ask your questions if any.

Thank you for your time!

--

--

Omid Reza Izadi
The Startup

7+ years in game development, key contributor to major projects, skilled game programmer. Helped captivate 100K+ players. Committed to continuous growth