Weird question, but I’m curious how you all organize your files. When I started I had separate files for components and systems, and I mostly used [GenerateAuthoringComponent] if I needed to attach something to a GameObject for conversion. I was also doing a lot of procedural work where I assembled the entities in code. I used to find it really annoying that a lot of Unity’s samples had an AuthoringComponent Monobehaviour, a Component, and a System all in one file. It seemed like it made things hard to find. But now I seem to be doing some of that for systems that are really focused on one component. Just curious what your approach is. It’s one of those little things that I keep changing my mind on while I’m working on a project.
It went very similar for me. Having components inside the system files makes a lot of sense to me now. Why have a single file somewhere else? Doesn’t organize very much, does it?
I still have a component folder for authoring components because we’re forced to have it in a single file and, when having a conversion process, it makes sense there.
For the rest I have a systems folder with folders that categorizes these systems on a higher level. Often in game mechanics.
From a project file analysis it resembles old C projects very much.
My file organization is all over the place but I attempt to group them together into similar categories.
The only naming convection I enforce upon myself is that all mono-element components must be singular (so no “-s”). Components containing FixedLists or my own implementation must be plural.
The suffixes are reserved “-Chunk” for IComponentData intended to be a chunk component, “-Shared” for ISharedComponentData, and “-Singleton” for singleton components. I have not yet needed to use any DynamicBuffers but I’ve reserved the “-Buffer” suffix for any components inheriting IBufferElementData.
An example: FactoriesChunk inherits IComponentData and is a chunk component. It also contains a FixedList128 so the primary word is plural.
I dont really use GameObject conversions, prefering to instead instantate all my entities manually, so my authoring is fairly empty with one mega system initializing all 80,000+ entities at startup currently circulating in the simulation.
We are following a file structure organized by mechanics/features. The files are then separated into two folders Data and Systems. This works quite well for us. It’s really easy to find what you are looking for by using that layout.
Conversion is in it’s own assembly and we aren’t using any GenerateAuthoringComponents. The reason for that is that in almost all cases we’ve seen it makes sense to pack multiple components into one authoring.
It’s a lot easier to add a VehicleAuthoring to a vehicle instead of figuring out all the 15-20 different components to make it behave as it is supposed to. Grouping those into one MonoBehaviour greatly reduces the mental overhead.
Another part why I really dislike GenerateAuthoringComponent is that it exposes all of your data.
You often only want a subset of the data to be actually edited but to do that with GenerateAuthoringComponent you have to add this ugly HideInInspector attribute to everything you don’t want to be visible.
I actually don’t use [GenerateAuthoringComponent] anymore. I found out that if you decide to rename the component, all prefabs break. I also don’t like putting components and systems in the same file, because the filename can only represent one or the other, and so one of the two doesn’t have a clear naming mechanism for finding it. So consequently my hierarchy looks like this (the names are slightly different from my actual convention for clarity):
_Code
Authoring
I’m not very disciplined with authoring organization yet
Components
ModuleAComponents.cs (contains all components for module)
ModuleBComponents.cs
Systems
ModuleA
A0System.cs
A1System.cs
ModuleB
B0System.cs
B1System.cs
ComponentSystemGroups
Bootstrap.cs
RootGroups.cs
ModuleAGroups.cs
ModuleBGroups.cs
Utilities
Static classes and helper structs live here
Sometimes if a system exclusively uses a component at runtime (no authoring) I will put that in a system’s file rather than components. Usually the use case for this is some system stats that I want to see live in the editor, though I have used it for temporary entity tagging in the past (which is an outdated technique now due to EntityQuery entity filtering). But otherwise, I try to keep things separate.
I have a file per system usually but not always. I group component definitions in the same files as the system that most closely relates to them subjectively. I don’t over think it.
I don’t like having a single file for a 10-40 line definition of a component (like some samples) because I run out of tabs in editors quickly. As others mentioned you can’t avoid that for authoring.
I avoid GenerateAuthoringComponent completely now for the reason DreamingImLatios mentioned.
I’ve started ordering by module, then components/systems. Each module can either contain another smaller module, and/or the components/systems needed for it. I’ve found it flexible and easy to navigate a large set of systems, a lot easier than parsing through Systems->Module->System, then Components->Module->Component, etc. Namespaces generally take the topmost module name, but I can go farther if it makes sense.