Sunday, March 02, 2014
Getting started with StrangeIoC
StrangeIoC is a design pattern enabler for Unity3D projects. It focuses on decoupling logic from presentation through the use of Inversion of Control. This idea is summed up well in this old (2008) but well explained hour long video: http://www.dnrtv.com/default.aspx?showNum=126
Unity3D game objects are the MVVM View, the XAML & Codebehind
StrangeIoC ContextView, Root GameObject & MvcsContext are the binding of the MVVM View to the ViewModel, aka XAML's DataContext
StrangeIoC View and Mediator is the MVVM ViewModel, what's bound to XAML DataContext
StrangeIoC Model/Service is the MVVM Model
The initialization of a GameObject's modifiable properties should be pulled from a model and put into a view. There are views for many GameObjects inside a single context. This should also be represented in the Unity3D Hierarchy by making GameObjects with a view be children of a GameObject with a context. We need a context GameObject in the Unity3D Hierarchy. Our cube either needs a parent empty GameObject with a CubeContext.cs component or to become an empty GameObject and have a child Cube object. We'll also need a new CubeView.cs script. This is what our GameObject Hierarchy should look like:
StrangeIoC compared to MVVM in XAML
I come from a XAML background, where MVVM is the popular pattern. Some initial mapping of StrangeIoC to something I'm familiar with helped me get a grasp of its goals. This is how I found MVVM maps to StrangeIoC:Unity3D game objects are the MVVM View, the XAML & Codebehind
StrangeIoC ContextView, Root GameObject & MvcsContext are the binding of the MVVM View to the ViewModel, aka XAML's DataContext
StrangeIoC View and Mediator is the MVVM ViewModel, what's bound to XAML DataContext
StrangeIoC Model/Service is the MVVM Model
How StrangeIoC gets started
The first hook into StrangeIoC is a top level GameObject from the Unity3D Scene Hierarchy. The \examples\Assets\scenes\myfirstproject\TestView.unity example that comes with strange shows this on the "ViewGO" gameobject with its MyFirstProjectRoot.cs component script. The purpose of this Root.cs script is to define and initialize a StrangeIoC context. This is explained with detail in the StrangeIoC How-To. I was looking for something with a little less detail to get started.Building a Unity3D app with rudimentary usage of StrangeIoC
I made a top level Cube gameObject and attached a CubeRoot.cs script to it:using strange.extensions.context.impl; public class CubeRoot : ContextView { void Awake() { context = new CubeContext(this); } }The CubeContext is the mapping container for all StrangeIoC objects. It's not used correctly in the code below, as no mapping is done. This usage instead allows you to test that you have StrangeIoC included in your project correctly.
using UnityEngine; using strange.extensions.context.impl; using strange.extensions.context.api; public class CubeContext : MVCSContext { public CubeContext(MonoBehaviour view) : base(view) { view.renderer.material.color = Color.yellow; //verify view loads it's context } }You now have a completed basic framework for StrangeIoC. You can run the project. The cube should change to yellow by using its context.
Following a pattern by using injection
The constructor of the context class is not the right place for making modifications to the view. The purpose of the Context is to define mappings between the MVCS layers and to define the scope where GameObjects can send or receive events from other GameObject.The initialization of a GameObject's modifiable properties should be pulled from a model and put into a view. There are views for many GameObjects inside a single context. This should also be represented in the Unity3D Hierarchy by making GameObjects with a view be children of a GameObject with a context. We need a context GameObject in the Unity3D Hierarchy. Our cube either needs a parent empty GameObject with a CubeContext.cs component or to become an empty GameObject and have a child Cube object. We'll also need a new CubeView.cs script. This is what our GameObject Hierarchy should look like:
- Context - Only transform and CubeContext.cs components.
- Cube - Has default cube components along with CubeView.cs script.
using UnityEngine; using strange.extensions.context.impl; using strange.extensions.context.api; public class CubeContext : MVCSContext { public CubeContext(MonoBehaviour view) : base(view) { } protected override void mapBindings() { injectionBinder.BindFor the sake of simplicity, I hijacked the Color datatype, using Color as our Model. The Color type would normally be replaced with a model interface and injected with a model that uses that interface. The CubeView makes use of the bindings defined in CubeContext.cs to inject the CubeColor from the model.().To(Color.red); // map binding to a model } }
using UnityEngine; using strange.extensions.mediation.impl; public class CubeView : View { [Inject] public Color CubeColor {get; set;} protected override void Start() { base.Start(); this.renderer.material.color = CubeColor; } }There is much more to StrangeIoC than just these fundamentals. Understanding the flow above will make the StrangeIoC How-To easier to digest. There is also an introductory video on StrangeIoC in this article.
Labels: StrangeIoC, Unity3D
Subscribe to Posts [Atom]