Search Unity

How to design Project architecture

Discussion in 'Game Design' started by LOSTSOUL86, May 22, 2020.

  1. LOSTSOUL86

    LOSTSOUL86

    Joined:
    Apr 17, 2017
    Posts:
    10
    Hi
    I am programming in C# in Unity I created a game and I published it. So i am quite familiar with writing code. I will be starting a new project soon.
    I need help with learning more about code/game design. I will describe below what I struggle sometimes, I am not certain of and I would like to improve on.
    I am not sure how to name this subject so I am looking for advice. What course to take what books to reading and how this subject is called.
    What I am not certain and sometimes struggle with is:
    -What is the best way to organize classes
    -what is the best way to split tasks between the classes
    -When certain task should have separate class
    -Which game object should hold certain class
    -Should I control the objects from the class attached to the objects or make external game object with class that will control all objects
    -Should input class be attached to the game object that it controls or separate object
    -What is the best way to split tasks between classes
    -How to pass information from one class to another when needed

    As I said I know technically how to implement the functionality of above but how to learn what is the best practice and how to organize it in a proper manner.
    Please advise best course to take to learn this.

    Thanks Wojciech
     
  2. dgoyette

    dgoyette

    Joined:
    Jul 1, 2016
    Posts:
    4,195
    That's a lot of topics, each of which would probably be better off as a different thread, probably in the Scripting forum, where those topics get a pretty good amount of attention. However, for many of the topics you raised, the "best" approach will depend on the kinds of things you're doing in your project, and on the criteria on which you rate the approach as "best". As a high-level example, the "best" approach might involve an extremely complex framework which does all sorts of advanced stuff. But if your game doesn't seem that kind of complexity, it's probably no longer the best solution. So, my recommendation would be to take these topics individually, and try to provide some more context on the specifics of your needs within the scope of your project. That will help guide others to understanding what makes sense for your projects.

    But, I figure I'll give my opinion loosely on some of these things:
    • Organizing Classes: I firmly stand by not making things too complicated early on. I've wasted a ton of time making complex inheritance-based approaches only to realize later that I just needed a single class plus a config file. So, I'd avoid having too complex an inheritance structure until you really need it.
    • Splitting Tasks: You should be a bit more clear on the specifics here. But, I'll interpret this as having two classes that somewhat inform each other. In my game, I have one class that handles movement, but it's dependent on another class that detects things like whether the player is grounded, on a slope, etc. In such cases one class has a reference to another, either having been provided in the inspector, or finding/assigning it at Start(). In general, it's pretty nice to have small, isolated bits of code that specialize in a single thing, allowing other classes to make use of the results.
    • Separate Classes: This one is more of a toss up. I personally end up splitting up classes mainly when I think the class is too complicated for me to fully understand anymore, or if multiple classes need similar functionality. But I have some outliers to that. Probably my most complex class is my First Person Character Controller. It's quite big, and its Update() method basically calls 20 other independent methods, all detecting and doing different things. I could break that functionality out into different classes, but I don't think it would improve anything at this point. I can work on individual parts of the class without breaking the rest of it, so functionality is already fairly isolated. And no other classes in the game need to reuse any of that behavior. So, my FPCC remains a very large class.
    • Game Objects holding classes: This is probably referring to the use of things like Singletons to manage global data? Maybe you could be more specific here. I personally use a large number of "Directors", which is what I call singletons with DontDestroyOnLoad, and a large number of "Managers", which are singletons that get reinstantiated every scene. Then of course there's all the one-off objects in the scene that aren't singletons. I'm not sure if that kind of approach is exactly a "pattern", but it seems to cover all the bases for me.
    • Controlling Objects: This largely depends on the context, but I'd say that an overarching controller in each level/scene/area makes sense. In my game, for example, some AI opponent has its own controller that lets it perform all of its actions. But I can still use a scene controller to tell the AI to go do something it wouldn't normally do with its AI. I'd say, in general, that if you need two independent things to do something in a coordinated fashion, you probably want a higher-level controller to manage that process.
    • Input Classes: I don't think this really matters too much. However you want to do it. I personally have it as separate classes so that I can inject some simulated input into my game, for testing purposes, but otherwise I don't think it's too bad if a class monitors directly for input.
    • Splitting Tasks: Probably you should decide whether a class it performing two reasonably distinct tasks, and split that into two different classes, but only if there's value to doing so. Breaking things into a million small pieces definitely adds complexity, even if it's theoretically "cleaner". But if you don't benefit from splitting a class into smaller pieces, each dedicated to a different task, I probably wouldn't bother. It's only when a new class comes along that needs some of that behavior, but not all of it, that I'd split up the behavior.
    • Passing Information: I think this is the most complex question, with lots of approaches. I use three general approach:
      • Sometimes a scene controller is enough to just have a handle on a few things and pass some data between them.
      • The next step up is having classes ask singletons for information, or provide information to singletons.
      • Next step would some kind of pub/sub event system, where classes can inform anyone who's listening that something happened, and any class in your project could handle that response.
      • Anyway, this one can get real complex, so you should probably state some specifics of what you're trying to pass around.
     
    _6__ likes this.