vendredi 29 avril 2016

Clean use of design patterns in Unity

My students have learned OOP as well as the strategy design pattern during the first semester (Processing/Java), which lead to understanding Unity's component based architecture (similarity of strategy and component pattern).

In the second semester they dive deeper into Unity programming, while applying OOP patterns like the Observer Pattern to keep the code clean and independent. The example I have for them is a box-shaped trigger zone that opens a simple door when an actor enters, and closes the door when he exits. So far so good. But what if we want to open several doors -> observer pattern.

So in the first run we create a nice generic trigger script (our "Subject" in the sense of the observer pattern) that notifies observers of enter and exit events (within Monobehaviour's OnTriggerEnter() and OnTriggerExit()). This doesn't know much about the observers getting notified except that they implement e.g. an interface IDoorBehavior with open/close methods. We implement this once using the built-in UnityEvent mechanism and once using C# delegates/events and discuss pros and cons.

In the Start() function of the trigger script, we gather all objects that derive from an abstract class Openable : Monobehaviour using FindObjectsOfType() (can't use plain interfaces here because Unity demands this method be called with a type derived from Monobehaviour). Then for each of these Openable objects found we add the Open/Close methods to the event/delegate list to be notified.

So here we have the (I feel unusual) issue that the subject searches his observers an forces them to observe them. "You better observe me, or else...". Shouldn't the observers do this?

What if we foresee that in the future there will be different types of doors that can be opened by specific triggers/actions. How to design that in a flexible and clean fashion?

I plan to use the strategy pattern (known to the students) in order to have different open/close behaviors for doors (slide up/down, hinges, etc.).

Later I also want to create a classic pick-up-the-object-and-put-it-to-inventory example in a clean patterny way, so we have a neat sandbox with exemplary scripting design for the students to learn, extend, and design their own games.

So overall I'm looking for insightful comments from experienced OOP/pattern cowboys that might help improve the design and just "get it right" (I know there is not one "right" solution to these problems).

Aucun commentaire:

Enregistrer un commentaire