3 Easy Tips for Code that doesn't SUCK!

แชร์
ฝัง
  • เผยแพร่เมื่อ 5 ก.ค. 2024
  • gamedevguild.com - Register and Join us LIVE!
    bit.ly/3uRMXVM - Game Architecture Course
    / @unity3dcollege - Join the Channel
    unity3d.group - Join the Group (facebook)
    bit.ly/3INem13 - The Asset Refresh 50% off SALE!
    / @unity3dcollege - Join the Channel
    0:00 - What we're talking about today! - 3 great tips
    0:11 - The best part
    1:00 - Coding Conventions | Coding Standards
    2:50 - What was that??
    4:00 - Small Classes - How to do it Easily
    6:30 - Name things well - Tips on how to do that and what it means
    Standards Docs
    avangarde-software.com/unity-...
    unity3d.college/2016/05/16/un...
    docs.microsoft.com/en-us/dotn...

ความคิดเห็น • 71

  • @vladrootgmailcom
    @vladrootgmailcom 2 ปีที่แล้ว +33

    The whole world: Let's be reasonable with using electricity, less power usage is good for the environment.
    Jason: Power plant, get your ass ready - I'm making a video today.

  • @Tarodev
    @Tarodev 2 ปีที่แล้ว +15

    +1 to the naming conventions section. I made a very aggressive video about this (which I have since de-listed). Your version is far more polite with less bias :D

  • @callmedeno
    @callmedeno 2 ปีที่แล้ว +48

    My biggest problem with unity is gluing it all together. Can never decide on what's the best way, tried event driven, component based, compenents as data, things just get lost in the editor managing all the different things that are on different gameobjects. Then there is the problem if you have small components and getting the systems to fire in order, manually setting script execution order is a pain.

    • @captainnoyaux
      @captainnoyaux 2 ปีที่แล้ว +2

      hahaha man, I feel you, that's exactly what I've been testing the last month

    • @walker-snow
      @walker-snow 2 ปีที่แล้ว +1

      You need some singletons to keep everything in sync.

    • @LuukDomhof
      @LuukDomhof 2 ปีที่แล้ว +2

      I've recently been doing some full projects with a scriptable object based variable / event system. While it isn't perfect for every use case, for many different systems, especially those you have one of, it is a great system to use. It gives you the flexibility to connect stuff through the inspector and since every variable is saved in the project saving it is really easy.

    • @michaelberna987
      @michaelberna987 2 ปีที่แล้ว +1

      Unity events can be nice so that you can easily add and change callback functionality in the editor similar to onclick. One example that I like is I made a list in my class that handles player stats. The list is 2 dimensional and contains a level to activate on and then the event/function it will call.

    • @Noixelfer
      @Noixelfer 2 ปีที่แล้ว +2

      Usually you shouldn't modify the execution order of the scripts, If that's the case then most likely you have faults in your code architecture. Try to create the flow of initializations from code, don't have multiple logic in Awake where one component depends on the initialization of the other one (and they are in the same scene)

  • @j.j.maverick9252
    @j.j.maverick9252 2 ปีที่แล้ว +16

    agree with 1 and 3 but I think 2 is debatable. There’s a problem with small classes in large projects that isn’t often mentioned… memory (ours). When reading code I lose track of the functionality at a depth of maybe 6 to 8 levels. Very small classes are highly likely to end up much deeper than this. I don’t advocate for huge sprawling messy objects, but related features can IMO be left in a single larger class if the alternative would add several layers of depth to an already deeply nested object.
    My rule of thumb for all 3 of your points here is to think about a stranger reading my code, and try to make things easy for them. I know that in two years, I will be that stranger.

    • @setroid8235
      @setroid8235 2 ปีที่แล้ว

      Abstractions free our memory from extra work. I don't drill down to machine code, Assembly, Microsoft packages, or Unity's backend. You shouldn't need to drill down into your code either. If you are, then I recommend you start using unit tests, so you know your abstraction works. If your throw ALL implemetation to the top you will start programming in machine code. Even if it is just your own code you throw to the top, you are still jamming several functions worth of code into one function, without the help of abstractions.
      I can't fit that in my memory without abstraction, can you?

    • @setroid8235
      @setroid8235 2 ปีที่แล้ว

      @@aleccowan7246 I think there is a bit of confusion here. My comment wasn't in response to your comment. I don't particulary care to look at the absolute file size to judge a class. My comment is more about people who will "lose track of the functionality at a depth of maybe 6 to 8 levels."
      I think there are many people who fit into this category, who need help understanding the core value of OOP. Abstract messaging can be a real struggle, and many less-experienced programmers will try to bite off more than they can chew. They try to see the whole problem all at once, which is too much for anyone.

    • @mpbMKE
      @mpbMKE 2 ปีที่แล้ว

      @@setroid8235 I definitely see both sides of it. For sure, one of the huge benefits of abstraction is to figure out the really meaty problems and then take them out of your code with a human-friendly implementation that you'll use for the rest of the project. But I've also seen projects where people will have dozens of scripts on an object, all managing a particular granular aspect of said object, and I just wonder if it wouldn't be more efficient to have the functionality of related classes grouped into a single middleweight class. Maybe, maybe not? It might be a project-by-project issue.

  • @gamesplusjames
    @gamesplusjames 2 ปีที่แล้ว

    Using good names for variables is such a vital thing! It really makes your code so much easier to read for yourself, but especially when working with other people. Control R R is probably one of my most used shortcuts :D

  • @stamatispsarras
    @stamatispsarras 2 ปีที่แล้ว +6

    Great tips! What comes to mind when you said press f2 and rename your variables is merge conflict!!! It is really difficult to rename things in a developing project without creating friction points, with the rest of the team, when you try to merge. I feel there is a big skill and system gap between working by yourself in a project and working with a 2-10 people. All of the sudden you need to know git in a way more advanced level, maybe even writing unit tests, having reviews etc...

    • @morothar_loki
      @morothar_loki 7 หลายเดือนก่อน +1

      Please, be less afraid of merge conflicts. Learn to resolve, use tools, improve Coding Guidelines of the project / team to include a workfow and branching strategy to minimize friction. Don't let "merge conflicts" scare anyone away from a healthy "refactor early, refactor often". Future you will thank you for improving your code constantly!

  • @mpbMKE
    @mpbMKE 2 ปีที่แล้ว +2

    It's not often I watch a video like this and can say I'm already doing all the things. 😂 I'm naturally a huge stickler for project organization, and I think that's what all three of these tips come down to: being proactively organized inside your codebase. The one thing I'll cop to that you mentioned, I do let my classes have too many responsibilities sometimes. Trying to get better at that one.

  • @Nevarek_
    @Nevarek_ 2 ปีที่แล้ว +2

    I recommend learning to think about undefined states of your code. Things like networking and databases will cause all kinds of chaos and bugs if you make assumptions about your game state. This also includes data/state security for cheaters.
    Another recommendation I have is to have a maximum of two ways of implementing the same thing. For example, there can be a bunch of valid ways to set up and organize a scene, but having one way can be way too obtuse or time-consuming for unique scenarios. The "rule of two" helps when you are working with other developers, because being pedantic over coding conventions can kill productivity (when you could just adapt to an alternative style instead). This also works well with refactoring code, as you can have an old code style and refactored code style exist harmoniously in the same codebase without being hard to follow.

  • @NameUnknown-
    @NameUnknown- 2 ปีที่แล้ว +3

    i checked code from a class mate once, all the variable names where puns. It was funny to read, until you needed to know what the hell that code was supposed to do

  • @Songfugel
    @Songfugel 2 ปีที่แล้ว +3

    Very good and important advice, but sadly nothing new for me. Was hoping for some hidden World-shattering info I had missed and could help me get out of this rut

  • @SpaghettiOhh
    @SpaghettiOhh 2 ปีที่แล้ว +3

    WRT naming, I've been forcing myself to learn to stop calling main character things "Player." I've found this to be very helpful when talking about the architecture of a game and differentiating the main character from the actual player of the editor or final build, etc.
    e.g. calling the main character object "Samus" and class "SamusController" instead of "Player" object and "PlayerController."
    Something I don't see very often, surprisingly...

  • @NunSuperior
    @NunSuperior 2 ปีที่แล้ว +1

    I agree. Consistency, readability, portability, and maintainability are the big issues a coding style needs to address.
    Many of the coding conventions I use are based on the tools I have. Can my IDE handle large classes well? Then I can make large classes. No? Better make all my text files reasonably small. Can my non-IDE text editors handle tabs? Better use spaces then. Those sorts of choices. And they change over time.

  • @adventuretuna
    @adventuretuna 2 ปีที่แล้ว

    I think more beginner programmers should learn how to use Break Points and the Debugger of their IDE. While using logs to debug can be helpful, being able to step into a specific line of code, see how the code runs step-by-step, and identify the values of variables in that given instruction is a lot more helpful.

  • @DenaturowyJanusz
    @DenaturowyJanusz 2 ปีที่แล้ว +2

    When you finish changing class name or field in Visual Studio pres ctrl + . (dot). After press this you will see small window with few options . One of them is to change all references names to new one.

    • @j.j.maverick9252
      @j.j.maverick9252 2 ปีที่แล้ว

      right click on any label and choose refactor works too

    • @Any1SL
      @Any1SL 2 ปีที่แล้ว

      Right click, remame works

  • @kmud7750
    @kmud7750 2 ปีที่แล้ว +3

    What are some alternatives to a state machine? Specifically for a player? I find that having multiple actions for a FSM creates a spiderweb that starts to get messy.

    • @Any1SL
      @Any1SL 2 ปีที่แล้ว

      Goal oriented aspect programming I think its called.

  • @lordkylo1364
    @lordkylo1364 2 ปีที่แล้ว

    When is your next game dev show??? just excited

  • @lordkylo1364
    @lordkylo1364 2 ปีที่แล้ว

    Thanks for this new video!

  • @zekiozdemir420
    @zekiozdemir420 2 ปีที่แล้ว

    needed this thank you!

  • @joscpe
    @joscpe 2 ปีที่แล้ว +1

    I've only recently started putting underscore at the beginning of private unserialized variables. Really only because Rider insists by default...
    I tried doing that closer to when I started out and just hated how it looked and having the extra key presses. But now I'm a lot less concerned with such things and I've grown to the underscore convention.

    • @mpbMKE
      @mpbMKE 2 ปีที่แล้ว

      I didn't like it at first either for similar aesthetic reasons, but you really notice the difference when you start mixing multiple member variables with multiple local variables in methods. It creates a kind of a default hierarchy in your head that you don't have to think about and can't get backwards.

  • @MaximilianPs
    @MaximilianPs หลายเดือนก่อน

    Sorry for the late but I was struggling with the Unity's Third Person Character asset because it was looks terrible to me (in terms on how they code it) and also because I want to use a state machine and be able to apply most of the stuff to AI too. So I split a bunch of their code into the FSM States... then I pointed out about the HUUUGE list of variables, and that's was a big issue because all of them.. well most of them was needed and so I get the idea I split all of them into sub-class inside the same PlayerController class. which is the main class that runs the FMS... what did you think about it?... it's a good practice? 😅
    public class MovementData
    {
    public float moveSpeed { get { return _moveSpeed; } }
    public float sprintSpeed { get { return _sprintSpeed; } }
    public float targetSpeed { get; set; }
    public float targetRotation { get; set; }
    public float rotationVelocity { get; set; }
    public float rotationSmoothTime { get { return _rotationSmoothTime; } }
    float _moveSpeed = 1.0f;
    float _sprintSpeed = 5.0f;
    float _rotationSmoothTime = .12f;

    }
    public class GravityData
    {
    public readonly float gravity = -9.81f;
    public readonly float terminalVelocity = 53f; // Maximum speed reachable during a fall.
    // Time required to pass before entering the fall state. Useful for walking down stairs
    public readonly float fallTimeout = 0.15f;
    public float verticalVelocity; // Fall speed
    }
    public class CharacterControllerData
    {
    public bool isGrounded;
    public readonly float groundedOffset = -0.14f;
    public readonly float groundedRadius = 0.28f;
    public readonly float jumpHeight =0.75f;
    // timeout deltatime
    public readonly float jumpTimeout = 0.50f;
    public float jumpTimeoutDelta;
    public float fallTimeoutDelta;
    }

  • @foreducation408
    @foreducation408 2 ปีที่แล้ว

    This is really helpful video.

  • @michaelberna987
    @michaelberna987 2 ปีที่แล้ว +2

    Along with tip 3, if using Visual Studio, I recommend using 3 comment slashes to create a summary and then add descriptive information or notes to it. When you hover over the variable anywhere, it will show you this information.

  • @DJSpiess
    @DJSpiess ปีที่แล้ว

    Is there a good linter for C#?

  • @alsantour8835
    @alsantour8835 2 ปีที่แล้ว +2

    While I agree about keeping classes short, it's really tough... 200 lines ain't much... I constantly find my self using a variety of sizes, but more than 200... I find that in a 30 script project I have about 8 under 150 , 10 in the 150-300, 8 in the 3-500, and always a few beasts in 5-1k range , maybe 1 or 2 above 1000 but pretty rare... But also I'm pretty generous with my blank /n and Debug.Log lines, so I'm sure my stuff is inflated a bit...

  • @supertenchoo4271
    @supertenchoo4271 2 ปีที่แล้ว

    Very informative video

  • @Plagueheart
    @Plagueheart 2 ปีที่แล้ว

    I generally do 500 lines max, what about partial classes where other methods is moved away from the logic into a different file under the same class 'partial'

  • @DukeByte
    @DukeByte 2 ปีที่แล้ว +4

    Hi Jason🖖. If these 3 Tips are so simple. Then why is it so hard sometimes to incorporate them into daily coding? 😅

  • @joscpe
    @joscpe 2 ปีที่แล้ว +1

    All variable names should be varying lengths of underscore and nothing else.

  • @HeavyMix3
    @HeavyMix3 2 ปีที่แล้ว

    I think you forgot to link coding conventions in the description, please add it

  • @MaskedImposter
    @MaskedImposter 2 ปีที่แล้ว +6

    I use the Bracky's/TH-camr coding convention.

    • @SasoriSoft
      @SasoriSoft 2 ปีที่แล้ว +1

      Could you share the video or example?

    • @MaskedImposter
      @MaskedImposter 2 ปีที่แล้ว +6

      @@SasoriSoft I meant it as a joke. As in I've followed their tutorials so much, my code looks like theirs.

  • @lemetamax
    @lemetamax 2 ปีที่แล้ว

    Before I heard 4:00, I was thinking of how to write an entire game logic and mechanics in one class.

  • @ardaozler631
    @ardaozler631 2 ปีที่แล้ว

    Jason do you have any videos on how to keep people from hacking your game after you release it? I have been trying to learn about this topic but cant seem to find any good info online. Maybe you could help?

    • @turkeyjerkey
      @turkeyjerkey 2 ปีที่แล้ว

      Book: Protecting Games by Steven Davis, Cengage Learning, 2009. Not online, but maybe a good place to start.

    • @ardaozler631
      @ardaozler631 2 ปีที่แล้ว

      @@turkeyjerkey Thank you i will check it out

  • @markedforstrike
    @markedforstrike 2 ปีที่แล้ว

    How descriptive variable name should be? Is "_HorizontalMovementInputFallingMultiplier" too long?

  • @halivudestevez2
    @halivudestevez2 ปีที่แล้ว

    in every class I write, my coding style is different :( yes, I shall clean it up.

  • @soma78
    @soma78 2 ปีที่แล้ว +1

    Jason, I totally love your videos, they are incredibly helpful for new devs, but I have a question : how the hell can you work in that wilderness of shiny clutter ? Or is it just props for recording sessions ?

  • @SigmaWebDesign
    @SigmaWebDesign 2 ปีที่แล้ว

    does anyone else think this guy looks like teek from battle of Endor?

  • @Any1SL
    @Any1SL 2 ปีที่แล้ว +2

    For those really wanting to write better code go read "Clean Code" by Robert Martin. Very popular book in the software industry.

  • @CodyHoskin
    @CodyHoskin 2 ปีที่แล้ว

    Are you available for one on one mentorship? lol

  • @aliozer861
    @aliozer861 2 ปีที่แล้ว

    Why is your room so colorful

  • @JayadevHaddadi
    @JayadevHaddadi 2 ปีที่แล้ว

    okaaaay... i wouldn't call this beginner tips... this is more like prerequisites for actually writing code! 😜

  • @unicornslayer7
    @unicornslayer7 2 ปีที่แล้ว

    Early:)

  • @DanIel-fl1vc
    @DanIel-fl1vc 2 ปีที่แล้ว +4

    public float GetStateValue(StatType statType) => GetStat(statType).GetValue();
    Stat GetStat(StatType statType) => _stats[statType];
    I have never used this kind of syntax in my life, what's the point. I keep my stats in a list of classes that holds stats.
    Manager.getComponent().partyMembers[0].strength (An example)
    Stats of player 1, on enemies the stats are on the enemy prefab. It annoys me when I see weird syntax that seem unnecessarily fancy for no reason at all. It's not better because it's inconvenient and messier. Same with getters and setters, I understand what they do but what's the point. Private and public variables are way better.

    • @BlacKHellCaT78
      @BlacKHellCaT78 2 ปีที่แล้ว +3

      i agree with you on the part of weird syntax that often is unnecessary, but in your case getcomponent could be an issue if you use it often because its rather slow. Usually such data you either already have on the class working with the data, or have the data in a static or singleton class where you can access it, which is faster than having unity fetch it from the game object. For example at work we store the data we receive from the server in a static C# class (serialized from a JSON from the server) and in unity I then always have access to that C# class and the data, be it player stats, card data, enemy stats etc
      I dont understand your point about private and public variables being better compared to getters and setters because you never use getters and setters on anything but private (or protected) variables. You cant really have one or the other. In most projects you can definitely get away without using that part of OOP (getters/setters) but they do come in handy when you are creating a library or API or unity package that other people will use. That way you can only give them access to things they need to interact with and wont mess up any of the internal code you wrote, and then blame you for it :D
      edit: some typos

    • @MatrixQ
      @MatrixQ 2 ปีที่แล้ว +3

      Yes, there's sometimes a lot of overcomplication in code, but that doesn't mean all of it is bad.
      When it comes to getters and setters, they have their value, just seldom in the examples I've seen in tutorials. Getters and setters are good for when you need to do additional logic before getting something. And that something doesn't have to be a value, it can be an object as well (for example from a pool where it might need to get instantiated first).
      Generally, I prefer to have private properties altogether and just access an object through its methods. So instead of getting a variable and doing a calculation with it, I'd give the object with the variable the information it needs to do the calculation and then just get the result. Much cleaner that way.

    • @Unity3dCollege
      @Unity3dCollege  2 ปีที่แล้ว +7

      This is a great question, gonna do a video explaining it maybe tomorrow. (I promise there's a good reason)

    • @DanIel-fl1vc
      @DanIel-fl1vc 2 ปีที่แล้ว

      @@BlacKHellCaT78 I never thought of that, I assumed adding the list that contains instances of classes that contains the players stats would be easiest to access from the manager object. But you could probably have it be a global singleton, then you wouldn't need to GetComponent every time. But then you couldn't modify it as easily in the editor? Being able to create a new instance of anything by just adding a new list item is very convenient.
      Yeah I've never used getters and setters, in my mind they're only useful if you got a variable that you want to change every time you get or set it. And I have no idea about the other syntax in the video, I've almost recreated a complete 3D jrpg from scratch without using any of those.

    • @BlacKHellCaT78
      @BlacKHellCaT78 2 ปีที่แล้ว

      ​@@DanIel-fl1vc honestly at the end of the day the tools that help you finish the project are the best ones. Especially if you are the only person working on the project. Everything you use has its good and bad, its about knowing when to use what, just like any other tool. Yeah, there are good practises like coding standards that help you organise and maintain your code much easier. Doesnt matter if you wrote it, come back to the code a month later and you probably dont remember any of it, so sticking to a standard helps a lot. Also with the complexity and team size growing, so does the need for better organisation.
      The person above commented another quite nice use case for "getters/setters".