Too subjective and argumentative
What are best practices for using GameObjects and public fields?
In my game, I'm using a lot of Manager classes to handle different areas of the game. For example, I have a TownManager class that has a BuildingManager component and a ResourceManager Component. The BuildingManager then contains a list of the current buildings located in the town, etc. I have pretty extensive programming experience with Java and a couple other languages that aren't OOP. From my Java experience, I have a natural desire, when creating something like a TownManager with a Script component of the same name, to create the child Managers not as GameObjects, but simply class in another script, which are set to private fields on the TownManager. I realize that this means that accessing the current buildings in a town would be like TownManager.getBuildingManager().getCurrentBuildings() or something like that, but that seems like normal practice to me.
However, Unity has multiple options for things like this. Instead of privately initializing the ResourceManager and BuildingManager, I could make those fields on the TownManager public, create new ResourceManager and BuildingManager prefabs, and drag those in the engine. Or, I could make the fields private, but instead of just initializing the Managers as classes, I could actually instantiate a ResourceManager and BuildingManager prefab and set those to the values of the field.
My question is: which of these is better? Is there an encouraged method or rule of thumb? How do I know when, having a class, I should:
make its fields public and drag many scripts/GameObjects on to them,
make its fields private, but instantiate script/GameObjects at start to fill those fields,\
make its fields private, and fill those fields with non-GameObject classes (classes that don't derive from a monobehavior, I guess)
To try and make the question clear, think of a Player that has an inventory. The player is a GameObject with a script component class also named Player. To make an inventory, should I create a public inventory field and drag an Inventory game object onto it, or should I just instantiate an Inventory game object at start, or should I have the inventory object exist solely as a class in a script not attached to another game object (so to reference the inventory, you would have to use Player.getInventory(), or something like that).
I hope that makes sense, and I'd be happy to clarify or edit the question if need be. My big thing is that I want consistency across the board - I don't want some classes to make a lot of use of public fields and dragging in the Editor, and some others to have a lot of private variables and classes that the Editor can't see. In my eyes, it seems like it would be better to have either a small amount of GameObjects with many script components or one script component that use many different classes, or to have many GameObjects with different scripts, and have those GameObjects themselves be used by parent GameObjects/Managers.
Debatable questions like this that don't have a correct answer are better suited for the forums :)
That being said, do whatever comes easiest. There are $$anonymous$$iscule performance benefits to be gained by not using GameObjects and $$anonymous$$onoBehaviours when not needed, but nothing worth redesigning your architecture over or staying away from using them.
$$anonymous$$y thought process when deciding when to use or not to use prefabs for example, revolves more around maintainability rather than actual program$$anonymous$$g: would the old-school resource management system that i'd write myself for a certain resource adapt to changing needs/design better than a prefab system would etc.
A variable doesn't have to be public to be assignable in inspector. You can make a private variable visible by using the SerializeField attribute. I tend to use this a lot since i don't want intellisense to offer me fields that shouldn't be changed from outside the class.
With Unity just like in all program$$anonymous$$g i try to at least loosely follow some kind of a $$anonymous$$VC pattern... and I try to use prefabs etc. mainly for the View part because they make accessing resources so convenient. And because gameObjects are pretty much THE way to show anything on the screen in Unity :P
On top of that i use $$anonymous$$onoBehaviours for $$anonymous$$anager type classes etc. that need an Update() routine and don't have a 'parent' handy that could call it for them. $$anonymous$$onoBehaviours also have the events that get called when the app is taken to background on mobile etc. not to mention all the physics related events like OnCollisionEnter. If you need those, it's just handier to do things the Unity way because frankly there's no need to fight it :)
I figured that there might be some kind of accepted and mostly objective best practice for this, so I decided to take a gander with answers, but you're right, it is quite open ended, my bad (:
That's a good thought though. I'm definitely trying to keep an $$anonymous$$VC-like architecture, but being new to Unity, I wasn't sure if it was good to keep a lot of classes that were only visible as fields to other classes, or that weren't outwardly visible to the editor. That's a good tip about the SerializeField attribute though, I forgot about that. Thanks for the thoughts! Like you said at the end, I'm just trying to figure out the Unity way haha (:
Follow this Question
Related Questions
Can't reference script of parent 2 Answers
Enabling and Disabling a Canvas 1 Answer
How do I remove ALL components from a gameObject? 3 Answers
error cs0103 GetComponent().sprite 0 Answers
Unable to correctly use game objects? 2 Answers