Categories
Game Dev Opinions

Failings of the Unity Tutorial Era

I’ve had a few topics I wanted to talk about for a while now, but they weren’t really big enough to justify a full blog post on their own. Two big issues I have with a lot of what I see online can be summed in one topic that I consider a failure in the era of the very drawn out video tutorials for Unity.

Try it Yourself

I’ve found myself time and time again, whenever I search for a topic online, only finding “tutorials” or very high level questions on forums from beginners when all I really wanted was documentation. A large amount of the questions I see online can typically be answered in one of two ways: 1) Google, 2) try it. I may come off as “holier than thou” when I say this, but the best advice I can give to any beginner is when you have a question about how something works … just try it and see what happens.

If I’m on a forum (such as reddit gamedev subs) and see a question like “what does this do,” “why is this happening,” etc., all I can really think is “why don’t you attach a debugger and find out?” Most questions I see from beginners can be solved by actually taking the time to investigate and using your brain. Instead of immediately going to reddit and asking a bunch of strangers, I would love to see beginners using the tools available to them and struggle to debug their own problems. Struggling early by printing out values, then moving on to using break points and inspecting variables, eventually even looking at memory dumps; this level of progression is very important for anyone doing any kind of low level programming at a professional level.

This is likely a side effect of how easy things are now, but I find myself firmly in the camp of “learn C then move on to whatever you want after.” Using the “bad” or “weak” tools before moving on to all the power in the world gives you perspective for how to solve problems that you otherwise lack if you jump right into the deep end with C#, Java, Python, etc.

Code Structure Please

This is definitely getting even deeper into the opinion territory than what I said above, but it goes back to my original gripe, Unity tutorials. Every time I stumble across a tutorial and find myself looking at it to see what they do, I can’t help but be disappointed in how they are showing people to write code. Everything is public, naming conventions with no structure, just throw whatever code wherever you feel like. I’ll try and keep it brief, but I do want to talk about each of these a little.

Use SerializeField

Making all your data public is an easy way to serialize your objects in Unity. I see everyone do it, and if you’re the only developer you probably won’t ever run into issues with it. In my opinion(!!) this can lead to some very bad practices. If all your data and methods are public by default, there’s nothing stopping you from accessing them directly from other scripts. Now, later on in development, what happens when you want to ensure some data member has new restrictions? Any place where you previously modified that data now needs to ensure you have these restrictions. This is where the idea of getters and setters that everyone hates comes from. If your data is always private and only modified through a designated setter, later on when you decide you want to restrict it in some way, changing it in the setter is the (theoretical) only thing you ever need to touch. Now that your data is private, it doesn’t show up in Unity though(!?), that’s what SerializeField is for. SerializeField is a property that can be applied to any class member variable to have it show up in the editor, this also means you know EXACTLY what data is being serialized and what is actually localized to your code (and only your code).

public int myData; // BAD

[SerializeField] private int myData; // GOOD

Naming Conventions Oh God Please

Something I see from a lot of people, and this likely originally comes from some Java guide somewhere, is naming conventions that tell you nothing about what you are using. I don’t have any personal grievances with particular naming schemes as long as there are enough variations to determine where a variable or function is coming from. This means that your local variables and your data members should LOOK different. Your function names and your variables as well should also be visually distinguishable. If you have a variable named coolData, what is it? Is this data local to your function? Is it a data member? Is it a property?! With a lot of Unity tutorials I see, it would be impossible to know without going and looking at the definition of coolData. I’ll give some examples below of naming conventions I’ve seen (and used) that give you just that extra bit of information from a name alone.

// m_ denotes member data!
private int m_data;
// leading _ can also denote member data, use what works for you
private int _data;

// Pascal case is very common for function names
private void MyFunction() {}

// prefixing static data with s_ is logical and descriptive
// this can also be g_ or a lowercase g for global data in some languages
private static int s_data;

// similarly, c prefixes for constants very clearly tells you what it is
private const int c_data;
private const int cData;

Based on what’s above, I think you get the idea, what about local variables though? Regular camel casing, underscores, whatever you want as long as you’re consistent and don’t overlap with what you’re doing elsewhere honestly. Camel casing (first letter lowercase) is one of the most common ones and is perfectly acceptable for local variables.

Group Code Logically

I honestly don’t really have much to say on this outside of the topic line. Lots of people like to just write new code at the bottom of the file and keep going. Grouping code together when it is used together makes it look like you at least thought about what you were writing though. C# even provides you with #region for creating IDE collapsible areas of code. If you have a bunch of callback functions for handling inputs, putting those together and wrapping a #region tag around them with an “input” label or something means you are at least thinking about what you are doing and not just going through the motions. Grouping all your serializable data together at the top means you know everything that is being serialized just looking at the top of your file. Keeping files small means you aren’t scrolling thousands of lines to find what you are looking for (this can be done with partial classes in C#). I could go on and on about ways to organize your code, but at the end of the day it will come down to what works best for you as the author, but the more readable your code is, the more likely someone is going to be able to help you when there are those hard problems you find yourself wanting to ask for help on.

Conclusion

Writing this honestly felt like a rant the whole way through. Lots of small topics, but things that I feel needed to be said. If this got even one person to try and learn how to be an “engineer” and not just a “programmer,” I feel like it was worth writing. I am a “Software Engineer,” that means I don’t just write code, I solve problems and find solutions, and that should be what everyone tries to do. Being a “programmer” and just writing code sounds a lot less interesting than actually finding solutions for complex problems then implementing them in clean and reusable ways.