Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. Have a look at our Games Focus blog post series which will show what Unity is doing for all game developers – now, next year, and in the future.
    Dismiss Notice

Question UI not tied to player or GameContoller

Discussion in 'Game Design' started by Dark_Seth, Aug 19, 2022.

  1. Dark_Seth

    Dark_Seth

    Joined:
    May 28, 2014
    Posts:
    119
    Hi All. Hope you doing well.

    I am getting to a point as normal I feel where I have the usual. Health Script on the player, 2 Slots for weapons that the player switches between . GameController with a script that contains Resources the player has collected.

    I have done many prototypes and always UI design ( Not Look ) has not been the focus. Always bind a GUI element on the GameController etc. Move to a new scen and Null errors galore.

    I want to explore this by making a proper system I can re-use and expand on.

    What do you guys do and how did you implement this?

    Did read something about receiver and signals? But got no idea where to start.

    Thanks all! Would love to get some info, Videos articles!!
     
  2. spiney199

    spiney199

    Joined:
    Feb 11, 2021
    Posts:
    2,830
    There's a lot of patterns out there about sending and receiving signals. Publisher/Subscriber, Event Broker, etc. Most if not all of them make use of delegates at the end of the day, so I would look into learning about those.

    But in the context of Unity it's often easier to use Scriptable Objects.

    For example, you could have a scriptable object to hold onto your players stats:
    Code (CSharp):
    1. using System;
    2. using UnityEngine;
    3.  
    4. [CreateAssetMenu(menuName = "Player/Stats Object")]
    5. public class PlayerStatsObject : ScriptableObject
    6. {
    7.     [Serializefield]
    8.     private int playerHealth;
    9.    
    10.     [SerializeField]
    11.     private int playerMana;
    12.    
    13.     public event Action<int> OnPlayerHealthChanged;
    14.    
    15.     public event Action<int> OnPlayerManaChanged;
    16.    
    17.     public void SetHealth(int health)
    18.     {
    19.         playerHealth = health;
    20.         OnPlayerHealthChanged?.Invoke(playerHealth);
    21.     }
    22.    
    23.     public void SetMana(int mana)
    24.     {
    25.         playerMana = mana;
    26.         OnPlayerManaChanged?.Invoke(playerMana);
    27.     }
    28. }
    Both the player and the UI can have a reference to an instance of this object without ever knowing the existence of one another. The UI can just subscribe to these delegates, and the player can call the methods. This also doesn't care about which scene the UI or player are in (ideally they would be in their own dedicated scenes), as the SO lives at the asset level.

    Notably anything else can listen to this object's delegates, but anything can also affect it's health, too, so, double edge sword there.

    Obviously it's just a quick example and a real world case would be much more robust. Just illustrating a possible solution.
     
    tmonestudio and Dark_Seth like this.
  3. Dark_Seth

    Dark_Seth

    Joined:
    May 28, 2014
    Posts:
    119
    Ohh. Thank you. Give me some direction!
     
  4. BIGTIMEMASTER

    BIGTIMEMASTER

    Joined:
    Jun 1, 2017
    Posts:
    4,835
    Game Programming Patterns

    i'm always recommending this book, it has helped me a lot^

    just a couple threads down i was asking similar questions and there are pretty thorough and human-friendly answers which are giving an overview of composition design.

    the key thing I am focusing on as I am refactoring my nearly finished first game is consistency. If there is not consistent pattern to my code, it ends up feeling more complicated than it ought to be, and that causes fatigue when dealing with it.

    By consistency I mean things like:

    Does one class tell another what to do, or does a class make decisions for itself?
    In either case, why?

    I am trying to generalize different classes into types. There is types that listen, types that direct, types that report... I am trying to make sure that the way these different types communicate with each other is always following the same pattern.

    One general rule I've settled on is that just by default, if one class is going to communicate with another, it will be via an interface. This way I am not building up classes which hard-reference each other. So for each class which may need to be directed by another, or listen to another class, it subscribes to an interface accordingly.

    I am not a professional programmer so the way I am doing things might be a little unorthodox, but I am thinking about interfaces like radio channels. If somebody wants info about GameState for instance, they subscribe to the GameStateReportingChannel interface. If somebody wants to direct some UI panel to show/hide an element, they call on the UI_VisibilityChannel interface.

    That's just how I am getting some consistency in class->class communications.

    It is probably going to help if you can sketch out your general game loop and then try to fill in smaller details from that. Something like this helps me a lot:
    upload_2022-8-22_11-57-15.png
    if i try to jump into details without having broader picture pretty well mapped out, I find that I end up doing things in very inefficient ways.
    And of course, don't spend too long on initial plan because it won't take into accoutn all the things that you don't know yet, so I think its good to make a quick attempt once you have an inkling of a plan in mind, just to figure out the weird little details that you aren't planning for, then you can update the original plan and take a better shot on the second go.


    edit:
    this guy is showing some practical examples of design patterns in unity. I am working in unreal currently but i still use this as a reference sometimes because its hard to find good, plain language practical examples.
    Observer Pattern - Game Programming Patterns in Unity & C# - YouTube
     
    Last edited: Aug 22, 2022
    Dark_Seth likes this.
  5. Dark_Seth

    Dark_Seth

    Joined:
    May 28, 2014
    Posts:
    119

    Real good info. Will take a read. What a post! Thank you!!!
     
  6. Dark_Seth

    Dark_Seth

    Joined:
    May 28, 2014
    Posts:
    119
    Thanks all. Got a System that is working that goes well with my Scriptable objects .
     
    angrypenguin likes this.
  7. angrypenguin

    angrypenguin

    Joined:
    Dec 29, 2011
    Posts:
    14,959
    Cool. What'd you end up doing, and what are its strengths and weaknesses? That kind of thing could be super useful for anyone who finds this thread in the future. :)
     
  8. Dark_Seth

    Dark_Seth

    Joined:
    May 28, 2014
    Posts:
    119
    Used Signal System. Health etc is on scriptable objects. Have a script on UI that listenes for any signals ans then reads the Scribtable objects.