Using the INotifyCollectionChanged interface in Unity

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.)

Es wurde kein Alt-Text für dieses Bild angegeben.
Figure 1

In Figure 2, a data class called Quest and a derived class of QuestLogBase are implemented. Nothing exciting happens here.

Es wurde kein Alt-Text für dieses Bild angegeben.
Figure 2

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.)

Es wurde kein Alt-Text für dieses Bild angegeben.
Figure 3

Example 2

In Figure 4, the INotifyCollectionChangedExample1_CollectionChanged method is called twice.

  • The first time, all new quests are printed on the developer console.
  • The second time, however, the number of new quests is printed on the console. The reason is that the NotifyCollectionChangedEventArgs class has multiple constructors and interprets the instance of System.Collections.Generic.IList<T> as well as many other types as System.Object. So e.NewItems does not contain two instances of Quest, but instead a list with two Quests.

Es wurde kein Alt-Text für dieses Bild angegeben.
Figure 4

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.

To view or add a comment, sign in

More articles by Lars Wobus

  • Brief introduction of my main game mechanics

    As some readers of my newsletter already know, I'm currently developing a turn-based strategy game, among many other…

  • UI & UX design from a Programmer's Perspective

    As some people already know, I'm currently developing a strategy game as part of my second master's degree at the…

  • Asset and Project Management for Indie Game Developers

    This week, I want to talk about Miro, which my tutors and comillitons recommended to me some time ago. It's an online…

  • Unfinished Unity Projects (Round 2)

    #Unity #3D #Blender Foreword Welcome back to episode 20 of my newsletter. For this particular episode, I thought we'd…

  • Greyboxing in Blender

    Hello fellow game devs and hobbyists and welcome back to the next episode of my newsletter. This time I will talk about…

  • The importance of a core gameplay loop

    The need for a good gameplay loop can be summed up in one sentence. If the main game mechanics are flawed or not…

    1 Comment
  • Data Analysis before, during and after Live Events

    #marketing - #games - #gaming - #gamedevelopment - #videogames On Friday, April 14, 2023, I visited the game festival…

  • Paper Prototyping in Game Development

    Foreword Last week one of the instructors at the University of Applied Science in Dresden said that he insists that I…

  • Data Driven Marketing - About Touchpoints and Customer Journey

    Foreword In the past, it was enough to advertise new products widely to boost sales. But that is no longer sufficient!…

  • Market Research for Game Developers

    Foreword Only a few people already know that I have started a second master study on the subject of Games and XR…

Others also viewed

Explore content categories