I did a bit of searching, and I was only able to find one other thread that touched on this topic. I was hoping the Unity community could provide some advice on some patterning issues I am having.
Basically, I am designing a tactical space sim game, which primarily deals with ships, and the modules that belong to those ships. My goal is to encapsulate the functionality and UI of each component to maximize the ease of revision and late-stage development. To that end, my current approach is to implement a model, view and controller class for each element, and use a combination of controller interfaces and dictionary registries of C# events to handle communication between the ship and its member modules, and between the gamecontroller and the instantiated ships. Each one of these elements is a gameobject, and I attach the relevant classes as monobehavior scripts.
My question is whether I necessarily need a model class for my purposes. Given the way unity is designed, my model is fundamentally the gameobject and any colliders, rigidbodies or other components that I attach to it. Currently, I’m using the model class to define additional attributes, (such as energy cost and speed, for instance) to the various modules, and to implement the methods that control the gameobject. Optimally, I’m thinking either I might eliminate the model class entirely, and incorporate the additional attributes into my controller class, or further insulate the gameobjects from the controller and view, by having them interact only via methods defined in the model class. In the latter case, the controller and view would never actually touch the gameobject they are attached to.
Can anyone who has worked with a similar setup recommend a particular approach? I’m having a hard time seeing the advantages and disadvantages of each choice, and I feel like I’m getting unnecessarily bogged down in what should be simple stuff. I appreciate any feedback anyone can provide.
I have a global singleton Messaging service, that has a few types of messages, like StateMessage (health, fuel etc), InfoMessage (die fool, etc).
Then I have an interface, IMessagable, so whichever object in the game wants to know about something else it implements this.
My messaging system supports instant responses and aynschronous responses. Useful if you want to be notified for things like, on_death etc. or if you simply want to poll it every update.
My gui simply polls on update. It sends queries to the Messaging service asking for updates about whichever entity its displaying the stats of.
I don’t see why your stressing about MVC…personally I wouldnt worry about doing that way. If you have to rework you have to rework, theres a lot of myths about code reuse, really when if its wrong its better to just admit it, can it and start again.
MVC is imho a little bit too much of how could i decouple my code so i could use it in all of my following games.
I think it’s a waste of time.
My gui has a StateMachine and due to the active state i call different Update methods.
Then i code the logic for every state and if i want to display the Health of the player, i use the property health of my player script.
If a value of an object has to be changed due to Gui input, i will call the corresponding method of the object.
The only 2 things i use in games:
a hierarchical state machine: 1 game state machine, 1 input state machine and 1 gui state machine.
an action manager ( commands ): if i want that a unit can be selected, i write a SelectUnitAction. The action defines which parameters are needed. An action is something that can also run longer ( e.g. an WalkToAction ). When you call SetCompleted the action is removed from the action queue.
I like the idea of a global singleton messaging service, though much of the messaging that goes on in my game happens between a parent objects and child objects. Also, gameplay involves multiple ships moving and activating modules in parallel, and I worry that relying on a single queue will create some problems down the road.
However, my biggest concern, and the primary reason for choosing to use at least some aspects oft he MVC pattern, is that each module has a UI associated with it, so selecting a module will display additional UI elements, and I’m worried that keeping all my UI code in one central script will become extreme unwieldy very quickly. I’d like to avoid thousand line scripts that handle UI code for a variety of different objects. It’s more about keeping myself sane than reusing the code.
No need to be worried about “queues”. Its merely a look up that interested parties register with to pass on messages to each other.
Ouch I don’t like that idea…I would chose not to store UI information in a gameobject/entity/module, if I understand you correctly. You can break up your GUI into different classes to make it simpler of course, but storing GUI info in entities doesnt sound like a good way to simplify complexity to me.
Unless you mean something else entirely by “module”?
Yeah, basically each ship is a gameobject, and the modules, like weapons or engines, are child gameobjects. The idea being that once I have it all working, creating or tweaking ships is just a matter of dragging and dropping prefabs and changing values in the inspector. The way I’m building it now, the ship has it’s own UI script, and each of the child modules has its own UI script.
No events are overkill. I just use a dictionary lookup. Simple. Straightforward. You have to follow Unitys pattern of doing things, so I’m not sure if events would work (what happens if an event fires outside an Update?).
Ok so maybe in some contexts this is not a bad idea (albiet I would not actually imbed the actual GUI code in the module code). For instance if you are intending on having 3rd parties develop modules for your simulation, then its their responsibilty to make an equivalent GUI for it. The other reason I can think of is perhaps you have a spaceship that can have weapons customizations/upgrades and you want the GUI to reflect the new features the weapon has?
How about using a strategy style pattern where you have these weapons modules, and can attach a given GUI to it, which the GUI master uses to render the final cockpit. Hence weapons modules and their GUIs are “swappable”. This way your weapon is completely decoupled from its UI. You just have to define how you want the GUI and its weapon to interact. How simple or self describing these interactions are is up to you, but i’d err on the side of simple.
You can read my tutorial about MC for unity. I try to implemets small login/registration functionality using this approach. http://unity-tutorials.blogspot.com/