Design Pattern Practices

Has anyone else tried implementing software design pattens (MVC, Observer, Strategy, Interface, etc.) in Unity.

I get that it’s all cool and fun to have things visible in the inspector and let one script grab exposed variables from another, but it’s a general practice that I would never use in PHP, Java, or even JavaScript.

The GUI in particular makes it easy to break coupling rules with ease and is my current focus in the implementation of an MVC pattern with proper update callbacks and such.

Anyone else as anal as I am with this stuff, or is it Free Love for variables and methods in Unity?

Although Unity enables scripting using more “formal” languages such as C#, it IS scripting, and as such is intended for a wider audience (in terms of programming experience) than, say, VisualStudio.

Game scripting in particular is a little bit different beast, and I have personally written scripting systems in the past for game engines where, because the scripting was being done by non-programming game designers, I built in things like easy access to global and object-level variables.

I didn’t necessarily like it from a purist’s standpoint, but it made getting those non-programmers up and running SO much easier.

Just my $0.02

I think CogCode makes a good point here, that generally speaking you are not starting “tabula rasa” here, so there is an inherited tendency towards exposing variables and such, mostly targeted at quick prototyping, small projects, less technically inclined, and so on.

Having said that, I don’t think there is any inherent limitation.

For example;

I use a simple strategy pattern in my spell mechanic. When the player presses the right mouse button I execute whatever spell they currently have selected. This current spell object is swapped out for other spell objects as they use the scroll wheel.

I use Observer and Mediator/Manager type patterns pretty heavily. For instance, when the InputManager detects they player wants to jump, they call into my Mediator and notify that we are jumping. The Animation, Sound, and CharacterController managers are all “listening” to this event, so the SoundManager plays the Jump sound, the AnimationManager starts the jump animation and the CCManager launches the player into the air.

Note, that I am not using the BroadcastMessage built-in function, but rather a Delegate dictionary, where each key in the dictionary (i.e. “Jump”) contains a multicast delegate which is piggybacked with as many listeners as needed. Not that it usually matters but this is about 35% faster than BroadcastMessage and generally cleaner.

Note: I did originally write this where my components where inherited from an AbstractCommunicator where they would self-register with the concrete meditor, I then changed it to a singleton manager with abstract communicators using reflection and method attribute decoration to subscribe to certain events, but now I’m just manually subscribing to events on the Awake call of my object. Not really sure how or why it evolved.

At any rate, I’m only meaning to say that I think in most cases you are not limited in what you can do (at least in C#).

Another small example is terrain footsteps; I have a class that monitors which part of the splatmap my character is walking on and, from that, determines what their footsteps should sound like. I could expose this as a variable that is viewable from other scripts, but instead I instantiate an object that listens for “Step” events, and knows how to respond correctly. This allows me to change the sound of walking on sand versus walking in grass, but I can extend this object to provide other effects too, such as dust particles, footsteps, moving grass, ect… as needed.

Now, on the other side of this; I’m not working on a team, and I mostly doodle with ideas, so my implementations have not been “stress tested”, so take all my advice with a grain of salt, but thus far I have not come up with an idea, architecturally speaking, that I could not do.

It’s not true MVC, maybe, but;

if (Gui.Button(rect, Character.Data[“CurrentNumber”]))
{
Character.RandomizeNumber();
}

At least here you are not exposing literal variables, as the logical meaning of “CurrentNumber” can change, and the business logic (randomizenumber) is not in your gui code, only the user intent is coded.

The wiki contains at least 2 other versions of “managers” and “notification centers” (and the notification center is in JS), so you may want to look at those too.

Um, hope this rambling helps.

Charles

It seems like we’re all in the same place on this. Unity’s ease has been great to get a noob team up quickly, but for those of us with more oop experience, it wants for structure. The Observer pattern definitely gets a lot of use here!

As had already been mentioned, Mono runs .Net 2.0, so from C# you can use any pattern that doesn’t rely on 3.0 features.

The only area where you may run into issues is with UnityScript, as it doesn’t support some of the needed language features such as Generics. You could probably hack it enough to at least get most working in UnityScript if you wanted.

If you are working on a more solid OOP framework C# is more suited anyway, but it’s worth mentioning.

-Jeremy

As a note, last I checked UnityScript didn’t support multicast delegates, just single cast, so you want to keep that in mind also if you choose UnityScript.

-Jeremy

I implements MVC pattern for login/registration functionality.
See my post http://unity-tutorials.blogspot.com/