[MVVM, DI, IoC and others...] Bringing order to chaos question.

Hi Unity users,
hopefully this is the right place to ask this.

Short-story:

  • Has any of you got any experience/advises to share regarding MVVM, DI and IoC in Unity3D? Any success stories to share? Which packages/assets from the store you used (if any).
  • Have you tried NData combined with StrangeIoC or Zenject (why one over the other?)
  • The UnityTestTools?

Long-story:

  • I’m trying to move forward in Unity experience by making a small experiment. It’s basically a Tycoon type of small prototype. Why a Tycoon? From the outside it might look very simple, but it’s actually a quite complete experience… it has lots of UI work, gameplay logic, metagame, social integration, multiplayer, several screens and play modes, data persistence, they lend themselves to IAPs (since they are mostly free to play nowadays), etc.

  • My background is C#, XNA days, where I learned to program, mostly gameplay and graphics programming. A few of the games that I started with some friends in those days got really far, prizes and all… however, they get to a point where change is extremely resistant, adding any little feature becomes a daunting task, etc you know the drill. Game never gets finished.

  • Since WPF, XNA/Silverlight integration efforts of the community and others, MVVM (and similar design patterns) came to light with MVVMLight Toolkit, Dependency Injection and IoC libraries, Unit Testing, etc… sounded very interesting.

  • To be honest, without a specific project at hand to try these out, my time was just spent reading about them, understanding about ‘Mocks’, best practices, etc… documentation and examples is infinite (I wonder if, for me, it is just faster to just hack away code).

  • Coming back to Unity, these type of libraries start surfacing once again. And with good reason, Unity’s SendMessage or any other of Stringified events seems like a nice a idea for the first 20minutes of usage.
    It would be nice to give them a fair try. Except that I’m again at that infinite loop-hole trying to understand and find ‘the perfect’ usage for these.

I have gone on a shopping spree… got NGUI, FullInspector (seriously recommend this one), NData, FingerGestures, etc…
I ask of you:

  • Have you tried gluing these all together successfully in a lean way? Do you do UnitTesting at all?
  • Have you used Zenject (has nice features, for example, the ITickable interface, basically an equivalent for XNAs IUpdateable)
  • Have you used StrangeIoC (comes with a feature complete signals system, that is GC friendly. And a Bind-Anything-To-Anything framework)
  • NData?

MVVM question:

  • What do you think of Monobehaviors? People seem to recommend to use this as a ‘View’… however, these can objects can have: Colliders, Meshes, Animations, Custom classes, and many many more components attached to it (and it’s expected to be like that). Sounds like a super-fat view in my opinion.
  • StrangeIoC proposes the approach of ‘Mediators’ which is another Monobehavior that does the middleman between the target monobehavior and some business logic.

Am I asking the right questions? Anything you would like to advise (i.e. ‘just code away’ : p)

Cheers and thanks!

## Editing to have more info on the acronyms used mercilessly:
MVVM: Stands for Model-View-ViewModel. Design pattern that tries to separate the concerns of an UI (View), Data (Model) and the BusinessLogic (ViewModel). Very similar to others like Model-View-Presenter, Model-View-Controller, etc. The idea is to seriously decouple the UI from the logic of the application… changes and notifications are done via ‘Commands’ and ‘Events’.
IoC: Stands for Inversion Of Control. Classes don’t have the control of instancing new classes (mostly) anymore. Somebody does it for them.
DI: Dependency Injection. The idea is that classes are and logic are programmed towards interfaces. Specific or concrete implementations are ‘injected’ to the classes that require it. i.e.

  • You have a Character, and it uses an IWeapon? he will get it, magically.
  • But which one?. You would configure it via an IoC. in the IoC you can say Bind().To(); Everytime something needs an IWeapon it would give it a NetworkEnabledWeapon. Your character code would not change.
  • You have levels. They use IEnemyFactory. You want a singleton for all your levels: Bind.To().Single(); (syntaxes depend on the IoC of choice).

NData: on the Asset Store. Add-on, for NGUI enabling it to use MVVM (see above). Bought already, haven’t used it. Judging from the videos it looks very impressive. Kudos to them for coming up with this.
FullInspector2 Asset Store. Unity’s inspector and serializing capabilities in overdrive mode. List, Dictionaries, Generics, Interfaces, you name it… all of that becomes serializeable and shows on your inspector windows for easy configuration. This description doesn’t do it full justice. Really.
StrangeIoC and Zenject: Inversion of control libraries. Still wrapping my head around which one to choose. For my specific situation at hand.

I wouldn’t want to say “MonoBehaviour” and “MVVM” in one sentence. I think they have almost no overlapping at all.
A MonoBehaviour is not a view, it is a… very distinctive component. For me, it is almost always data, sometimes controller. But view? Maybe the renderer :wink:
Its like an extendable class with multi-inheritance. Or interfaces with actual code.

I want a weapon? Okay, take a renderer. Oh, it should move? Add an animator. It should shoot? Add a script for instantiating bullets with velocity.
I think you overcomplicate it, if you try to fit it in some of those pattern.

You can use some ioc, but I won’t put everything on that just for fun. Sometimes it is nice to not register anything anywhere. Every object in the scene can be independent (at least for you, unity will still call start, awake, update etc).
There is no need for a mediator, if a script says “if I bump into something, I will explode”. You can put something inbetween, but… why?

Truthfully, I had to look up some of the original posters terms.

We use MVP here, which sounds a lot like MVVM. We use a C# Model, loaded into a MonoBehaviour Presenter (aka middleman), connected to another MonoBehaviour View that has all our labels, animations, whatever as children. Sometimes we’ll have child MVPs run by master MVPs for complicated stuff.

I can’t give you any advice about those plugins. We’ve coded a lot of that stuff in-house already, so we haven’t needed to use plug ins.

One thing I will say about game development… some design patterns are really useful, but trying to fit your game into a design pattern just doesn’t work sometimes.

Usually it’s the other way around. We have a problem that we’re trying to solve, and there’s a design pattern that matches what we need.

I found this to be kinda helpful… http://wiki.unity3d.com/index.php/Dependency_injection

The hill I’m trying to get over is the quirky limits on keeping things serialized…

because this is easy to have serialized, as you can drop it in as inherited (err… ok, a component):

public class myBase : Monobehaviour
{
   [SerializeField]
   public string _important;
}

but if you start working with ScriptableObjects instead of Monobehaviours things seems to get wonky… atleast they have been so far for me with relation to a List where T perhaps references a base class of type ScriptableObject.

there is apparently a way to do it, but requires you to have a framework setup to retrieve the data from a static file on any play mode and/or selection change… which just seems weird to me.

so can you do any of those “best practices and patterns”… I suppose you could, but you’ll find some odd things just in the way Unity is setup… which is probably not odd to the purpose of this component development style, it just is not what I had been learning with those other standards and best practices.

@tswalk: I think that maybe the problem with List is definitely an Unity drawback. As far as I understand it, it will only serialize Arrays[ ] of a specific type. That’s where I decided to use FullInspector2 from the get go… it allows to serialize lists, dictionaries, generics, interfaces, abstract clases, you name it. It goes long distances with it’s features like:

public SplashDamageWeapon : IWeapon
{
     public float DamageArea;
     // (rest of IWeapon interface implementation)
}

public MachineGunBurstWeapon : IWeapon
{
    public float FiringRate;
    // (rest of IWeapon interface implementation).
}

public EnemyBehavior : Monobehavior
{
    public IWeapon weapon;
    void Start(); void Update(); etc.
}

If you assign this script to a Monobehavior (or equivalently on ScriptableObjects if the script is of scriptable object class). You will be able to, via the editor, choose which of the available implementations of IWeapon you want, and after choosing the concrete class, modify that specific implementation properties (i.e. if you choose machine gun the editor will show you the FiringRate parameter and if choosing SplashDamage one it will show you the DamageArea parameter.
You can even go as far as List weapons;
It will all serialize properly. Probably that will help with using what you found useful about DependencyInjection.

@Carpe Denius: Thank you very much for your feedback and approach. Yes, I cannot not agree with that. Basically, ‘what Unity offers and its way of doing things… well, it’s probably the way to go’. To which I agree, that’s why I tried to offer a ‘game example’, which for as far as I know, your advice still stands.
Curiosity, ‘if I bump into something I explode’ script. When it explodes it just says: ‘Hey! Everybody! I exploded!’ and then the object is destroyed… or this object starts finding and doing some damage to the objects around too.

@Garth Smith: If you ask me, in practicality, MVP might very well be MVVM (you have your data or model, something in between that works as the middleman and your View/UI/etc that should not be dependent nor even know of the existence of the other two. UI artists do their thing, programmers do their thing, UI just fires events or expects some data to display and all “magically” gets binded together at runtime. I’m no evangelist neither, so don’t know the tiny details. If somebody wants to chime in, I’m all ears.
Good to know that you have worked with MVP and that it fits your specific needs, on a real case scenario… feel more motivated to try. But yes, you are right, I should get up to the problem points and then find solutions.

At least I know these type of games are UI heavy (seriously heavy), very flexible (people make their own cities), etc.
At the very beginning I started using Unity’s SendMessage and recently MessengerHelper (nice Broadcast and Listeners type of events) and it already feels it won’t cut it. It will need to be typesafe at the very least.
The task at hand was:

  • User clicks on a button
  • Menu with bunch of items slides in
  • User drags any of the items.
  • Menu slides back to a hidden state to offer the full view.
  • Item is now in 3d placeable on a surface
  • When the user stops touching the screen a confirm/cancel dialog pops-up on top of the item where it was released.
  • He can continue dragging items and confirm/cancel buttons would start to pop-up.

When I was already popping out the confirm/cancel messages, and Messenger.Broadcast() the user selection off the pop-up dialogs, being string-based… it began to feel seriously “ugly”. Feels like the UI does too much…
Though the proper solution was, somehow the UI has ‘ConfirmDialog’ lists that automatically gets filled and discarded. The selected actions are relayed back to the target objects, somehow. That’s where binding frameworks and UI design patterns felt like a proper solution… and with these IoC and DI and whatnot are a few clicks and links away.

Hey guys, thank you very much for your feedback and advises. By all means, keep them coming, I’m curious to know what you guys have to say about all this.

not sure how you did your UI stuff… if you came within 10 feet of the built-in GUI stuff, I’ld be surprised if you didn’t spontaneously combust at your desk. I waiting for the next gui to attempt anything within unity for this type of solution… and it better have tools, or vector import support.

anyway, the sendmessage system is a little strange too… seems to have its’ limits (can’t recall what I prototyped with it, was spawning related with physics)… regardless, you’ll definitely want to handle that stuff. Now, I have “not” done this yet in any great detail beyond basic delegate/event handling… as I’m still prototyping; however, “if” (as in this is what I plan to do), is to attempt the observer-design pattern.

( Observer design pattern - .NET | Microsoft Learn )

however, going back to my original statement of “wonky”… not sure this pattern can even be followed. (lost data via state change is not good in any framework)… but, i’ll look into FullInspector, but I hesitate to use things like this as I become dependent on yet another developers way of doing things, instead of building on my own.

[edit]
well… nvm, what I said about observer-d-p, since we’re stuck on .NET 2.0 or whatever…

The Obsever Design pattern is actually probably good to what I need. The idea at least. Doesn’t need to be the one included in .Net libraries… it’s sounds the same to Broadcasters<->Listeners, or PropertyNotificationEvents<->PropertyNotificationListeners, or Signals, etc. but in an standardized way… thanks for the suggestion, going to read that one for better grasp.

UI: Absolutely… Unity immediate UI is great for debugging and doing very fast simple funcionality, but for a complete game it just doesn’t cut it. Currently I’m using NGUI library, and it’s great. Supposedly the new UI of Unity had some help of the same guy that did this library (or somehow he was involved with it at some point).

Yes, you are right. Me at this point I’m depending on quite a few libraries and it’s developers. I trust them : p…

Well, I stated that the thing will only explode, nothing else. You don’t need a mediator for that.

If you want stuff around that to be affected, then I would check every affectable object in explosion radius and act accordingly. Still no mediator needed. You can use one, but you don’t need to.

There are situations where it would be right, but not every situation. Thats why I said that you shouldn’t create your game with thinking “how can I squeeze this into that pattern”, because with that, you would doing more work than you should. If it is the right pattern… use it. If not, don’t.