Week 2: More about GUI, MVC and Interactive Applications, and Entity/Component Model of Unity3D. Please download and unzip the Week2.zip file in the Files/WeeklyExmaples folder.

1.       WPF_Analogy: WPF stands for Windows Presentation Foundation (OK … interesting?)

a.       Transferable knowledge: what have we learned from Unity3D GUI construction that can be transferred to another GUI system?

                                                               i.      EVERYTHING!!

b.      “Toolbox”: icon (or menu) for creating GUI elements (or Microsoft refer to these are controls). E.g., creating a button.

                                                               i.      Toobox menu (View è Toolbox)

                                                             ii.      Typically with drag and drop. Nice.

c.       Appearance (e.g., color) and properties (e.g., slider bar range) of GUI elements can typically be changed in two ways:

                                                               i.      The GUI editor: usually lets you modify the elements

                                                             ii.      Run time in code: a variable representing the GUI element can be defined to access the element, and everything can be changed at run time.

d.      Register events: on the GUI elements to respond to. Again, you can do through GUI editor or via code.

e.      The above are the mechanics of working with GUI system. Now, how to design and implement solutions based on GUI?

f.        Verify everything with WPF.

                                                               i.      Button click: to change button height

                                                             ii.      Slider: to control button height

 

2.       SliderWithEcho: Interaction unit solving a simple problem, e.g., slider with echo …

a.       Problem: given slider is not enough, need numerical output, and some form of label

b.      Solution: build a UI Prefab

c.       Remember the “GUI Work Template”

                                                               i.      Create the GUI Widget: Drag out the icons (GUI element) that is the GUI widget

                                                             ii.      Define the behavior:  Create a new class to associate with the new Widget. In this new class:

1.       Must have access to the content GUI elements

2.       Must provide callback (listener) mechanism for user of this Widget

3.       Must: allow object update GUI when binding the object to the GUI

4.       Must: support GUI update object when user adjust the GUI

d.      SliderWithEcho prefab:

                                                               i.      UI Element structure (GUI “frontend”)

1.       Panel (for the nice looking color bound), create the visual effect that all elements within the panel belongs to the same “GUI object”

2.       Three GUI elements: slider, text for echo, text for label

                                                             ii.      Logic/Behavior (GUI “backend”): SliderWithEcho.cs (in Source/Prefab Support/UIPrefab)

1.       Object set GUI when binding occurs:

a.       SetSliderValue(): lets the caller ensure this is handled properly

2.       GUI set Object when user modifies GUI

a.       SliderValueChange(): through mCallBack()

                                                            iii.      Something we know(?): C# delegate (function pointer)

1.       The SetSliderListener() function is kind of interesting?

                                                           iv.      Exported as a general asset, you can import by:

1.       Asset è Import Package è Custom Package

e.      Behavior: ScalableSphere (in Source/Prefab Support/)

                                                               i.      Simple and boring

f.        TheWorld: our model, a collection of selectable spheres with radius that can be changed

                                                               i.      Behaviors: SelectAtPosition(), SetSelectedRadius(), GetSelectedRadius()

                                                             ii.      Private method: for changing selected color

g.       MainCanvas: MainController where everything come together

                                                               i.      Continas:

1.       The Model: TheWorld

2.       The View: TheCamera (for RayCast)

3.       The Controller: SliderWithEcho

                                                             ii.      Function: coordinate Model and Controller

1.       Object set GUI: Model value sets the GUI

a.       After selection: TheSlider.SetSliderValue(TheWord.GetSelectedRadius());

b.      What happens if we don’t call this? Try:

                                                                                                                                       i.      Click to create a sphere

                                                                                                                                     ii.      Change the radius

                                                                                                                                    iii.      Click to create another sphere

                                                                                                                                   iv.      Now: note the slider bar value is different from the selected sphere radius!

2.       GUI set Object:

a.       when user changes slider: RadiusChange() è TheWorld.SetSelectedRadius();

h.      Note:

                                                               i.      the SliderWithEcho Controller (slider bar) has no knowledge of the Model

1.       è SliderWithEcho can be used any time a slider is needed

                                                             ii.      The Model has no knowledge of the controller

1.       è Trivial to define a new set of UI operation, e.g.,

a.       Use Arrow Key to move a cursor,

b.      <CR> to create a new sphere

c.       “ZX” keys to increase/decrease the radius

                                                            iii.      MainController knows all the intimate details, it is the UI binding for the model, the “application”, and not as re-useable.

i.         Question:

                                                               i.      What If ScalableSphere has a update function that increases the radius by 0.01 per update (for correct 2-way binding, when a sphere is selected, we must inform the UI)!

                                                             ii.      Solution: one solution is for MainController to pull the selected object and update the slider per update (this is what we will do in this class).

 

·         Model-View-Controller at multiple levels:

a.       EchoWithSlider: what are the M, V, and C

b.      The 2.SldierWithEcho application, when running, what are the M, V, and C?

                                                               i.      How does Unity engine help us with the Model?

c.       Now, think about the Unity editor, how can we use MVC to explain the Unity editor?

d.      How about Microsoft Word, or Microsoft Powerpoint, or any image editing software (E.g., GIMP)?

e.      Here is a short article we wrote about this topic (to be published soon).

 

3.       ClickDragSphere: Another example of working with MVC …

a.       Behaviors:

                                                               i.      LMB: Click and drag to show a sphere and “shoots” from release towards the center

                                                             ii.      RMB: Click to select

                                                            iii.      X/Z: sliders shows the current position of the selected

b.      Model:

                                                               i.      A collection of spheres (maintained by Unity)

                                                             ii.      Need representation for the selected

                                                            iii.      Behavior:

1.       TheWorld_Create: Creation support: LMB down, drag, up

a.       CreateAt, ScaleTo, SetToMotion

2.       TheWorld: Selection support

a.       Select, ReleaseSelect

3.       TheWorld: Set/Get state support (for GUI)

a.       SetSelectedPosition, GetSelectedPosition

c.       MainCanvas: again, all connecting work done in MainController.cs

                                                               i.      References to TheWorld, TheSliders, and TheCamera

                                                             ii.      Mouse support in MainController_MouseSupport.cs

                                                            iii.      GUI set Object:

1.       NewXValue()/NewZValue()

                                                           iv.      ObjectSetGUI:

1.       In update(): SetSliderVaue()

2.       What if we did not do this?

 

4.       GUIObjPositionControl: If objects X/Z position is important to us and we see future needs of re-using this functionality … this is what we can do:

a.       ObjPositionControl: Define a new GUI Widget to support object position control

                                                               i.      GUI:

1.       Remember: good habit (probably): always Panel as base (to be created in a given Canvas)

2.       Drag GUI to your heart content (make it look pretty)

                                                             ii.      Behavior: ObjPositionControl.cs (in Source/Prefab Support/UIPrefab)

1.       Define variables for each of the GUI elements (the two sliders)

2.       Define support for:

a.       GUI set Object: NewXValue() and NewZValue()

b.      Obj set GUI: ObjSetGUI()

b.      Now, TheWorld, does not need to know much details, it can simply coordinate

                                                               i.      Has instances of:

1.       Model: TheWorld

2.       Controller: ObjPositionControl (PosControl)

                                                             ii.      No need to worry about telling sliders to set selected object positions anymore

                                                            iii.      In Mouse support

1.       When create/select object, simply tell PosControl to set to newly selected object

                                                           iv.      MUCH cleaner!

 

ð  Done with GUI, Event Driven Programming, and MVC