0
\$\begingroup\$

I'm making a game in Unity for my game dev course in uni. I hope the question isn't too confusing but I have bolded sort of like a TLDR at the bottom.

My level currently has a pregame UI panel, to set number of players and lives, and that panel gets hidden in midgame. When a winner is found, the midgame UI is hidden, and I unhide an endgame UI panel which shows the name of the last survivor, and the LevelManager emits these events that tell my UI to do that, along with data about who won, the player object that won, etc.

I have an EventManager singleton that I currently use that the UIManager can use to subscribe to the LevelManager emitting a game end event. I pass through data or params using CustomEventArgs, and the UI can use that data to update itself. So essentially, I'm using the former method in my title, where a UIManager just hides or shows panels based on its own method calls that it receives through events from the LevelManager, and has no idea whether or not the game is over, or done, or is started, it just does its own method calls based on the events it's subscribed to and I manually show and hide pregame/postgame panels in these methods.

But I was wondering whether or not a better way would be to add some sort of state machine to the LevelManager and just have the UIManager change based on tracking state changes of the LevelManager. If the LevelManager changes its own state, the UIManager would just receive information about the LevelManager's change in state and hide/show its own panels automatically depending on the current game state? I feel like since the UI is so near the LevelManager in terms of having to use the LevelManager's information, I should be having the UIManager ask for and receive data from the LevelManager directly, instead of changing UI naively with event calls and data passed in params from ouside.

What do you all think? Should a UI system stay sort of uncoupled from a game manager and only change itself based on method calls and passing in data with params, or should the UI system just keep a reference to some global game state and know when and what to change through changes in this global state?

\$\endgroup\$
2
  • \$\begingroup\$ "Should" is a tricky question to answer in games. All a game really has to do is give a great play experience and ship on time. Whatever allows you to get there is what you should do. It sounds like you have a working solution already - do you foresee a problem with your working solution that could threaten the player experience or your ability to complete the game on time? If so, ask for a solution to that specific problem you've identified. If not, then whether or not this solution is "optimal", it may well be "good enough" and your time and attention could be better spent elsewhere. \$\endgroup\$
    – DMGregory
    Commented Dec 11, 2020 at 23:05
  • \$\begingroup\$ @DMGregory thank you for giving such a succinct answer on sort of a broad question; I really do agree with you about leaving something as "good enough" based on whether or not a foreseeable problem can or can't be seen. It works for now using the naive implementation, so I might just keep it at that and come back to it to refactor if I do end up having to! \$\endgroup\$
    – yookakim
    Commented Dec 12, 2020 at 0:48

1 Answer 1

1
\$\begingroup\$

As a project gets bigger tighter coupling starts becoming a bigger problem since it leads to any small changes becoming nightmares. This is because if classes depend on each other, changing one class will affect many other classes. As a project grows it’s good to try to decouple classes where you find this starting to occur. As @DMGregory mentioned, it’s good to keep things as is until you notice a problem.

As for UI, with direct references, you may start to find that any small changes to your managers completely break your entire UI. This might slow down your development considerably in a larger project. Moving to an event system, or an observer pattern can help decouple and reduce such breakage.

You need to balance getting things done quickly with helping future you’s quality of life. If you’re building a quick prototype, don’t bother. If you expect to reuse the code, or use it in a long term project, it might be worthwhile to engineer it a bit more carefully.

Myself, I usually get things working quick and dirty, then every week or two take a pass on some things that seem like they might be an issue in the future. But I don’t go over all the code, just code I’ve ended up working on a lot or things that bother me.

\$\endgroup\$

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .