Beispiel #1
0
    public override void GetContent(IDocumentationBuilder _)
    {
        base.GetContent(_);
        _.Paragraph("The uFrame Kernel is an essential piece of uFrame, it handles loading scenes, systems and services.  " +
                    "The kernel is nothing more than a prefab with these types of components attached to it in an organized manner.");

        _.ImageByUrl("http://i.imgur.com/5Rg2X25.png");

        _.Paragraph("In the image above you can see the scene 'BasicsProjectKernelScene'.  This scene will always always contain the 'BasicsProjectKernel' " +
                    "prefab and any other things that need to live throughout the entire lifecycle of your application.");
        _.Paragraph("Important Note: All SystemLoaders, Services, and SceneLoaders are MonoBehaviours attached their corresponding child game-objects in the kernel prefab.");

        _.Note(
            "Whenever a scene begins, uFrame will ensure that the kernel is loaded, if it hasen't been loaded it will delay " +
            "its loading mechanism until the kernel has been loaded. This is necessary because you might initialize ViewModels, deserialize them...etc so the view should not bind until that data is ready.");

        _.Break();

        _.Title2("Scaffolding The Kernel");
        _.Paragraph("For convenience uFrame 1.6 makes the process of creating the kernel very easy and straightforward.  " +
                    "By pressing the Scaffold/Update Kernel button it will create a scene, and a prefab with all of the types created by the uFrame designer.  " +
                    "You can freely modify the kernel, and updating it will only add anything that is not there.");
        _.Break();

        _.Title2("Boot Order");
        _.ImageByUrl("http://i.imgur.com/L5CC8q8.png");

        _.Title2("The Game Ready Event");
        _.Paragraph("Once the kernal has loaded, it will publish the event 'GameReadyEvent'.  This event ensures that everything is loaded and bindings have properly taken place on views.");
    }
Beispiel #2
0
    public override void GetContent(IDocumentationBuilder _)
    {
        base.GetContent(_);
        _.Paragraph("The uFrame Kernel is an essential piece of uFrame, it handles loading scenes, systems and services.  " +
                    "The kernel is nothing more than a prefab with these types of components attached to it in an organized manner.");



        _.ImageByUrl("http://i.imgur.com/5Rg2X25.png");

        _.Paragraph("In the image above you can see the scene 'BasicsProjectKernelScene'.  This scene will always always contain the 'BasicsProjectKernel' " +
                    "prefab and any other things that need to live throughout the entire lifecycle of your application.");
        _.Paragraph("Important Note: All SystemLoaders, Services, and SceneLoaders are MonoBehaviours attached their corresponding child game-objects in the kernel prefab.");

        _.Note(
            "Whenever a scene begins, uFrame will ensure that the kernel is loaded, if it hasen't been loaded it will delay " +
            "its loading mechanism until the kernel has been loaded. This is necessary because you might initialize ViewModels, deserialize them...etc so the view should not bind until that data is ready.");

        _.Break();

        _.Title2("Scaffolding The Kernel");
        _.Paragraph("For convenience uFrame 1.6 makes the process of creating the kernel very easy and straightforward.  " +
                    "By pressing the Scaffold/Update Kernel button it will create a scene, and a prefab with all of the types created by the uFrame designer.  " +
                    "You can freely modify the kernel, and updating it will only add anything that is not there.");
        _.Break();

        _.Title2("Boot Order");
        _.ImageByUrl("http://i.imgur.com/L5CC8q8.png");


        _.Title2("The Game Ready Event");
        _.Paragraph("Once the kernal has loaded, it will publish the event 'GameReadyEvent'.  This event ensures that everything is loaded and bindings have properly taken place on views.");
    }
Beispiel #3
0
    public override void GetContent(IDocumentationBuilder _)
    {
        base.GetContent(_);

        _.CodeSnippet("var player = this.CreatePlayer()");
        _.Title2("Creating a ViewModel with the Extension Method");
        _.Paragraph("In uframe 1.6 there is an extension method for creating any viewmodel that will use the correct controller to create it.");
        _.CodeSnippet("this.CreateViewModel<PlayerViewModel>()");
        _.Paragraph("This method will resolve the controller and invoke the associated controller's 'Create' method.");
        _.Paragraph("It is important that you use this method because the controller will initialize the commands on the viewmodel to point to the correct handlers on itself.");
        _.Break();

        _.Title2("Initialization Inside Controllers");
        _.Paragraph("Typically you will use the relevant Controller's Initialize{ElementName} function to initialize " +
                    "a newly created ViewModel with default values and references.  It's a great place to subscribe to " +
                    "state changes and \"scene property\" changes, or possibly track a list of ViewModel instances when " +
                    "acting similarly to a manager.");



        _.Break();
        _.Title2("Initialization Inside Views");
        _.Paragraph("For convenience, you also have the option of Initializing a ViewModel from a particular View, by checking Initialize ViewModel on the View.  This is particularly useful when setting up a scene before runtime or creating prefabs.");

        _.Break();
        _.AlsoSeePages(typeof(ViewModelManagers));
    }
    public override void GetContent(IDocumentationBuilder _)
    {
        base.GetContent(_);

        var graph = new ScaffoldGraph();
        var node  = graph.BeginNode <SceneTypeNode>("UIScene").EndNode() as SceneTypeNode;

        _.Paragraph("Scene Types exist on the root game object of a scene. These components need to live on the root game-object of the scene. This allows uFrame to know what scene has been loaded and to keep a reference for removing this scene when needed.");


        _.Title2("Generated Scene Types");
        _.Paragraph("The scene type is a mono behaviour that will go on your root scene object.  This allows uFrame to associate a game object so it can easily be destroyed when you want to unload a scene.  This also allows uFrame to listen for when the scene has actually been loaded.");
        _.Break();
        _.TemplateExample <SceneTemplate, SceneTypeNode>(node, true);
        _.Break();
        _.Title2("Generated Scene Loaders");
        _.Paragraph("A scene loader is generated for every scene type that exists in the graph.");
        _.Paragraph("The scene loader lives as a gameobject on the uFrame Kernel, when the same corresponding 'Scene Type' has been loaded," +
                    " the scene loader will get a reference to the scene type and allow you to load it accordingly.  This gives very fine grained " +
                    "control on how scenes are loaded and unloaded.");
        _.Break();
        _.TemplateExample <SceneLoaderTemplate, SceneTypeNode>(node, true);


        _.AlsoSeePages(typeof(UsingSceneLoaders));
    }
Beispiel #5
0
        private static void ImportantMethods(IDocumentationBuilder _)
        {
            _.Title2("Execution Order");
            _.Paragraph("There are actually several different entry points on generated Views.  The usual order is:");
            _.Title3("For Views instantiated at runtime");
            _.Paragraph("Awake > OnEnable > PreBind > Bind > AfterBind > InitializeViewModel > Start > Update loop begins");
            _.Title3("For Views existing \"SceneFirst\" before runtime");
            _.Paragraph(
                "Awake > OnEnable > CreateModel > InitializeViewModel > Start (before base call) > PreBind > Bind > AfterBind > Start (after base call)");

            _.Title3("When Destroying an object");
            _.Paragraph(
                "OnDisable > OnDestroy (before base.OnDestroy() call) > UnBind > OnDestroy (after base.OnDestroy() call)");
            _.Break();
            _.Break();
            _.Title2("Help, my bindings have stopped working!");
            _.Paragraph(
                "There are a few methods that ALWAYS need their base.Method() calls intact, otherwise uFrame can easily  produce unexpected results.");
            _.Paragraph("These methods include a majority of the overridden standard Unity methods:");
            _.Paragraph(" - Awake(), Start(), OnEnable(), OnDisable(), OnDestroy(), Update(), LateUpdate()");
            _.Paragraph(" - PreBind(), Bind(), AfterBind(), UnBind(), InitializeViewModel()");
            _.Break();
            _.Break();
            _.Title2("Important Methods");
            _.Paragraph(
                "When looking for more clarity on how uFrame builds upon Monobehaviour, it can be fairly useful to look through ViewBase.cs, as this is what all uFrame Views inherit from.");

            _.Title3("PreBind()");
            _.Paragraph("This happens before the View begins creating bindings to its given ViewModel.");
            _.Break();

            _.Title3("Bind()");
            _.Paragraph(
                "This is where the View actually creates property bindings, collection bindings, and command bindings to the given ViewModel.  The base.Bind() call will automatically create the bindings specified in the uFrame diagram for this specific View type.  If you have any further manual bindings you need to do, this can be a good place to implement them.");
            _.Break();

            _.Title3("AfterBind()");
            _.Paragraph("This is called immediately after the View creates bindings to its ViewModel.");
            _.Break();

            _.Title3("CreateModel()");
            _.Paragraph(
                "This is when SceneFirst Views request a proper ViewModel from the scene's Dependency Container.  For the most part, this should be left alone.");
            _.Break();

            _.Title3("InitializeViewModel()");
            _.Paragraph(
                "On a View, when the Initialize ViewModel option is checked in the inspector, this is where the base.InitializeViewModel() call will set the ViewModel's properties to the values of the View's matching properties (which are underscored in code on the View).  This will usually never need to be overridden.");
            _.Break();

            _.Title3("Awake(), Start(), OnEnable(), OnDisable(), OnDestroy(), Update(), LateUpdate()");
            _.Paragraph(
                "These are all the same as their Unity counterparts, and must retain their base calls if you override them, in order for uFrame to function properly.");
            _.Break();
        }
Beispiel #6
0
        private static void ImportantMethods(IDocumentationBuilder _)
        {
            _.Title2("Execution Order");
            _.Paragraph("There are actually several different entry points on generated Views.  The usual order is:");
            _.Title3("For Views instantiated at runtime");
            _.Paragraph("Awake > OnEnable > PreBind > Bind > AfterBind > InitializeViewModel > Start > Update loop begins");
            _.Title3("For Views existing \"SceneFirst\" before runtime");
            _.Paragraph(
                "Awake > OnEnable > CreateModel > InitializeViewModel > Start (before base call) > PreBind > Bind > AfterBind > Start (after base call)");

            _.Title3("When Destroying an object");
            _.Paragraph(
                "OnDisable > OnDestroy (before base.OnDestroy() call) > UnBind > OnDestroy (after base.OnDestroy() call)");
            _.Break();
            _.Break();
            _.Title2("Help, my bindings have stopped working!");
            _.Paragraph(
                "There are a few methods that ALWAYS need their base.Method() calls intact, otherwise uFrame can easily  produce unexpected results.");
            _.Paragraph("These methods include a majority of the overridden standard Unity methods:");
            _.Paragraph(" - Awake(), Start(), OnEnable(), OnDisable(), OnDestroy(), Update(), LateUpdate()");
            _.Paragraph(" - PreBind(), Bind(), AfterBind(), UnBind(), InitializeViewModel()");
            _.Break();
            _.Break();
            _.Title2("Important Methods");
            _.Paragraph(
                "When looking for more clarity on how uFrame builds upon Monobehaviour, it can be fairly useful to look through ViewBase.cs, as this is what all uFrame Views inherit from.");

            _.Title3("PreBind()");
            _.Paragraph("This happens before the View begins creating bindings to its given ViewModel.");
            _.Break();

            _.Title3("Bind()");
            _.Paragraph(
                "This is where the View actually creates property bindings, collection bindings, and command bindings to the given ViewModel.  The base.Bind() call will automatically create the bindings specified in the uFrame diagram for this specific View type.  If you have any further manual bindings you need to do, this can be a good place to implement them.");
            _.Break();

            _.Title3("AfterBind()");
            _.Paragraph("This is called immediately after the View creates bindings to its ViewModel.");
            _.Break();

            _.Title3("CreateModel()");
            _.Paragraph(
                "This is when SceneFirst Views request a proper ViewModel from the scene's Dependency Container.  For the most part, this should be left alone.");
            _.Break();

            _.Title3("InitializeViewModel()");
            _.Paragraph(
                "On a View, when the Initialize ViewModel option is checked in the inspector, this is where the base.InitializeViewModel() call will set the ViewModel's properties to the values of the View's matching properties (which are underscored in code on the View).  This will usually never need to be overridden.");
            _.Break();

            _.Title3("Awake(), Start(), OnEnable(), OnDisable(), OnDestroy(), Update(), LateUpdate()");
            _.Paragraph(
                "These are all the same as their Unity counterparts, and must retain their base calls if you override them, in order for uFrame to function properly.");
            _.Break();
        }
Beispiel #7
0
    public override void GetContent(IDocumentationBuilder _)
    {
        base.GetContent(_);
        _.Title2("What is it?");
        _.Paragraph("Controllers dictate the rules of your game and, like ViewModels, they do not inherit from Unity's Monobehaviour.  As they only handle logic, there only ever needs to be one Controller for each type of ViewModel.  For example, when a PlayerViewModel performs the PickupItem command, the PlayerController would simply need to know which PlayerViewModel to execute that command logic on, and the logic remains the same whether there are 4 players or one.");

        _.Paragraph(" A controller is designed to implement the data-driven logic and rules behind an element " +
                    "and could be considered just a \"group\" of commands for a view-model. " +
                    "The Designer has enough information about an element to implement most of the controller itself " +
                    "In most instances, you only need to apply the logic and rules to each method.  ");

        _.Break();



        _.Title2("Best Practices");
        _.Paragraph("When implementing controllers, think of the element as its own little section of your world, " +
                    "if you want your element to interact or be visible to the entire world, publish events as " +
                    "necessary in your command controller methods.");
        _.Paragraph("To understand this idea a bit more, take a look at the following diagram.");
        _.ImageByUrl("http://i.imgur.com/KbPL9bw.png");
        _.Paragraph("So in the diagram above, on the EnemyHit command handler, we publish the command as 'global' event.  This means that services can be your general connection layer that make various elements work together.");
        _.Title3("But why should I do this?");
        _.Paragraph("Imagine you create a Player element, if it lives entirely on its own (no dependencies on other controllers, services..etc), you can re-use the element in another game and implement services to connect them together.");
        _.Break();
        _.Break();

        _.Title2("The Setup Method");
        _.Paragraph("The setup method is an implementation of the ISystemService interface, this means that all controllers are ultimately services, they do not derive from monobehaviour.  This means you can easily listen to any kind of event on a controller, as well as publish them.");
        _.Title3("Important Note");
        _.Paragraph("You must be careful when listening to events in controllers that use inheritance. For instance, if you have an elementA controller, and a derived elementB controller, and in the setup method you are listening to event 'C', then beth element A and element B will be listening to the same event.  In some cases this may be wanted behaviour, but its important to understand.");
        _.Break();
        _.Break();
        _.Title2("The Initialize Method");
        _.Paragraph("The initialize Method in a controller can be used to initialize an Element's ViewModel (similar to how it might be initialized in the inspector of a View). It is a great place to subscribe to 'Scene Properties'.");
        _.Title2("Command Handlers");
        _.Paragraph("Every command that is outlined on an element, in the Element Designer, will have a corresponding method in a controller (assuming the diagram is saved).  ");
        _.Paragraph("There are a few things to notice when looking at the code example below:");
        _.Paragraph(" - The \"FPSWeaponController\" is derived from \"FPSWeaponControllerBase\", which is generated by the designer.");
        _.Paragraph(" - All of these methods are overrides, because the base class has implemented an empty \"virtual method\" for each command.");
        _.Paragraph(" - The reload method has an IEnumerator result type, because is it is marked as a yield command (indicated by the yellow marker).  This can be achieved by right-clicking on a command and checking \"Is Yield Command\". It is used for simulating a co-routine.");
        _.Paragraph(" - In each method we are simply processing rules by reading and modifying the FPSWeaponViewModel's instance data .");
        _.ShowGist("7bba5439faf0b46efa61", "FPSWeaponController.cs");
    }
Beispiel #8
0
 public override void GetContent(IDocumentationBuilder _)
 {
     base.GetContent(_);
     _.Paragraph("uFrame, specifically created for the Unity game engine, uses a pattern-based framework called MVVM (Model View ViewModel). It is designed to provide developers with the visual editing tools, code structure and knowledge to develop games faster and more efficiently. This \"frame of mind\" for creating games is different than what most Unity developers are used to, but once understood the possibilities of where an idea can go are limitless. So, let's jump right into the \"uFrame of mind\"! ");
     _.Title2("Making things simple");
     _.Paragraph("Far too often game development begins with throwing a bunch of random game objects and components together and then retrofitting code in hopes of creating a masterpiece. Teams fail to focus on the basic concepts first and are left with trying to assemble pieces of a project that don't quite fit together. Doesn't make much sense does it?");
     _.Paragraph("uFrame simplifies things by separating out the essential and peripheral parts of the Unity's component model. It eliminates the visual noise (user-interface, HUD, transformers, positions, rotations, working with geometry, shaders, pathfinders, mouse events etc.) that can overwhelm and discourage many developers, and allows them to initially focus on the core logic.");
     _.Paragraph("uFrame does this with the use of Elements . Each element in a game has different parts, which consists of the ViewModel, Controller, View and possibly the View Component. A ViewModel serves as interface between the visual entities and logic of the game. These entities include properties (Score, Ammo, etc.), collections (Players, Environments etc.), and commands (PlayerHit, Upgrade etc.). A Controller works with a ViewModel to initialize and modify data when a command is invoked and/or interaction occurs between an event and the user. ");
     _.Break();
     _.Title2("Always Consider Portability.");
     _.Paragraph("In uFrame, both the Controller and the ViewModel are \"portable\" parts of a game. This means taking them outside of Unity and putting them into a separate environment, such as a terminal application or web server, will never be an issue. In fact, this is essential to providing proper support for the extended features of uFrame and is enforced by the Element Designer (which limit the types that are available). This should always be taken into consideration when developing or extending Controllers or ViewModels. ");
     _.Note("Even if a game doesn't need portability it is still good to think in these terms. uFrame is built around this concept, which allows each piece to fit together more naturally.");
     _.Break();
     _.Title2("Making The Noise Sing.");
     _.Paragraph("The other two parts of the element, the View and the View Component, connect the game logic with the visual noise. They are the key components that connect Unity to the Controllers and ViewModels, bringing the game to life. A View Component can read and modify the real-time data of a ViewModel, but isn't necessary for every element. It is only meant to provide an extra level of extendibility when needed. A View (which is technically a View Component, but with a larger role) binds to an element's data so that it's notified when something is changed. When these changes occur, it directs the View Component to execute the appropriate action. Views also execute the commands of events and interactions that occur in the scene (e.g. Collision, MouseClick, Hover). ");
     _.Break();
     _.Title2("Naming Things.");
     _.Paragraph("When creating elements, particularly element commands, it's important to think about how things are being named. For instance, if a player can pick up an item when a game object collides with it and when the player clicks on it, then a developer would want to create a label such as \"PickUpItem\", that describes both commands. This would more broadly explain its function and allow for items to be collected in a different way, if the developer so chooses.  ");
     _.Break();
 }
    public override void GetContent(IDocumentationBuilder _)
    {
        base.GetContent(_);

        var graph = new ScaffoldGraph();
        var node = graph.BeginNode<SceneTypeNode>("UIScene").EndNode() as SceneTypeNode;
        _.Paragraph("Scene Types exist on the root game object of a scene. These components need to live on the root game-object of the scene. This allows uFrame to know what scene has been loaded and to keep a reference for removing this scene when needed.");

        _.Title2("Generated Scene Types");
        _.Paragraph("The scene type is a mono behaviour that will go on your root scene object.  This allows uFrame to associate a game object so it can easily be destroyed when you want to unload a scene.  This also allows uFrame to listen for when the scene has actually been loaded.");
        _.Break();
        _.TemplateExample<SceneTemplate, SceneTypeNode>(node, true);
        _.Break();
        _.Title2("Generated Scene Loaders");
        _.Paragraph("A scene loader is generated for every scene type that exists in the graph.");
        _.Paragraph("The scene loader lives as a gameobject on the uFrame Kernel, when the same corresponding 'Scene Type' has been loaded," +
                    " the scene loader will get a reference to the scene type and allow you to load it accordingly.  This gives very fine grained " +
                    "control on how scenes are loaded and unloaded.");
        _.Break();
        _.TemplateExample<SceneLoaderTemplate, SceneTypeNode>(node, true);

        _.AlsoSeePages(typeof(UsingSceneLoaders));
    }
Beispiel #10
0
        public override void GetContent(IDocumentationBuilder _)
        {
            base.GetContent(_);

            _.Paragraph("System loaders are used to setup the uFrame Runtime with any dependencies it might need before the game begins.");
            _.Break();


            _.Title2("Custom System Loaders");
            _.Paragraph("In some cases creating a custom system loader can be very useful for different environments.  e.g. Dev Environment, Production Environment..etc");
            _.Paragraph("To create a custom system loader, derive from SystemLoader, override the load method, and add it to the kernel.");
            _.Break();
            _.Break();
            _.Title2("Generated System Loaders From Subsystems");
            _.Paragraph("All subsystem nodes inside a project will generate a 'SystemLoader'. These register an instance of every element " +
                        "controller that lives inside of it, as well as any 'Instances' defined on it.");

            _.Break();

            var graph = new ScaffoldGraph();
            InstancesReference instance;

            graph.BeginNode <SubsystemNode>(Name)
            .AddItem <InstancesReference>("MyInstance", out instance);

            var subsystem = graph.EndNode();

            graph.BeginNode <ElementNode>("Player");
            var playerNode = graph.EndNode();

            graph.PushFilter(subsystem);
            graph.SetItemLocation(playerNode, new Vector2(10f, 10f));

            instance.SourceIdentifier = playerNode.Identifier;

            _.TemplateExample <SystemLoaderTemplate, SubsystemNode>(subsystem as SubsystemNode, true, "Load");
        }