Design Patterns in Unity3D #1 - Observer
Observer is perhaps one of the most frequently used design pattern in game development. In games, we use lots of UI elements to display the current data of the player. That is where Observer pattern can come in handy. The basic idea is, the object that will be observed (lets call it Observable) will register any existing Observers to its list. Once Observable makes any change, it will give notification to all of the Observers in the list to update their state/display/information.
Lets give an example. Lets say, in a game, the player is the Observable, and the health bar is the Observer that will monitor the player's health. Everytime the player heals himself or receive damage, the player will notify the health bar that the amount of health has changed. The HP bar then will change its display, from a full (100%) bar to, let's say, 80%.
Lets see how basically this pattern works with Unity3D and C# programming language.
Lets create a C# script and name it Observer. Delete the Monobehaviour since we don't need that for this script. Change it from being a class to an interface. We will observe an object that has only 2 variables, hp and power. So create a method called update (it has to begin with lowercase) in the Observer interface, and we pass the hp and power as the parameter.
Next, lets create another new script called Observable and like before, change it from a class to an interface. This interface contains all the behaviors of the Observable that I mentioned earlier, which is to register, notify all of the listed Observers, and do something when its attribute/state changed.
Now lets create 2 new Unity game objects that will act as the observer. Name it Attribute Displayer and Slider Displayer.
Then, create AttributeDisplayer script in Attribute Displayer object and SliderDisplayer script in Slider Displayer object.
Both scripts extends MonoBehaviour and implements the Observer object.
Remember that both SliderDisplayer and AttributeDisplayer implement Observer, and now they can implement their own update() method.
SliderDisplayer will update the current and maximum value of the bar, while AttributeDisplayer will update its text display with the text that has been created by the StringBuilder.
The next thing that we want to do is to create the Obervable object with all of the Observable implementations. Make it abstract because we don't want to create any instances from this class.
As you can see, this class has list of observers as well as the attributes that will be observed, which are hit points and power.
OnAttributeChanged will be called after every changes in those attributes and OnAttributeChanged will call the notifyAllObserver. In the notifyAllObserver, we update all of the observers in the list.
After that, we will create the concrete Observable class. Lets create a cube, set its position to (0, 0, 0) and attach MyCube script in it.
MyCube script will derive from ObservableObject. In the start() method, register the Attribute and Slider Displayer by GameObject.Find() and get their respective Displayer by GetComponent<>().
Then, make assignRandomValueToAttribute method that will change the hit points and power value with a random number between 1-1000 (ignore the setHitPoints and setPower method), and then call the OnAttributeChanged() inside it.
Now we want to create a button that will call MyCube's assignRandomValueToAttribute() method when clicked.
Edit the text of the button. Put "Change Attribute Value" in the text field.
This is the final result. When you play, click on the button. The button will then change MyCube's value to random value and will notify all of the observers to update their values & display.
Thank you for reading this. Hope this gives you idea on how to implement Observer design pattern in game programming in Unity3D.