I've also a tip for beginner : don't over focus on optimisations, instead make your game. If your game is not optimised, you can do it later. But if your game is not working because you spent too much time implementing good practices and well designed patterns - over commenting your code, you gonna loose precious time and energy. When you are experienced and you know what are the pros and the cons of using a specific method you will automaticly try to use the best of it. Bu when you're a beginner, just make the game.
The only optimization you should do along the way is optimizing the way your code is organized. If you don't organize your code it becomes unreadable for future you
Another downside of optimizing your game too soon is that when you add more functionality to your game you usually have to change old scripts, meaning that all the time you spent optimizing was for nothing. Optimizing once you are done with the game works nicely since you know what everything needs and can optimize accordingly.
100% agree on the Naming Convention point. I personally use the following; public Type variableName (Camel Case) private Type _variableName (Underscore Camel Case) public/private void MethodName(Type value) { var variableName (Camel Case) } This allows instant identification of public variables, private variables, and methods, not just for scope but functionality as well. All function-scoped variables are camelCase as they are easily identifiable as local within the scope of their parent method. While the author, whom I have deep respect for, recommends using PascalCase for public variables & properties, I however, find using PascalCase only for MethodNames makes it impossible to confuse methods with similarly named properties. Just my 2¢. 😁
I probably knew the majority of these already, but using the [field:SerializeField] attribute to specify that the backing field should be serialised on a property is actually ingenious shorthand. Thank you so much!
At first I wanted to complain about the title being too clickbaity, I didn't expect to learn much new stuff but wtf get set fields can be serialized?! Your videos never disappoint. This is amazing.
Coding conventions are so important. Even as a solo dev. This last one is a great tip! Always remember: readability is king. It's SO important for the person who will read your code next. And you SHOULD care about that person - cause 9 out of 10 times, that person is you! 😁
I kept typing out comments to add to what you were saying, only for you to go on and say exactly what I was going to say! I'm a software developer by trade, and work in C# on a daily basis, building an enterprise product. Whenever I sit down to learn something about Unity, I end up spending a bunch of time griping about how I don't get the latest c# features, and critiquing (in my head) the actual C# code that's used in many of the tutorials out there (including first party ones!). It's really refreshing to see someone using C# to its fullest, great video!
Thank you, every second from your every video is pure gold diggin... thank you!!! And thank you for the naming convention, I've had my fair share of confusion, bugs, and misreads due to wrong use of naming convention... Thanks for serializing a property, the mod wraparound thing and operator overloading... so useful, and more importantly so nicely explained... thanks.
I like having the convention that every 'prefab' I reference for instantiation is ALWAYS a gameObject then I never worry about having to change it's type and losing all my references. But that's just a personal choice. Great video!
Naming Conventions have always helped me quickly solve coding issues that crop up during projects, I didn't realize so many people didn't use them until I started entering GameJams.
I'm glad you said that people really need to use inheritance when it fits the situation. Always use the tool that seems the most appropriate. As for naming variables (or really anything in code), do not abbreviate unless it is very obvious what it stands for. I've also seen far too many people leaning on comments to explain a function, when naming the function something more descriptive would do just as well.
Not really. That variable is now unbounded and will wrap around eventually, with possible issues if the compiler has checks on integer overflows not known about?
great tips, I didn't know many of these even though I've been working with unity for 2-3 years. For naming conventions, I use "m_varName" for private variables, uppercase initials for public variables, underscore for parameters and lowercase for locally scoped vars. It greatly improved the readability of my code for my own sake.
It's funny because the naming conventions, I've always flipped local and private from what you do, but there is another benefit to doing it your way. If you are in your IDE and you type "_" then your private variables will populate the IntelliSense popup, and not your public, which can be handy for setting variables that no other scripts will have access to, since it will still look pretty on the outside, but remain easy to read and write on the inside. I also did not know about overloading the operators, that is indeed a VERY cool trick. It's a tier above extension methods, which are already S tier. Thank you for making this video, I always look forward to them!
I rarely write any comments, but you are just too good. I wanted to thank you for all of your videos, which helped me a lot in game-development. Keep quality of your work on high level, man, thats why we enjoy it! I recommend this channel for every developer i know. Cheers from UA game-dev Community!
The. Return. of. the. King! Good to see you, Sir. Thank you for the tips, the helpful details, and the easy to understand ways to impliment them. As always, I'm happy to see your video, and I'm looking forward to both your upcoming ones, and your larger projects. Good luck and good health.
So nice to see you getting back to releasing videos And on the last point - I think there is a special place in hell for people that say "I code for 35 years and do not use naming conventions" 🤣
No farm sim, just felt compelled to draw a cute cow for the video, which ended up taking longer than the video itself... I always seem to do that :D Thanks mate!
Wow... 3:44 Serialized 'Properties' is huge... I didn't notice that change and I really appreciate you mentioning it. It always bothered me to write a full propery to conform to Unity and C# coding conventions..! Thank You!
Along the lines of naming conventions, one thing I think can be really useful is writing out booleans as lines above the check, for example: var jumpWasPressed = Input.KeyDown("Space") if(jumpWasPressed) { //do jump stuff} The code itself is a comment, and it prevents comments/code from getting out of sync. This is of course a broader topic about variable names in general, but that's one I do that I think would benefit a lot of code since it explains the "why" of the boolean/etc in many cases. Also, if the variable is within a function scope and you're not returning it or etc, it's not allocating (on heap) or etc, so there is no real performance difference.
Thanks a lot for those hints. I am a fan of not making it harder than it is. Plus: Programming is the art of making yourself not lose track of the things you are doing. The very first thing I came up with was to separate variable scopes through naming conventions. This makes life a lot easier.
10:20 When it comes to naming conventions, people don't really mention a convention for naming function parameters. In my experience, I have personally found it more convenient to tell the difference between an injected value vs a value held or created by this object than anything else. People just lump local variables and function parameters together, but to me I just feel like a variable potentially injected from another class should be distinguished from a local variable, especially when using ref/out. I feel like C# standard naming conventions aren't really made for game development, because it puts more emphasis on identifying public vs private variables when I just don't use public variables for game development. The 3 categories for me are class values, function values and injected values.
A quick note with the mod to loop collections section. Using mod like that does have 1 bug with it, and that's the clipIndex could wrap once it hits Int.MaxValue, causing it to not loop correctly, and also since the int is signed, it'll eventually crash once it hits the negative values. Instead I would write it as _clipIndex = (_clipIndex + 1) % _clips.Length, then index directly using _clipIndex.
That was question in my head actually. Since the game is very long for example, IDX value will get so much higher values. So in first example, we reset the value to 0 which even if its a long way, still proper way. I was trying to find a better way to reset idx.. But your example seems legit.
@@TheKr0ckeR If it's a 32 bit unsigned int, and it's incremented 60 times a second, it'll take about 2.26 years to overflow. That's a long time to run a game.
Great video! Love love love that you covered the naming conventions again and didn't back down! Soooo important for the exact reasons you mentioned. ❤️
I feel so good now that I know I have been doing these for quite some time now, and better to know the things I totally missed, thanks for the heads up 😘😘
so much KNOWLEDGE! Awesome video, Taro -- I specifically liked the phrasing at the end with coding conventions: "would have gotten along a little bit better" 😆
The naming conventions tip is actually the best here. I am a hobbyist unity developer but a professional C# user for a decade and it always hurts seeing tutorials here on TH-cam with people just mixing everything together.
One minor issue with the modulo approach to index cycling is the index variable isn't really an index anymore, more like a counter, and related to that you could potentially run into overflow issues with really big numbers (not that it's really all that likely).
Absolutely, to give a simplified example of the problem: suppose we have x a uint8_t (unsigned 8 bit int). Then define "i = (x++ % 5)". Starting from x=0 we have i = 0,1,2,3,4,0,1,2, ... but when x is 255 we have i = 0. Then when x increments it goes from 255 to 0. But that means i is 0 again, so the pattern breaks whenever x overflows. Of course in most games we use uint32_t or sint32_t, so this won't happen for a long time. But if the counter goes up several times a frame, it will still overflow after a few minutes or hours which can create a hard to detect bug later down the line. So for me I would always explicitly wrap an integer back to 0 manually rather than rely on modulo operators.
@@houtamelocoding Modulus can't be predicted, it's just a very slow operations. Possibly one of the slowest math operations you can have And Mono is also not smart enough to replace '% 2' with '& 1' That said, hundred of modules per frame, most certainly, won't change your FPS in any meaningful way
Quick note: The "public Type Variable => ReturnValue;" Syntax creates a readonly property, so its not the same as having "public Type Variable {get;private set;}". The difference is, that the readonly property cannot be changed even by the instance itself, it has no setter.
The value can still be changed by directly modifying the field it accesses, so in *practice* it is the same. (unless you mark the backing field as readonly as well)
Thank you for this one. I'm trying my best to get industry standard coding, and stuff this goes above and beyond. You are so far out of the hundreds of youtubers in this category that is unequivocally straight to the point and the most professional. Looking forward to diving into more of your videos.
Still to this day, 95% of Unity tutorials on TH-cam use camelCase for all their fields. So back when I eventually learned about proper naming conventions, it confused the heck out of me since no one seemed to be doing it hehe. 🙂 Sorry to hear that people were "hating" on your naming convention video. It is definitely not deserved, and it clearly comes from a place of frustration, since most Unity tutors ignore it... Us who use proper naming conventions for some odd reason are the minority. 😅 Don't let people in the comments discourage. The information you provide is top notch and technically correct, even if some people get upset hehe. 🙂 Your videos are absolutely incredible, and are a must see for people who learn Unity.
To be fair, I was pretty aggressive in that video. The thumbnail even had big red text "Your naming conventions suck", lol! Us who use conventions know how helpful they are. The only resistance I get is from non-users... funny that. Thanks for the kind words brother 🙏
@@Tarodev I did the same thing on a video quite a while back, and ended up changing the title, since it was like moth to a flame when it come to "negative" personalities hehe. 🙂
@@Tarodev And it's healthier in the long run. 😂 The vibe of the content determines the vibe in the chat. And it's just much nicer to wake up to positivity when you check your notifications. 🙂
Very good point about privacy levels. If you want solid, clean, maintainable code that will serve you and your customers in the years ahead, then design your code with an API mindset. i.e. start with PRIVATE on most everything. Encapsulate EVERYTHING. Then, you provide a public interface to those workings, which the rest of your app uses, ONLY for those things that are needed. I suggest reading 'Writing Solid Code' by Steve Maguire. It's old, but timeless. It's the bible for making quality, maintenance-friendly software.
I really appreciated the section about naming conventions! I've been following a lot of tutorials that use the same conventions you mentioned, but I didn't understand why people always used _ in some variables, or capitalized others. I'm definitely going to follow this more now.
Totally agree about the naming convention but here's the one I prefer to use: 1. Local vars are camel case (same as the video) 2. Private member vars are also camel case but accessed with the this keyword (like this.varName) 3. Public member vars (honestly rarely used): Pascal case (starts with capital) and accessed with this keyword.
The naming convention thing is pretty smart. I do underscore for local and lowercase for all others, but I'll start testing uppercase for public going forward. Thanks for the tips!
Loved the part on naming conventions. In addition is good to remember always to give useful names for the variables, that also makes all the difference.
Composition sounds a lot like the structure in ECS. Where an entity is given components. Rather than inheriting from another entity. I built a similar composition system for my hierarchical state machine. Where I have one state that only holds states. So that I can add a state for camera actions, a state that handles controls etc. Separating actions and features which also hold their own stats to do their own thing. While the core values "transform, camera, rigidbody" called context. Are all on the player for all states to access.
The naming conventions I use were taught to me in my CS courses. Cap class publics, mCap for private class variables, then lower for local variables. I sometimes use a fourth convention specifically for counters which use usually an _ or C_
As a new dev I constantly need to go back to my codes to change something cause I learned a better way to do it, and I found myself lost in my own code several times. naming conventions not only saves time but also its way less stressing if, as I, you're coding for 3-4 hours after your 8hr job. definetelly will implement these
That last tip felt like a direct roast to me😂 and it hurts even more to acknowledge that you're completely right. There's a some great tips in here! Thanks😁
On the topic of using `mod`, it is usually slower than `if`, so saving couple lines of code can end up costing performance a bit. Usually this is not noticeable, but if you do it too much, it can add up
Thanks for driving home the point on naming convention. All the courses and tutorials I've followed in the past have been very wishy washy on them. Some instructors would use a convention in one course and then the same instructor would just give up naming conventions completely in the next course. It made me think they weren't that important.
currently kind of binging your tutorials especially because you are sticking to the MS c# naming convention. Other tutorials or code snippets often dont use them and it can get hard to follow because of this. Thanks for advocating this!
I agree with having a naming convention. Suggesting capitals for public variables is against C# and Unity's coding conventions. Capital variables are reserved for properties.
As you said readbility is as important as writting a good code. But I still don't use this naming convention because : - Local variables and parameters are colored in blue and other are in white - I always know what are the paramaters of the function because it's the first thing I look at => Then I can notice easilly if it's a local or a parameter => If a function exceed more than readable amount of parameters, I wrap them all inside a struct The only problem remainning is the distinction between privates and public. Okay here I don't have an efficient tip, I just pack my privates variables together after all the public fields and it's rarely an issue. But you convinced me to change my habit, I will probably try to put an underscore now ! Thanks for it :)
I wanted to add somthing : - I never found that modifying a variable from the script where it's contained could be an issue. I mean, if it's local or private what should you concerned ? If you have well defined the usability of the variable modified (private or public) there is no problem. If you wanted to use that modified variable from somewhere else but the variable was private and you didn't notice that when you was modifying it, the problem is not "I wasn't able to realise the variable was private" but "I misdefined it"
The IDE colours is a good addition, but it doesn't help when you paste your code to a forum or discord. I'd be keen to hear how you go after a few weeks of using the convention :)
Dam, finally someone said it! I hate that in unity it's a common thing to name public variables with lowercase char. And EVERY (or at least the one I saw) tutorials actually doing it the same way. I'm not sure why - it's way easier to read code if every scope has different naming style
I'm sad to hear you got so much hate for the naming convention video. Sure you've been a bit cocky but in a humorous way which I found quite entertaining. Glad I saved the link for myself so I could still link it to a friend since it went unlisted. I could have never imagined how much it improved my working experience once I implemented your proposed convention. Thank you so much for it!
Oh man, I'm so glad you took it on board and are enjoying it. It's such a minor change, but makes such an impact. Also, you sneaky bugger... bookmarking it.
These are really good tips, its basic stuff but not obvious, the best kind of advice. The only thing I don't care about in Unity is making everything private. Obviously using the strongest access modifier is best if you are novice or work in a team or even just prefer to do it that way. However outside this, as a solo dev, I personally do things a little differently. I still have rules about access modifiers, and its like so: Basically if it's something to set up in the inspector, its public. If its a cached component ref then its protected and its done by script. If it's a script local runtime only value then it can be private, but only if I know for sure but only if it really should be 100% private. This mentality comes from using DOTS, where all data is public anyway so better to build the discipline about access instead of relying on access modifiers. It's also less fiddling about if suddenly some other script needs to read a value. I also didn't know you could serialize properties now! that could change my setup a little since most of the time, public stuff is only public so it can be read. Communicating read/write access is really what one wants to do.
The difference here is it sounds like you know what you're doing. You have very specific reasons to not private everything, and you know both the pros and cons in doing so. As you said, as a solo dev it's different, and you can take specific liberties to fit your code style and also just to speed up development.
Really appreciate the videos. I've watched a couple now and I've really enjoyed them, ez subscribe! So many Unity videos are the same ol things for beginners, its great to see good value content that is applicable to everyone.
I just subscribed to you and you pull out the naming convention card right away. I never use naming conventions and do just fine. All my vars are built using only the letters [I, i, l, 1] and i just remember what the vars mean.
Nice one! 04:31 that is probably not only more comfortable but also faster because there's no branches and non-branching code works better at the CPU level. 05:08 The static "playSounds" methods from AudioSource internally create an instance of AudioSource and then throw it away, so it creates garbage. Protoyping only.
In my game company we use m_ for members _ for arguments and nothing for local scope It ease code review indeed! Very good advices there, thanks for the video :>
I can't believe real devs hate on you for using naming conventions. Why not just do things properly? I always recommend to use industry standards for everything unless you really HAVE to deviate. There is a reason for the standards and if you stay up to date with the industry, you could for example import libs that expect industry standards (I once did that with an API doc lib) and when I shared it, my friend complained that it doesn't work, but it was because he did not use standards. Great video!
I think you approached the subject of naming conventions with humility and grace while still holding a strong opinion. I respect that, and I used to agree with you! However, time and exposure to different code bases and people who write code have changed me, and now I think that talking about naming conventions is a distraction from the real problem. When people argue in favor of naming conventions it always goes the same way. "When I'm looking at a big function with lots of variables dancing around with the same naming convention, I have to look harder to tell what's going on." If a function is so big and messy that it's hard to tell what's going on unless differently scoped variables have different naming conventions, then the function should probably be cleaned up. The way I see it, . Why not focus on the real problem of the big messy function/class? There were 2 times in my life when I felt strongly about naming conventions. 1) When I was fresh out of college feeling like I knew how everything "should" be. 2) When I get handed scripts written by scientists/researchers/non-coders and enforcing naming conventions is easier than teaching them how to write clean code. This video is great, and I watched till the end because I learned from it. My hope for this comment is to convince you coders that your battle is with big/messy code, not naming conventions. Choose the right battle.
Something which I don't see listed in the summary is enabling advanced play options in the editor settings. This allows one to choose whether to reload stuff or not on play, which most of the time isn't needed if you're just working on level-design for instance. It'll most likely save most devs precious seconds when entering playmode. Remember to disable it when working on advanced features though!
Finally, a new video! And a good one for sure. As a senior dev, you reminded me of the operator overloading and the neat tricks you can do with them. You could do a video on extension methods (like advanced level). I saw some seriously good sh*t with them. Duck typing in C# is a very cool feature.
Naming convention is indeed a good idea. I do try to go a step further by adding some details in the var name itself. so_something for scriptable, go_something for gameobject, etc.
It's called a hungarian notation and many people advise against using it, especially when using modern IDE. One of the downsides is you have to remember to change variable name when you change its type (like in the GameObject and Carrot example)
4:06 There's actually a way to change a field to a serialized property without breaking the editor reference link. [field:SerializeField, UnityEngine.Serialization.FormerlySerializedAs("_carrotPrefab")] private Carrot CarrotPrefab { get; private set; } You'll see the reference is still retained in the inspector after the code recompiles. Afterwards, you can remove that 'FormerlySerializedAs' attribute now that the reference has been updated. This is also super useful if you ever need to change a variable name in general. So you can refactor your code without breaking references!
at 2:29 worth mention order of scripts in the inspector does matter, and you can also take advantage of using the DefaultExecutionOrder attribute at class level
Apart from naming conventions, I think what I'll seriously recommend is using regions to divide different parts of your code. If you have a script that has a lot of complicated code, using regions helps so you only concentrate on the part that needs to be worked on. Also keeping public and private variables separately is a great idea, if you mix up the private and public variables in the same area then you start having to squint, but if they're separated(u can even use regions if they are a lot) you know where to look.
100% agree on the conventions. It’s okay if you have different conventions, but PLEASE be consistent! If you aren’t consistent, it’s very annoying to spend extra time reading through your code. After TAing and grading tons of students code… naming conventions have really made my life easier, and I’m sure as long as you and whatever team you are on just stick to the same convention, things will run much more smoothly.
Suggestion for future tips, dealing with scaling and unit measures - there must be some tricks to digging about the for the mesh bounds and setting localScale? If you're a contractor you'll know all about different naming conventions!! Though it's interesting when linters get involved (in JS world they're prolific) because they are sometimes so opinionated that they discourage people from adopting new or better strategies for their code, though they hopefully teach you new ones too!
My general recommendation is to have a naming convention and stick with it. It doesn't matter which convention you use, but if you're in a group use whatever the group's convention is.
I totally agree. In the real world you shouldn't barge into an established group and try change their conventions. Certainly fight for a good rule set if you're there at conception though.
I like to name functions/methods with Capitals private begin with _ Events begin with On *Listeners begin with When scoped variables can get away with not being descriptive because I don't have to look at code I'm not currently working on to know what they're doing so I don't have a convention for them other than comments on their definition *If the listener is solely used as a listener and too complex for lambda notation
Every programmer should keep this in mind while coding:
"Code is read much more often than it is written"
And it is written much more often than it is understood 😂
@@TheClanFollows I like this
Pls someone tell this to my boss...
Clean Code by Robert C. Martin?
Once I followed the tips from the book you quote, the speed of writing increased significantly! It's kind of less stress on your brain =)
My man rolled out of bed, threw on a shirt with a hole in it and started spitting C#/Unity knowledge. Love it. Great video!
I've also a tip for beginner : don't over focus on optimisations, instead make your game. If your game is not optimised, you can do it later. But if your game is not working because you spent too much time implementing good practices and well designed patterns - over commenting your code, you gonna loose precious time and energy. When you are experienced and you know what are the pros and the cons of using a specific method you will automaticly try to use the best of it. Bu when you're a beginner, just make the game.
Man you've saved me, I realized i was doing the same thing, i wanna go with the best practice so my didn't have to write the code again
The only optimization you should do along the way is optimizing the way your code is organized. If you don't organize your code it becomes unreadable for future you
My ass looking thru five hundred methods to make the character move so I can have the most optimised and best one
Another downside of optimizing your game too soon is that when you add more functionality to your game you usually have to change old scripts, meaning that all the time you spent optimizing was for nothing. Optimizing once you are done with the game works nicely since you know what everything needs and can optimize accordingly.
@@malforacic105 Exactly !
100% agree on the Naming Convention point. I personally use the following;
public Type variableName (Camel Case)
private Type _variableName (Underscore Camel Case)
public/private void MethodName(Type value)
{
var variableName (Camel Case)
}
This allows instant identification of public variables, private variables, and methods, not just for scope but functionality as well. All function-scoped variables are camelCase as they are easily identifiable as local within the scope of their parent method. While the author, whom I have deep respect for, recommends using PascalCase for public variables & properties, I however, find using PascalCase only for MethodNames makes it impossible to confuse methods with similarly named properties. Just my 2¢. 😁
Great video! all perfect advice, and reminded me about the serialized properties :)
I probably knew the majority of these already, but using the [field:SerializeField] attribute to specify that the backing field should be serialised on a property is actually ingenious shorthand. Thank you so much!
Same!
Your videos have the highest knowledge density. Never fails to amaze me in these short videos.
At first I wanted to complain about the title being too clickbaity, I didn't expect to learn much new stuff but wtf get set fields can be serialized?! Your videos never disappoint. This is amazing.
Coding conventions are so important. Even as a solo dev. This last one is a great tip!
Always remember: readability is king. It's SO important for the person who will read your code next. And you SHOULD care about that person - cause 9 out of 10 times, that person is you! 😁
I kept typing out comments to add to what you were saying, only for you to go on and say exactly what I was going to say!
I'm a software developer by trade, and work in C# on a daily basis, building an enterprise product.
Whenever I sit down to learn something about Unity, I end up spending a bunch of time griping about how I don't get the latest c# features, and critiquing (in my head) the actual C# code that's used in many of the tutorials out there (including first party ones!).
It's really refreshing to see someone using C# to its fullest, great video!
OMG! Using the modulus for iteration to avoid overflow is mindblowing. It was so obvious I don't know why I didn't think of it.
But now we have the problem of overflowing the int :P Only use it if you know it won't (99% of cases it won't).
Thank you, every second from your every video is pure gold diggin... thank you!!! And thank you for the naming convention, I've had my fair share of confusion, bugs, and misreads due to wrong use of naming convention... Thanks for serializing a property, the mod wraparound thing and operator overloading... so useful, and more importantly so nicely explained... thanks.
I didn't think I'd learn anything new, yet I clicked on the video :D Thank's for introducing to me Mod to loop and Operator overloading :)
I like having the convention that every 'prefab' I reference for instantiation is ALWAYS a gameObject then I never worry about having to change it's type and losing all my references. But that's just a personal choice. Great video!
Agree with this one. Good video though.
Naming Conventions have always helped me quickly solve coding issues that crop up during projects, I didn't realize so many people didn't use them until I started entering GameJams.
Another great no nonsense vid :) Took away so many tips from this. Thx
I've been using unity for quite a long time and did not know most of the tips in this video. Thank you sir🥰
Welcome :)
Love it. Thank you very much man. (twenty years of dev and 3 years in Unity here)
You're very welcome Servaus 🙏
I'm glad you said that people really need to use inheritance when it fits the situation. Always use the tool that seems the most appropriate.
As for naming variables (or really anything in code), do not abbreviate unless it is very obvious what it stands for. I've also seen far too many people leaning on comments to explain a function, when naming the function something more descriptive would do just as well.
People can get carried away, you know?
Man you are my favorate youtube unity knowledge master! I had no idea they added serialization of get set properties! Keep up the good work!
Only on properties with a backing field, just be aware 😄
The mod to loop collection was sick
Awesome 👍
Agreed. Going to save me so much time in the future.
That one made me realize that I need to use modulo more. It's an elegant syntax.
Not really. That variable is now unbounded and will wrap around eventually, with possible issues if the compiler has checks on integer overflows not known about?
@@Meow_YT interesting point. Definately will have a look. Thanks for the mention
great tips, I didn't know many of these even though I've been working with unity for 2-3 years. For naming conventions, I use "m_varName" for private variables, uppercase initials for public variables, underscore for parameters and lowercase for locally scoped vars. It greatly improved the readability of my code for my own sake.
I clicked because the thumbnail is so good. I stayed because this is very useful lol
It's funny because the naming conventions, I've always flipped local and private from what you do, but there is another benefit to doing it your way.
If you are in your IDE and you type "_" then your private variables will populate the IntelliSense popup, and not your public, which can be handy for setting variables that no other scripts will have access to, since it will still look pretty on the outside, but remain easy to read and write on the inside.
I also did not know about overloading the operators, that is indeed a VERY cool trick. It's a tier above extension methods, which are already S tier.
Thank you for making this video, I always look forward to them!
I rarely write any comments, but you are just too good. I wanted to thank you for all of your videos, which helped me a lot in game-development. Keep quality of your work on high level, man, thats why we enjoy it! I recommend this channel for every developer i know. Cheers from UA game-dev Community!
Damn. Thanks dizmo 🙏
The. Return. of. the. King!
Good to see you, Sir.
Thank you for the tips, the helpful details, and the easy to understand ways to impliment them.
As always, I'm happy to see your video, and I'm looking forward to both your upcoming ones, and your larger projects.
Good luck and good health.
Long time no see!
Great stuff! Thta tip with position and rotation really f'ed me up! Been using unity for years and never knew that function existed!
You are my favorite gamedev tutorial TH-camr! All your videos are very helpful for me!
And you're my fave commenter of today!
So nice to see you getting back to releasing videos
And on the last point - I think there is a special place in hell for people that say "I code for 35 years and do not use naming conventions" 🤣
No farm sim, just felt compelled to draw a cute cow for the video, which ended up taking longer than the video itself... I always seem to do that :D
Thanks mate!
@@Tarodev cute indeed.
@@anlozge1788 Me or the cow? ;)
@@Tarodev BOTH!, So you have drawn it all yourself?! :o That's impressive!
@@PitiITNet Nope, background was from Adobe Stock + Gaussian. I did draw the cow, with heavy reference art though.
Wow... 3:44 Serialized 'Properties' is huge... I didn't notice that change and I really appreciate you mentioning it. It always bothered me to write a full propery to conform to Unity and C# coding conventions..! Thank You!
Along the lines of naming conventions, one thing I think can be really useful is writing out booleans as lines above the check, for example:
var jumpWasPressed = Input.KeyDown("Space")
if(jumpWasPressed) { //do jump stuff}
The code itself is a comment, and it prevents comments/code from getting out of sync.
This is of course a broader topic about variable names in general, but that's one I do that I think would benefit a lot of code since it explains the "why" of the boolean/etc in many cases.
Also, if the variable is within a function scope and you're not returning it or etc, it's not allocating (on heap) or etc, so there is no real performance difference.
This is great advice. This kind of technique allows to clarify what it is we meant to be testing.
Yes, please follow naming conventions ^^, it's immensely helpful and expediates the process of reading code.
Thanks a lot for those hints. I am a fan of not making it harder than it is. Plus: Programming is the art of making yourself not lose track of the things you are doing. The very first thing I came up with was to separate variable scopes through naming conventions. This makes life a lot easier.
I've been using unity for a while and still learned something, so thanks!
10:20 When it comes to naming conventions, people don't really mention a convention for naming function parameters. In my experience, I have personally found it more convenient to tell the difference between an injected value vs a value held or created by this object than anything else. People just lump local variables and function parameters together, but to me I just feel like a variable potentially injected from another class should be distinguished from a local variable, especially when using ref/out.
I feel like C# standard naming conventions aren't really made for game development, because it puts more emphasis on identifying public vs private variables when I just don't use public variables for game development. The 3 categories for me are class values, function values and injected values.
There was so many “ohhhh this is so cool” moments
Mission accomplished
A quick note with the mod to loop collections section. Using mod like that does have 1 bug with it, and that's the clipIndex could wrap once it hits Int.MaxValue, causing it to not loop correctly, and also since the int is signed, it'll eventually crash once it hits the negative values. Instead I would write it as _clipIndex = (_clipIndex + 1) % _clips.Length, then index directly using _clipIndex.
That was question in my head actually. Since the game is very long for example, IDX value will get so much higher values. So in first example, we reset the value to 0 which even if its a long way, still proper way. I was trying to find a better way to reset idx.. But your example seems legit.
@@TheKr0ckeR If it's a 32 bit unsigned int, and it's incremented 60 times a second, it'll take about 2.26 years to overflow. That's a long time to run a game.
Great video! Love love love that you covered the naming conventions again and didn't back down! Soooo important for the exact reasons you mentioned. ❤️
I feel so good now that I know I have been doing these for quite some time now, and better to know the things I totally missed, thanks for the heads up 😘😘
so much KNOWLEDGE! Awesome video, Taro -- I specifically liked the phrasing at the end with coding conventions: "would have gotten along a little bit better" 😆
Makes it a bit tricker for them to bite back at me 😁
Glad you enjoyed it, Nicky!
The naming conventions tip is actually the best here. I am a hobbyist unity developer but a professional C# user for a decade and it always hurts seeing tutorials here on TH-cam with people just mixing everything together.
That serialize property tip. Been waiting for that for a while.
One minor issue with the modulo approach to index cycling is the index variable isn't really an index anymore, more like a counter, and related to that you could potentially run into overflow issues with really big numbers (not that it's really all that likely).
Isn't the Modulo also a bit slower?
Absolutely, to give a simplified example of the problem: suppose we have x a uint8_t (unsigned 8 bit int). Then define "i = (x++ % 5)". Starting from x=0 we have i = 0,1,2,3,4,0,1,2, ... but when x is 255 we have i = 0. Then when x increments it goes from 255 to 0. But that means i is 0 again, so the pattern breaks whenever x overflows. Of course in most games we use uint32_t or sint32_t, so this won't happen for a long time. But if the counter goes up several times a frame, it will still overflow after a few minutes or hours which can create a hard to detect bug later down the line. So for me I would always explicitly wrap an integer back to 0 manually rather than rely on modulo operators.
@@YassineZaroui Maybe? Branches are also slow so the proper way of knowing this would be benchmarking.
@@houtamelocoding Modulus can't be predicted, it's just a very slow operations. Possibly one of the slowest math operations you can have
And Mono is also not smart enough to replace '% 2' with '& 1'
That said, hundred of modules per frame, most certainly, won't change your FPS in any meaningful way
Quick note: The "public Type Variable => ReturnValue;" Syntax creates a readonly property, so its not the same as having "public Type Variable {get;private set;}". The difference is, that the readonly property cannot be changed even by the instance itself, it has no setter.
You're completely right, thanks for the correction!
The value can still be changed by directly modifying the field it accesses, so in *practice* it is the same. (unless you mark the backing field as readonly as well)
@@bread8176 Same in what you can do. Different in how you can do it.
Thank you for this one. I'm trying my best to get industry standard coding, and stuff this goes above and beyond. You are so far out of the hundreds of youtubers in this category that is unequivocally straight to the point and the most professional. Looking forward to diving into more of your videos.
08:57 I was confused about this. Now i'm done! Thanks so much for this and the others.
Thank you so much! your videos are always a treasure trove of incredibly useful information🙂
And serialized get-set property - its awesome!😎
That one's my bread and butter
Still to this day, 95% of Unity tutorials on TH-cam use camelCase for all their fields. So back when I eventually learned about proper naming conventions, it confused the heck out of me since no one seemed to be doing it hehe. 🙂
Sorry to hear that people were "hating" on your naming convention video. It is definitely not deserved, and it clearly comes from a place of frustration, since most Unity tutors ignore it... Us who use proper naming conventions for some odd reason are the minority. 😅
Don't let people in the comments discourage. The information you provide is top notch and technically correct, even if some people get upset hehe. 🙂 Your videos are absolutely incredible, and are a must see for people who learn Unity.
To be fair, I was pretty aggressive in that video. The thumbnail even had big red text "Your naming conventions suck", lol!
Us who use conventions know how helpful they are. The only resistance I get is from non-users... funny that.
Thanks for the kind words brother 🙏
@@Tarodev I did the same thing on a video quite a while back, and ended up changing the title, since it was like moth to a flame when it come to "negative" personalities hehe. 🙂
Some channels flourish in controversy. I don't have the resolve for it 😭
@@Tarodev And it's healthier in the long run. 😂 The vibe of the content determines the vibe in the chat. And it's just much nicer to wake up to positivity when you check your notifications. 🙂
@@Dani_Krossing 100% this.
Very good point about privacy levels.
If you want solid, clean, maintainable code that will serve you and your customers in the years ahead, then design your code with an API mindset.
i.e. start with PRIVATE on most everything. Encapsulate EVERYTHING.
Then, you provide a public interface to those workings, which the rest of your app uses, ONLY for those things that are needed.
I suggest reading 'Writing Solid Code' by Steve Maguire. It's old, but timeless. It's the bible for making quality, maintenance-friendly software.
I really appreciated the section about naming conventions! I've been following a lot of tutorials that use the same conventions you mentioned, but I didn't understand why people always used _ in some variables, or capitalized others. I'm definitely going to follow this more now.
You'll be happy you did :)
Your hot tips are always welcome mister tarodev
Totally agree about the naming convention but here's the one I prefer to use:
1. Local vars are camel case (same as the video)
2. Private member vars are also camel case but accessed with the this keyword (like this.varName)
3. Public member vars (honestly rarely used): Pascal case (starts with capital) and accessed with this keyword.
Great video, all helpful tips for beginners and old timers alike. Thanks again and keep doing your thing Tarodev!
You know what? I will
The naming convention thing is pretty smart. I do underscore for local and lowercase for all others, but I'll start testing uppercase for public going forward. Thanks for the tips!
Overriding the + operator is pure genius!
Loved the part on naming conventions. In addition is good to remember always to give useful names for the variables, that also makes all the difference.
Composition sounds a lot like the structure in ECS.
Where an entity is given components.
Rather than inheriting from another entity.
I built a similar composition system for my hierarchical state machine.
Where I have one state that only holds states.
So that I can add a state for camera actions, a state that handles controls etc.
Separating actions and features which also hold their own stats to do their own thing.
While the core values "transform, camera, rigidbody" called context. Are all on the player for all states to access.
This channel is always pure GOLD!
I'm with you regarding naming conventions.
And I'm with you
I was wondering where that naming convention video went, glad to have it back because I coudn't agree more and have been using it myself ever since!
Fills me with joy to know I converted you
@@Tarodev it really is that much better sorry everyone 😬
Good work man .
We waiting alot of time ,just dont forget us and upload this great video 😄😄
The naming conventions I use were taught to me in my CS courses. Cap class publics, mCap for private class variables, then lower for local variables. I sometimes use a fourth convention specifically for counters which use usually an _ or C_
As long as there is something in place to save you that extra parsing step, you're doing it right.
use C99 naming conventions.
As a new dev I constantly need to go back to my codes to change something cause I learned a better way to do it, and I found myself lost in my own code several times.
naming conventions not only saves time but also its way less stressing if, as I, you're coding for 3-4 hours after your 8hr job.
definetelly will implement these
Those are great tips, I will now follow your naming convention!
Dude I had no idea that Unity serializes properties, thanks
Dude, I can't believe I didn't know most of these! Thanks for sharing!
That last tip felt like a direct roast to me😂 and it hurts even more to acknowledge that you're completely right.
There's a some great tips in here! Thanks😁
On the topic of using `mod`, it is usually slower than `if`, so saving couple lines of code can end up costing performance a bit. Usually this is not noticeable, but if you do it too much, it can add up
+1 for the naming conventions. Thank you.
Thanks for driving home the point on naming convention. All the courses and tutorials I've followed in the past have been very wishy washy on them. Some instructors would use a convention in one course and then the same instructor would just give up naming conventions completely in the next course. It made me think they weren't that important.
It's a crime how some instructors don't use them correctly, It's so fundamental.
currently kind of binging your tutorials especially because you are sticking to the MS c# naming convention. Other tutorials or code snippets often dont use them and it can get hard to follow because of this. Thanks for advocating this!
I agree with having a naming convention. Suggesting capitals for public variables is against C# and Unity's coding conventions. Capital variables are reserved for properties.
As you said readbility is as important as writting a good code. But I still don't use this naming convention because :
- Local variables and parameters are colored in blue and other are in white
- I always know what are the paramaters of the function because it's the first thing I look at
=> Then I can notice easilly if it's a local or a parameter
=> If a function exceed more than readable amount of parameters, I wrap them all inside a struct
The only problem remainning is the distinction between privates and public. Okay here I don't have an efficient tip, I just pack my privates variables together after all the public fields and it's rarely an issue. But you convinced me to change my habit, I will probably try to put an underscore now !
Thanks for it :)
I wanted to add somthing :
- I never found that modifying a variable from the script where it's contained could be an issue. I mean, if it's local or private what should you concerned ? If you have well defined the usability of the variable modified (private or public) there is no problem. If you wanted to use that modified variable from somewhere else but the variable was private and you didn't notice that when you was modifying it, the problem is not "I wasn't able to realise the variable was private" but "I misdefined it"
The IDE colours is a good addition, but it doesn't help when you paste your code to a forum or discord. I'd be keen to hear how you go after a few weeks of using the convention :)
@@Tarodev Yeah you're right ! Okay if I remember to I'll do it :D
Nice to see you back buddy...
Great...Mind-blowing
Thank you Syed 🙏
Great video with some useful tips. Thanks ☺
Great content as usual. Extra points for the sporty look today.
Ready for action at all times
Dam, finally someone said it!
I hate that in unity it's a common thing to name public variables with lowercase char.
And EVERY (or at least the one I saw) tutorials actually doing it the same way.
I'm not sure why - it's way easier to read code if every scope has different naming style
Praise!! 🙏
I'm sad to hear you got so much hate for the naming convention video. Sure you've been a bit cocky but in a humorous way which I found quite entertaining.
Glad I saved the link for myself so I could still link it to a friend since it went unlisted.
I could have never imagined how much it improved my working experience once I implemented your proposed convention.
Thank you so much for it!
Oh man, I'm so glad you took it on board and are enjoying it. It's such a minor change, but makes such an impact.
Also, you sneaky bugger... bookmarking it.
Excellent tips at a perfect advanced level 😅
Well I certainly didn't know we can serialized properties now. Thanks a lot! :D
These are really good tips, its basic stuff but not obvious, the best kind of advice.
The only thing I don't care about in Unity is making everything private.
Obviously using the strongest access modifier is best if you are novice or work in a team or even just prefer to do it that way.
However outside this, as a solo dev, I personally do things a little differently.
I still have rules about access modifiers, and its like so:
Basically if it's something to set up in the inspector, its public.
If its a cached component ref then its protected and its done by script.
If it's a script local runtime only value then it can be private, but only if I know for sure but only if it really should be 100% private.
This mentality comes from using DOTS, where all data is public anyway so better to build the discipline about access instead of relying on access modifiers.
It's also less fiddling about if suddenly some other script needs to read a value.
I also didn't know you could serialize properties now! that could change my setup a little since most of the time, public stuff is only public so it can be read.
Communicating read/write access is really what one wants to do.
The difference here is it sounds like you know what you're doing. You have very specific reasons to not private everything, and you know both the pros and cons in doing so. As you said, as a solo dev it's different, and you can take specific liberties to fit your code style and also just to speed up development.
Really appreciate the videos. I've watched a couple now and I've really enjoyed them, ez subscribe!
So many Unity videos are the same ol things for beginners, its great to see good value content that is applicable to everyone.
@@krooqs Appreciate the words Krooq. Welcome aboard
I just subscribed to you and you pull out the naming convention card right away.
I never use naming conventions and do just fine. All my vars are built using only the letters [I, i, l, 1] and i just remember what the vars mean.
Nice one!
04:31 that is probably not only more comfortable but also faster because there's no branches and non-branching code works better at the CPU level.
05:08 The static "playSounds" methods from AudioSource internally create an instance of AudioSource and then throw it away, so it creates garbage. Protoyping only.
In my game company we use
m_ for members
_ for arguments
and nothing for local scope
It ease code review indeed!
Very good advices there, thanks for the video :>
I like the idea of a unique argument convention.
If you tell me you differentiate publics with PascalCase, you will win my heart.
@@Tarodev We're using C++ so we mainly use function to get access to private variable :D
(not always depending if it's a struct or a class '^' )
Thanks for the tips - esp for the naming convention tip.
I can't believe real devs hate on you for using naming conventions. Why not just do things properly? I always recommend to use industry standards for everything unless you really HAVE to deviate. There is a reason for the standards and if you stay up to date with the industry, you could for example import libs that expect industry standards (I once did that with an API doc lib) and when I shared it, my friend complained that it doesn't work, but it was because he did not use standards. Great video!
I think you approached the subject of naming conventions with humility and grace while still holding a strong opinion. I respect that, and I used to agree with you!
However, time and exposure to different code bases and people who write code have changed me, and now I think that talking about naming conventions is a distraction from the real problem. When people argue in favor of naming conventions it always goes the same way. "When I'm looking at a big function with lots of variables dancing around with the same naming convention, I have to look harder to tell what's going on." If a function is so big and messy that it's hard to tell what's going on unless differently scoped variables have different naming conventions, then the function should probably be cleaned up. The way I see it, . Why not focus on the real problem of the big messy function/class?
There were 2 times in my life when I felt strongly about naming conventions.
1) When I was fresh out of college feeling like I knew how everything "should" be.
2) When I get handed scripts written by scientists/researchers/non-coders and enforcing naming conventions is easier than teaching them how to write clean code.
This video is great, and I watched till the end because I learned from it. My hope for this comment is to convince you coders that your battle is with big/messy code, not naming conventions. Choose the right battle.
Thank you so much for sharing. It's really informative and helpful 🙂
Something which I don't see listed in the summary is enabling advanced play options in the editor settings. This allows one to choose whether to reload stuff or not on play, which most of the time isn't needed if you're just working on level-design for instance. It'll most likely save most devs precious seconds when entering playmode. Remember to disable it when working on advanced features though!
I actually have an entire video dedicated to this 😘
Finally, a new video! And a good one for sure. As a senior dev, you reminded me of the operator overloading and the neat tricks you can do with them. You could do a video on extension methods (like advanced level). I saw some seriously good sh*t with them. Duck typing in C# is a very cool feature.
I actually have a video on extension methods... Ancient though. Don't remember how advanced I made it
@@Tarodev Yeah, I remember, but that was not so advanced, still very useful.
Great tips, thank you!
Naming convention is indeed a good idea. I do try to go a step further by adding some details in the var name itself. so_something for scriptable, go_something for gameobject, etc.
This is very interesting. I can certainly see this being beneficial
I add prefixes for my filenames, but that's a good idea too.
It's called a hungarian notation and many people advise against using it, especially when using modern IDE. One of the downsides is you have to remember to change variable name when you change its type (like in the GameObject and Carrot example)
4:06 There's actually a way to change a field to a serialized property without breaking the editor reference link.
[field:SerializeField, UnityEngine.Serialization.FormerlySerializedAs("_carrotPrefab")] private Carrot CarrotPrefab { get; private set; }
You'll see the reference is still retained in the inspector after the code recompiles. Afterwards, you can remove that 'FormerlySerializedAs' attribute now that the reference has been updated.
This is also super useful if you ever need to change a variable name in general. So you can refactor your code without breaking references!
at 2:29 worth mention order of scripts in the inspector does matter, and you can also take advantage of using the DefaultExecutionOrder attribute at class level
Apart from naming conventions, I think what I'll seriously recommend is using regions to divide different parts of your code. If you have a script that has a lot of complicated code, using regions helps so you only concentrate on the part that needs to be worked on. Also keeping public and private variables separately is a great idea, if you mix up the private and public variables in the same area then you start having to squint, but if they're separated(u can even use regions if they are a lot) you know where to look.
100% agree on the conventions. It’s okay if you have different conventions, but PLEASE be consistent! If you aren’t consistent, it’s very annoying to spend extra time reading through your code. After TAing and grading tons of students code… naming conventions have really made my life easier, and I’m sure as long as you and whatever team you are on just stick to the same convention, things will run much more smoothly.
Suggestion for future tips, dealing with scaling and unit measures - there must be some tricks to digging about the for the mesh bounds and setting localScale?
If you're a contractor you'll know all about different naming conventions!! Though it's interesting when linters get involved (in JS world they're prolific) because they are sometimes so opinionated that they discourage people from adopting new or better strategies for their code, though they hopefully teach you new ones too!
My general recommendation is to have a naming convention and stick with it.
It doesn't matter which convention you use, but if you're in a group use whatever the group's convention is.
I totally agree. In the real world you shouldn't barge into an established group and try change their conventions. Certainly fight for a good rule set if you're there at conception though.
I like to name functions/methods with Capitals
private begin with _
Events begin with On
*Listeners begin with When
scoped variables can get away with not being descriptive because I don't have to look at code I'm not currently working on to know what they're doing so I don't have a convention for them other than comments on their definition
*If the listener is solely used as a listener and too complex for lambda notation
yesss knew all of them :D great video again :)
Your video is always great! Thank you so much :)