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. Dismiss Notice

Should i put behaviors in Manager Classes or on instantiate objects ?

Discussion in 'Scripting' started by ukioq, Sep 26, 2016.

  1. ukioq

    ukioq

    Joined:
    Oct 17, 2015
    Posts:
    2
    Hi everyone,

    I’m making my first game and i have a very fundamental question : what’s the most efficient/clever way to setup things between putting my methods on « manager » type classes or directly on the GameObjects ?

    My game is a tile based strategy game, like a boardgame with figurines where you can move one of your figurine at the time while the AI moves the others. My question is about the way to handle units objects (and tiles objects actually)

    My first idea was to handle behaviors and interactions in Manager Classes (GameManager, MapManager, MouseManager…), dealing with Custom Classes for my units and tiles, witch instantiate GamesObjects for the scene.

    A - Managers (singletons) <-> B - Custom Classes (in dictionaries, not MonoBehaviour, for properties and states) <-> C - GameObjects (for render, collision and animation)

    That way, if units are off screen i dont have to instantiate them but they’re still exist and behave.
    But since i dont put the behaviors scripts on the units (& tiles), my managers have to loop through my dictionaries for each behavior (some in the Update function, some with Enumerators).

    Is this a good way to implement my game?
    Should i use MonoBehaviour type classes instead of custom ones for my units and put the behaviors on it?
    Or should i merge B and C into GameObject and simply not render them when they are offscreen?

    On one side i have a lot of loops and tests, on the other a lot of objects in memory with the same scripts attached to…

    Here are two exemple of this :
    - i made a MouseManager with a raycast hittest to select units, but should i put a OnMouseDown on each unit instead?
    - unit have a downtime, i update each downtime trough a loop on the Update function of my GameManager since i can’t do this on Custom classe.

    I hope i’m clear enough.

    This may be very basic questions but i can’t find a proper answer on the net, so i hope some here could help me.

    Thanks
     
  2. JoeStrout

    JoeStrout

    Joined:
    Jan 14, 2011
    Posts:
    9,840
    First, don't worry about not rendering objects that are offscreen. Unity already does that for you. And this would be premature optimization anyway.

    You should structure your code in whatever way makes it the simplest, clearest, and easiest to maintain. It's hard for me to say which way is going to be that for you. But in general, you're better off embracing the "Unity way" than fighting it. That means a lot of small, simple scripts on each of your various GameObjects, each responsible for just one small aspect of behavior of the object they're attached to.

    You will still occasionally need a "manager" object, for things like keeping track of the game state — whose turn it is, etc. But do use simple MonoBehaviour scripts wherever that makes sense.
     
  3. takatok

    takatok

    Joined:
    Aug 18, 2016
    Posts:
    1,496
    What do you meant by this:
    Each unit can only move again after a certain time has passed?

    Note: When I use the term "manager" I mean a game object whose job is specifically control the actions of other GameObjects. A "BoardManager" that holds the information of what pieces are where isn't really a manager. Its just the Board Game Object. It could expose some Methods for other objects to tell it they moved, ask whats in a square etc.

    I think you have very little need for managers in most cases. For example moving pieces can be handled like this:
    • Give unit Prefab bool isSelected
    • Give unit Prefab OnMouseDown Fuction that sets their IsSelected. (assuming they have colliders)
    • Unit handles its own selection state by changing its own color, maybe flashing or whatever
    • Let Each Unit implement the IPointerUp/Down Interface. IPointerUP just returns if IsSelected is false
    • Now they Unit can get the next tile the user clicks on while they are selected.
    • Then the unit asks the BoardGame Object if its Legal for it to move there
    • Unit handles its own Movement to the tile and tell the BoardGameObect thats where it is
    • Now Unit sets its TimeSinceIMoved = 0f
    • You can then have the Update function check and reset this variable as time passes so it can use it to see if its legal for this unit to move in the above steps. SO no need to have a controller object update units downtime, they can handle it all on their own.
    Also all that functionality would be split up into UnitMouse.cs, UnitMove.cs, UnitGraphic.cs etc

    More along this vein. You could have a SoundPlayer GameObject. When the Unit calls the BoardGameObject and gets told its not legal to move someplace.. Unit can tell the SoundPlayer Object to play IllegalMove Sound. Thus all your Prefabs could just have a few key GameObjects (SoundPlayer, BoardGameObject) dragged onto them, and you could write your entire game with the idea that every GameObject is self-sufficient.
     
  4. ukioq

    ukioq

    Joined:
    Oct 17, 2015
    Posts:
    2
    Thank you both for the answers.

    I think this is what i expected : i have to refactor things in a more "unity way" as @JoeStrout says.
    And actually it seems more simple that way.

    Yes, the game is real time, you can play a unit when you want but each action freeze the unit for a certain time.

    That's the way i get this too, but i made them do everything...

    It's not only about rendering, I started the other way because i thought having all those objects with the same scripts ticking around will be memory (and cpu) consuming.

    Thanks again for the advices, it's time for me to put all this in good shape.
     
    JoeStrout likes this.