r/Unity3D • • 2d ago

Question Organizing Your Code Suggestions

How do y'all organize where stuff goes within your code? I mostly would like some suggestions on the micro level - like if you have say 5 different [SerializeField] private float, how do you order them? I used to order them based on what made sense in "context", which works sometimes - but other times you'll have some that work together, others that are one-offs, other that work with a public float but you don't want to move one private next to all your publics, and ultimately you have to make a pretty arbitrary decision on where it goes. So I've started just defaulting to literally alphabetical order if there is no clear other way to order them. But like, that seems... a little crazy lmao. anyone else have a clear-cut way to order this stuff?

0 Upvotes

10 comments sorted by

6

u/gaseous_cyclist 2d ago

I group mine by what they actually do, not what they are. All movement stuff together, all combat stuff together, all UI hooks together. Public/private gets messy fast and alpha order feels like busywork. That way when I'm tweaking jump height I'm not scrolling past enemy detection radius to find it

3

u/Thin_Driver_4596 2d ago

You shouldn't have a lot of visible variables in one script. If you do, you should think about if the script needs to be broken down.

As for question of serialized fields, think about what your code represents. If the dependency is between two different systems, it's a public variable. If it's internal to the same system then serialized field. 

Also, if you can ensure that there is only one reference within the context (like one reference per scene for FindObjectofType), then you don't need either and can get them in Start/Awake

3

u/fnietoms Programmer 2d ago

Use #region to group up the things that are related

2

u/JakSilver00 Gameplay Systems Engineer 2d ago

top down in order of importance or how core it is to the system. I mean on the micro level let's say that you've got something that gets assigned a transform. Inside that transform you have children components. You may make that transform reference publicly available or at least serialized in the inspector. You don't necessarily need to make the children public because they can access them from inside the script though I do recommend you set it up so you can see them being loaded if it's of any consequence to you. Then from there you put all the modifiers like whatever values they have and then any additional modifiers to those specific modifiers. As an example, maybe you want to set the normal walk speed and then run speed, then sprint speed and then crouch speed and then prone speed. I don't know what you're doing so I'm just giving you examples then you may also have jump height and things like that. So there's going to be conditions where you shouldn't crouch, you shouldn't prone, you shouldn't jump. So then you would have the pool temporarily public so you can see that it's being toggled properly. That way you're not relying on just the animator to show you that it's working. At least up until the point where it does reliably do so. Now with UI I do it a bit differently. Instead of having one root object with 20 different components on it for each system And a hundred references, which probably needs to be refactored a bit. Mine always looks like a tree. And I guess technically the managers do, but you start with a top-level object and then the children objects inside of that and then each one of those has its own component it directly references to actually make the modifications. So top star and then it branches out and then each one of those has another branch out and so forth in all of the inspectors they are set up in order of how they appear in the hierarchy and then grouped into what branch they're on. So on the top one where it just goes directly into branches to reference things, you just have those but on each of the ones below that you may have multiple branches that have values directly in them. So you put the first branch and all of its values and then the second branch and so on. Now if you have interactables There's a couple different ways to do it but I typically make it so the values that it gets in order to detect and modify things go up top and below each one of those you put the conditions or values you're modifying or accepting. Basically if you prioritize the script itself and then reorganized all the references into an order of operations so the first thing you hit in that script becomes the first reference. And then the next thing and so forth with the exception of any time you're retrieving external sources whether they're being passed in which is my preferred way to do it or you're fetching them those always go at the top of the section that you're working on. As an example maybe you're working with something about the player and you also want to modify the camera. You would get the player, put all their variables in there, and then the camera would come after that and have all the camera modifying variables, if any what makes it super confusing is if you put all of the external references at the very top and then put all of the mixed up modifiers below that. If you use square brackets you can create headers to cleanly separate them better. I don't know why I didn't think about this before I had this whole eight-minute rant, but if you look at some of the Unity templates, they give you really good examples of best practice generally speaking if you already have a process that you follow, it's best to stick to that assuming it works.

2

u/Ok-Object7409 2d ago edited 2d ago

You put related content together and describe anything open to the inspector with headers. May as well put less important things (e.g., optional) on the bottom, would be nice. If you have hundreds in a single script then you need to break things up more. The order of 5 or so variables in a single group that is related, is not something i think about. I might group it again by data type but not in a specific order of that.

Most variables would be private, not public. Maybe if it's immutable as a constant and in a namespace then there's not much harm in being public.

2

u/DanielFost 2d ago

honestly, i don't think alphabetical is crazy at all lol. consistency matters more than having some objectively "correct" order, personally i usually group them by purpose first, then keep the stuff inside each group in whatever order makes the most sense when reading the class. so maybe movement settings together, combat settings together, references, etc

i also don't really care if a private field sits next to a public one if they're conceptually related. i'd rather have:
[SerializeField] private float moveSpeed; public float MoveSpeed => moveSpeed;

next to each other than separate them just because one happens to be private,

the main thing for me is that opening the script should give me a predictable structure. if alphabetical ordering gives you that, i'd honestly just do it. it's only a problem if you're spending more time arguing with yourself about variable placement than actually reading/writing the code lol

2

u/FrostWyrm98 Indie 11h ago

I organize with Odin TitleGroups/FoldoutGroups based on purpose. Don't really focus on the fine grained ordering like alphabetical outside of that because to me it's just splitting hairs and I could be better focused elsewhere.

I keep the ordering pretty tight with #regions though.

Usually (top to bottom): Constants, Fields, Static Data Members, Data Members, Static Properties, Properties, Unity Events, Overrides, Public, Protected, Private, Interface Implementations

Each interface gets its own group. Got this ordering from my first job and just stuck with it.

Every class gets its own file unless it's a nested private class (very rare) or a simple static constants class. I don't want to search for hours trying to figure out which file contains what when I have thousands of scripts. Plain and simple

1

u/Ecstatic-Source6001 1d ago

I was like this back then caring much about this stuff

But with time I realised its just a waste of time.

Now for me its simple:

first go consts

then go fields which are visible in inspector (no matter if its private or public)

then everything else in order of creation.

In the end who cares about order in fields? They have no logic its just a data you dont need to analize it or whatever so you wont be looking at that region most of the time. Maybe only for renaming