Search Unity

  1. Get the latest news, tutorials and offers directly to your inbox with our newsletters. Sign up now.
    Dismiss Notice

Implement separate classes for UI and logic game

Discussion in 'Scripting' started by mahdiii, Aug 24, 2017.

  1. mahdiii

    mahdiii

    Joined:
    Oct 30, 2014
    Posts:
    835
    Hi all
    I would like to implement a section of a game that contains both UI and logic.
    Is it suitable that I separate them from each other? for example I have a panel that shows some information and interacts with a user.
    We can use two classes CPanelUI and CPanelLogic like below:
    Code (CSharp):
    1. public class CPanelUI :Monobehaviour{
    2. CPanelLogic m_panelLogic;
    3. //...
    4. }
    5. public class CPanelLogic{
    6. CPanelUI m_panelUI;
    7. //...
    8. }
    So they can call their methods and interact with each other but both of the classes depend on each other.
    If I implement like below. Is it better?(using event) or use MVC design pattern for all panels!
    Code (CSharp):
    1. public class CPanelUI :Monobehaviour{
    2. CPanelLogic m_panelLogic;
    3. void Start(){
    4. panelLogic.ChangedButtonEvent+=ChangedButton;
    5. panelLogic.UpdateTimeEvent+=UpdateTime;
    6. void ChangedButton(){
    7.  
    8. }
    9. void UpdateTime(){
    10.  
    11. }
    12. }
    13.  
    14. //...
    15. }
    16. public class CPanelLogic{
    17. public event Action ChangedButtonEvent;
    18. public event Action UpdateTimeEvent;
    19. //...
    20. }
    How can we do to reduce dependency and coupling? thanks in advance.
     
  2. Suddoha

    Suddoha

    Joined:
    Nov 9, 2013
    Posts:
    2,825
    If you want to stay flexible, the most important thing is to not couple the concrete implementations to each other.

    That is, in case you want to provide the instances via inspector, the types should be an abstraction so that you can plug in any concrete implementation that you desire at a later point in time.
    Whether you couple them using events or interfaces/base types is most-likely a personal preference, if the controller is only supposed to control a particular view, you could model that with simple associative relations.
    If you want to update more targets (i.e. views in the first place), you can either use the good old interface-based event listener that'll be registered or use [C# and/or Unity] events for convenience and reduce boiler-plate code.

    Also, due to Unity's inspector features and the component-based design, it's fairly easy to achieve loose coupling as hooking up the dependencies can literally be done using drag&drop without any further script in between or using GetComponent<T>.
    Additionally, attributes such as RequiresComponent and DisallowMultipleComponent can help to ensure that your views will always be able to resolve their controller pendants properly, given that you wish to place the components on the same object.
     
    Kiwasi likes this.
  3. BlackPete

    BlackPete

    Joined:
    Nov 16, 2016
    Posts:
    970
    Yes. Keep data and UI separate. Absolutely.

    Take a player's health, for example. That health might be shown in multiple places. It could show up as a health bar over the player's head, it could also show as a concrete number in your HUD, and it could also show as a number in your player status menu.

    Or to take a more extreme example: What if halfway through the game you realize "Oh crap, I want Unreal not Unity" and you need to replace the engine? Ideally you should be able to do this without touching the game logic and data.

    On a slightly less extreme example: Suppose you want to create a thin client that will do unit testing on your data and logic, or run some sort of a combat simulator to make sure your maths add up.

    The MVC pattern is a common pattern for this.

    This looks like a decent tutorial on utilizing the MVC pattern in Unity: https://www.toptal.com/unity-unity3d/unity-with-mvc-how-to-level-up-your-game-development
     
    mahdiii and Suddoha like this.
  4. Suddoha

    Suddoha

    Joined:
    Nov 9, 2013
    Posts:
    2,825
    That's indeed an extreme example. :D
     
  5. mahdiii

    mahdiii

    Joined:
    Oct 30, 2014
    Posts:
    835
    ok so I implement MVC but for every panel it takes a lot of time :)
     
  6. Kiwasi

    Kiwasi

    Joined:
    Dec 5, 2013
    Posts:
    16,787
    There are several valid approaches to UI architecture. Which you use depends a lot on your specific game.

    My preferred approach is to have the UI dependent on the game code. The game code simply exposes a bunch of properties and methods, and the UI code is aware of those properties and methods. As far as the game code is concerned, the UI does not exist. This does mean that you have to update the UI code every time the game code changes. But I find most games need this anyway.

    Another valid approach is to have each game entity responsible to create its own UI. It works for simple systems. But it is easy to get clashes on complex ones. And it means your UI logic gets spread out everywhere. Its great for debugging stuff, but not too flash for production.

    The final approach I've seen is to dynamically build the UI at run time by scanning the existing entities using reflection. This works great for complex simulation games with many different items. The downside is the entire UI has a samey feel to it. It becomes difficult to make custom UI for anything specific.
     
    mahdiii likes this.
unityunity