Using the INotifyCollectionChanged interface in Unity
#gamedevelopment , #unity3d , #csharp , #3d , #programming , #gaming
Foreword
In the previous article I have presented the ObservableCollection data structure. By subscribing to its CollectionChanged event, services can be notified when single elements are added or removed. However, this also means that services will be notified repeatedly when multiple items are added or removed. To avoid repetitive updates, today's topic will be how to implement custom solutions using the INotifyCollectionChanged interface.
Abstract
There are countless solutions for many software problems. However, the problem is often that custom solutions are usually not very comprehensible. For this reason, it makes sense to adhere to certain standards. One solution is to implement widely used interfaces. This makes it easier for other developers to understand what a custom class is for. However, it is impossible to say with certainty how the class will ultimately behave.
This is illustrated below by the implementation of the INotifyCollectionChanged interface.
Design
Let's imagine that we need a quest log where multiple quests can be added at once. At the same time, we want the user interface to show the player all the new quests immediately. We could pass the data to two or more services individually. But that would mean that we now need further logic to keep the data in sync when quests change.
In the mentioned use case, it would probably be wiser to implement a data structure that manages data only in one place, but notifies other services that data has been added or removed.
Example 1
Below is the base class of a custom ScriptableObject that implements the INotifyCollectionChanged interface. It should be emphasized that System.Collection.IList is explicitly specified to create an instance of NotifyCollectionChangedEventArgs. If we do not pay attention to this, it can easily happen that System.Object is assumed as input type instead, which has undesirable effects on further processing. (In the 2nd example I will go into this in more detail.)
In Figure 2, a data class called Quest and a derived class of QuestLogBase are implemented. Nothing exciting happens here.
Recommended by LinkedIn
In Figure 3 you can see a script that represents a sequence of player events. Let's assume that new story missions are added to the quest log during the game when the player is talking with different NPCs. In this process the user interface is updated. (For the sake of simplicity the new quests are displayed on the developer console.)
Example 2
In Figure 4, the INotifyCollectionChangedExample1_CollectionChanged method is called twice.
Final Words
Implementing the INotifyCollectionChanged interface manually can be useful in certain situations. However, this can easily lead to new sources of error. So if you do not want to or cannot use existing data structures, you should be aware of this.
That's it for today.
What do you think about implementing the INotifyCollectionChanged interface manually? Do you think it's worth the effort, or do you prefer to use other existing solutions? Or do you think that I have forgotten an important aspect, then feel free to leave a comment.
And if you are interested in topics like #gamedesign, project organization or software design patterns, don't forget to press the Follow button on my profile page or add me as a contact. Not convinced yet? Well, maybe you will be once you read some of my other articles.