Being able to make your code look like a flat list of instructions vs some kind of pyramid shape is really overlooked but it's a total lifesaver when you're hunting bugs.
@JamesMakesGamesYT2 жыл бұрын
Definitely! It even helps you recognise opportunities to refactor that you might not have spotted if your code was nested
@powerpc60372 жыл бұрын
It doesn't just look cleaner and easier to find bugs, it's also easier to add extra conditions afterwards without messing with the entire indentation tree and shifting every other condition an extra tab to the right.
@blinking_dodo2 жыл бұрын
@@JamesMakesGamesYT i refactored your statement... 🙃 You should really consider getting rid of redundant accolades... (see my contribution somewhere in this comment section.)
@ruslan_yefimov2 жыл бұрын
@@powerpc6037 also you can make lines of code longer
@tofikadigozalov94722 жыл бұрын
Its not overlooked by people who hire you tho (: Its overlooked by rookie devs who just started coding and it really slows down their learning by a lot
@Nerdsown2 жыл бұрын
I've always heard this referred to as an "early exit". It is one of the easiest ways to greatly improve readability.
@spythere2 жыл бұрын
Yeah, I also use it on daily basis and call it "guardians" because they guard the rest of code where you can't pass e.g. undefined value or unresolved task. It really makes it easier to read and manage the logic.
@Ishanatmuz2 жыл бұрын
I have been using this approach for 5 years now. Everywhere from servers to frontend to Unity. Never knew it was called guard clause.
@udyfrost63802 жыл бұрын
Same here man. Never knew the name
@phitc42422 жыл бұрын
I found out about the name once I googled for if it makes any difference or if it was bad practice (I was wondering if the code would get larger when compiled, speed performances, etc...) but now I do it all the time...
@ptidus12 жыл бұрын
Web dev here, I've seen this approach under the name "Early return pattern". Funny to see how good practices propagate even with different names.
@KiemPlant2 жыл бұрын
Me thinking I was going to learn something new (:
@Alche_mist2 жыл бұрын
I knew it as "Early returns". It's quite standard approach in Python for example.
@cappydev2 жыл бұрын
Beginner programmers, take notes! Readability and structure is king in systems
@dr_birb2 жыл бұрын
Maintainability and performance*
@cappydev2 жыл бұрын
@@dr_birb Of course, it should be structured for maintainability and performance
@mortenbork62492 жыл бұрын
@@dr_birb code is for people. Your CPU reads only 1 and 0. Humans read code. Code is for humans. Make your code readable to other humans is the first priority of your code. If no one can follow your code. You will eventually not be able to follow your code. Coders must write readable code. It is the top tier metric. Anything can be fixed that can be understood. Something that cant be understood can't be fixed. And code always changes. It's in the name. "Software" If code never changed. We would just be making hardware.
@dr_birb2 жыл бұрын
@@mortenbork6249 holy fuck learn to write like a human. Also no. Code isn't for humans, code is for computer. Humans are paid to read and write the code, even if it isn't easy/simple. Maintainability and performance was is and will be the most important thing in projects that are constantly evolving. Sure, most of the time writing clean and readable and minimalistic (simple) code is also good performance wise and is scalable, but that's not always the case, and that's why it's not the king.
@Dreadnaut25602 жыл бұрын
@@dr_birb Actually, code is for humans, it just is also for a computer. Most code we write is in a higher-level language that is interpreted through multiple steps into machine language. HLL is literally designed to be easier to write for humans. If humans can't understand the code easily, it makes it very difficult to maintain the code and even make it efficient in the first place. Code acts as a bridge between human ideas and a computer's execution cycle.
@dorky52562 жыл бұрын
That is actual genius. I've had so many cases where this was a real problem having so many stacking if statements. Great tip
@elriano12 жыл бұрын
These are exactly the sort of Unity videos I have been searching for, concise, informative and actually applicable. Please continue to make more!
@ChrisD__2 жыл бұрын
Start looking for general programming videos and not Unity videos. This video applies to any language.
@ultimatedude56862 жыл бұрын
@@ChrisD__ Not any language, but pretty much any imperative one
@ChrisD__2 жыл бұрын
@@ultimatedude5686 Shhhh, we don't talk about functional programming, we're game developers! It scares us.
@tonynussbaum2 жыл бұрын
I dont know. I think we need a few more videos on how to make a square move and jump.
@spiralingspiral722 жыл бұрын
YandereDev HATES this man for using these simple tips !!!
@Ryöken175 ай бұрын
XD that was the early project
@marzzbar2 жыл бұрын
I've beem programming for 10 years, not games, but this is a really good way to explain this. The way I visualise it is like a freeway, with exits. Most traffic goes along the freeway, but if there are certain conditions, they will exit with certain actions as per the criteria.
@lorderu12 жыл бұрын
I have no words.. as soon as I realised what you were doing my mind was blown and my code will be changed for the better forever. Thank you!
@LazerMarsupial2 жыл бұрын
I wish someone showed me this when I was starting out. This make both code easier to read but also so much easier to teach and understand. You should make a bunch more of these and in the same 'snack' sized way.. Thanks man, this is an eyeopener.
@JamesMakesGamesYT2 жыл бұрын
Glad the video was helpful!
@versenova55312 жыл бұрын
i started coding on roblox and so im used to return being to give the output of a function, but after learning that it was to return back to teh top of a method i just though "jesus christ im an idiot how did i not know that before"
@hidgik Жыл бұрын
I am not a programmer at all, but I am amazed that I was even able to understand the issue and the elegant solution offered offered to resolve it! Crazy!
@Mr.Not_Sure2 жыл бұрын
I usually oppose to use guard clauses. It can give you headaches when they're hidden somewhere in the middle of a method. The only acceptable case is when guard clause is RIGHT at the beginning of the method so it clearly visible, and it is for error-checking.
@JonasBergling2 жыл бұрын
While I agree that the best place for guard clauses is normally at the start of a method, I want to address what you said about visibility... If your methods are long enough that it's hard to spot something like that in the middle of them, they are probably way longer than they should be to keep code optimally readable/maintainable/extendable. Imo a method/function should normally have just one responsibility, if they need other stuff to be done they should delegate that responsibility to helper methods. In my experience if you consistently follow this your methods do not need to get long enough that visibility of guard clauses are an issue. SRP and the other SOLID principles are widely agreed upon for good reasons.
@Mr.Not_Sure2 жыл бұрын
@@JonasBergling I completely agree with what you said. Have to say it's just my personal story of one of my colleagues whose code was really terrible. It made me oppose even to completely valid language features like default values! And yes, I'm talking about one specific project, not in general. Your mileage may vary.
@Noname721052 жыл бұрын
As with all tools the utility comes from the user.
@dhovadick2 жыл бұрын
I agree, we should be careful to avoid the creation of "hidden" behaviors when using guard clauses, like you said. For that, I think we must put some effort to respect the Single Responsibility Principle, in this way our code tends to be more readable.
@lyons56092 жыл бұрын
This was a game changer for me when I first started writing code like this.
@R.B.2 жыл бұрын
The cautionary note here is that a function shouldn't have multiple returns if it can be avoided. Enter at one point, exit at another. What if there are multiple conditions which must be met for an action? Something which can help is a local boolean flag which can set a condition. In this example you are only writing one thing based on the state, but it might be better to have multiple conditions reported. Having a boolean shouldAttack initially set to true and then setting it to false and falling through the guard instead of returning, you can check all those other conditions as well. Then for the final attack call, put a guard which checks should attack. In this way you've decoupled that logic again but you don't have a bunch of checks which can all drop out of the method. A true guard check is one which is looking for conditions which might break the function, is the parameter passed into the function null, sort of thing. Short and not complicated logic. As a personal style choice, this is the only time I use an if statement on one line and only then if it is very well understood why. Anything more complicated like your example, I'd rather use the flag because it further breaks it up into guard, condition, and (conditional) action.
@Ishanatmuz2 жыл бұрын
@Ryan Beesley Care to show an example? Will be easier for us to understand what you mean.
@digdug14312 жыл бұрын
@@Ishanatmuz What Ryan suggested is this: private void Update() { bool shouldAttack = true; if (!Input.GetMouseButtonDown(0)) { shouldAttack = false; } if (IsSprinting()) { shouldAttack = false; } if (IsBlocking()) { shouldAttack = false; } if (IsJumping()) { shouldAttack = false; } if (shouldAttack) { Attack(); } } In this small case there isn't really any difference, but the main advantage of this code is that it is easier to find bugs because all branches pass through the final if statement, allowing you to place a breakpoint there and see what state the code is in right before it exits.
@volfdoesit2 жыл бұрын
@@digdug1431thx mate. I think this might be better approach becouse it doesn't contain those returns which are messing with whole update function if you want to have more than one action.
@Ishanatmuz2 жыл бұрын
@@digdug1431 Thanks for the explanation
@augustnasman2 жыл бұрын
Guard clauses rely on multiple return statements and that is not bad. It makes alot of sense to return a function right after a condition is met, since you then KNOW what will happen. If you dont return, somewhere else in the code you can mess up the flags making the code hard to debug. Returning is good!
@FedericoSpada132 жыл бұрын
Suppose you want to add some code at the end of everything, common to all cases (for example a special check that is always legit): now you have to rewrite everything as it was before... This reasoning can be done for completed functions that you already know what they do and so you can see that the code can be optimized. Not all functions are so straightforward!
@trancejockey2 жыл бұрын
Sorry if I'm misunderstanding you, but if you had to add something like this that would always trigger, you would just place it before your guard clauses are reached.
@FedericoSpada132 жыл бұрын
@@trancejockey Maybe it's something that must be done after you "attacked", if you was eligible to do it. If you can't attack, anyway I do something. Maybe a winning condition that is reached anyway (bleading effects): if CanAttack() then Attack(); UpdateLife(); if Has0LP() then PlayerWon();
@trancejockey2 жыл бұрын
@@FedericoSpada13 If it was something that had to happen at the end of the method (eg bleeding effects as you said), I would change the output of the guard clauses (setting a flag to false instead of returning for example), or extract the guard clauses into a separate function as in your example, which can trigger / skip the attack. My point being, we should always use guard clauses, and not return to using nested ifs as you said in your first comment.
@FedericoSpada132 жыл бұрын
@@trancejockey yes, you are right about the flag, but I think that it depends from case to case.
@Lee14G2 жыл бұрын
This is amazing. Guard clauses! I will be using them from now on. Thank you.
@pchris2 жыл бұрын
It's always nice finding out there's a name for stuff I've been doing for years
@chosencode58812 жыл бұрын
Been programming for a few years now, always had an instinct to take advantage of the empty else but I never thought of this. Thank you so much
@MyGameDevPal2 жыл бұрын
Nice thumbnails James! Also I love the way you cut out the empty space, only including relevant clips, most tutorials don’t do that :)
@isaackay58872 жыл бұрын
This video: *_Yandere Simulator dev:_* * nervously sweats and scrolls past *
@Brahvim2 жыл бұрын
I have used this concept before, but I neither thought I could make my code clean with it, nor did I know it's name. Thanks!~
@gingerbeargames2 жыл бұрын
What is good about this is that it doesn't just apply to unity. Readability is so important even when it's just a solo project, the larger a project gets the more time it takes to debug and i'm willing to bet that very few people actually enjoy debugging.
@jarkey2 жыл бұрын
i have learned this from a programming tips video 2 years ago with my colleagues, we still refer it as the most impactful tips for our career lol
@SolironBrightwoode2 жыл бұрын
Concise yet informative! Love seeing videos that don't unnecessarily bloat simple concepts. For those looking for more videos of this nature (code structure and design), search for that and leave out things like Unity and C#. It's general programming advice you're looking for. Which is the same whether you're making a game, website, api... You get it.
@CodingWithLewis2 жыл бұрын
This is helpful in more than just Unity. Amazing video.
@JamesMakesGamesYT2 жыл бұрын
Glad it was helpful!
@roellemaire19792 жыл бұрын
When I was in University the teachers always said to avoid (just dont do it) having multiple return statements in a function, especially if the function has no return value. It is (was maybe) considered bad programming
@skenming2 жыл бұрын
Good or bad is always situational when you think about it. Do whatever fits your needs in practise. In this example, 'return' just act as nothing but 'terminate here' so it is okay in this situatuation.
@wisnoskij2 жыл бұрын
It is really good in this tutorial to show how the simple inversion of the logic completely untangled the flow, but I agree in practice you want to avoid bloating a source file to twice the required line/character amount. Just use else ifs and put the attack in the final else and we can remove half the lines of code in that example.
@FunkyAnimations2 жыл бұрын
More tutorials like these are NEEDED on KZbin thank you!! I've always looked for things like this and having a video going over it is incredibly helpful
@carlosmspk2 жыл бұрын
Just want to point out you're unlikely to implement guard clauses when scanning for inputs. If you also want to monitor for another button press, the code shown here doesn't work. You'd have to go back to the original if, and switch the guard clauses with "if-else"s without returns. Guard clauses are better for "errors", be it checking for actual errors like null pointers, be it for checking for invalid actions (like the IsSprinting(), etc., in the video).
@CYXXYC2 жыл бұрын
In use case you mentioned, it certainly does not matter the way you write, and every way works for non-combining presses (mind I'm not writing in any particular language here, its an amalgamation of C++, C# and Java, and not using Unity API at all): if (button == A) { buttonA_action(); return; } if (button == B) { buttonB_action(); return; } buttonDefault_action(); if (button == A) buttonA_action(); else if (button == B) buttonB_action(); else buttonDefault_action(); switch (button) { case A: buttonA_action(); break; case B: buttonB_action(); break; default: buttonDefault_action(); break; } For multiple presses you can also write differently: if (buttons.pressed(A)) { if (buttons.pressed(B)) { buttonAB_action(); } else if (buttons.pressed(C)) { buttonAC_action(); } else { buttonADefault_action(); } } In the return way it will look like this: if (buttons.pressed(A) && buttons.pressed(B)) { buttonAB_action(); return; } if (buttons.pressed(A) && buttons.pressed(C)) { buttonAC_action(); return; } if (buttons.pressed(A)) { buttonADefault_action(); return; } // or buttons.pressed(A) && !buttons.pressed(B) && !buttons.pressed(C) So how come anyone would ever think of the code below as reasonable at all? It repeats the same clauses and looks like a mess by those very long expressions. The reason is the same as in the video: we are separating the logic from the actions, in a slightly different way: before each action there is a description on where this action would occur. We can bring out each guard into own method, which would make the code describe itself: public bool actionABReady(buttons) => buttons.pressed(A) && buttons.pressed(B); public bool actionACReady(buttons) => buttons.pressed(A) && buttons.pressed(C); public bool actionADefaultReady(buttons) => buttons.pressed(A); if (actionABReady(buttons)) { buttonAB_action(); return; } if (actionACReady(buttons)) { buttonAC_action(); return; } if (actionADefaultReady(buttons)) { buttonADefault_action(); return; } This means before each action there's a description of when this action would occur, completely separate from all the other actions (and probably the "return;" might be not be appropriate unless you are trying to write something like "do only one action per logic call", but without them it would rather be difficult to call it "guards" despite doing the same sort of refactoring as the video is trying to direct you to)
@CYXXYC2 жыл бұрын
A more practical example: imagine a top-view 2D game. You move on keyboard arrows (speed = 1, diagonal vector being longer is ignored for this example), and their movement can be combined. Here is a structural if-else code (again, syntax does not make sense): if (up) { if (left) move = (-1, 1) else if (right) move = (1, 1) else move = (0, 1) } else if (down) { if (left) move = (-1, -1) else if (right) move = (1, -1) else move = (0, -1) } else { if (left) move = (-1, 0) else if (right) move = (1, 0) else move = (0, 0) } Here is a guard-like code: move = (0, 0) if (up) move.y += 1; if (down) move.y -= 1; if (left) move.x -= 1; if (right) move.x += 1; // and that's it Now tell me which code do you prefer. You may tell me "I would never even think of writing the code the first way!", but I did write it like that when I was learning, and that's exactly the purpose of the video - to teach beginners on how to write more readable, more humane code, to make it less like mathematical robotic combinatorics and more like realistic causal chains, where it is clear what action each piece of code does.
@kleinebre2 жыл бұрын
No, this is not necessary. In most programming languages, you could simply define several buttons as handled = handle_arrow_up() or handle_arrow_down() or handle_arrow_left() or handle_arrow_right() then let each of those function handle their own button and let each return a boolean indicating whether the function ultimately invoked the handler. If the buttons require overlapping guard clauses, they can either be placed before the button handler, or moved to a function, depending on what's most efficient. If you have many buttons to handle, you might be better off calling a function from a lookup table rather than use if/else logic.
@carlosmspk2 жыл бұрын
Note that when I said "You'd have to go back to the original if, and switch the guard clauses with "if-else"s without returns" I didn't mean there wasn't a better way to do it, I just meant you couldn't get away with the if(...){...return} guard clause. Of course you can always extract methods, and create handlers, but that's not really about what this video is about which, despite the title, is guard clauses. You could, however, argue that you can always implement these same guard clauses in each button handler.
@leonardschoyen2 жыл бұрын
@@carlosmspk Advocates of guard-clauses frequently also advocate for separating out code to functions even if the code is used only once, for semantic clarity. Even if the guard-clauses doesn't work in a specific instance, other techniques can be used to reduce the indentation and improve readability. Guard-clauses are part of a technique that works great for almost anything.
@mikena85192 жыл бұрын
yes. also use this technique with principles of single function return (SFR) by incorporating with do-while(0) idiom. Many times also reducing the cyclic complexity of pre and postambles that are common.
@albertbatfinder52402 жыл бұрын
I do this every now and again, and hate myself for doing it every time! You just co-opt a block structure when there is no loop, never was a loop, and never will be a loop. But yeah, I do it occasionally because I love SFR. It might cause the maintenance programmer a few minutes head-scratching if they wonder whether the code is a fossil of an extinct loop,. Maybe previous programmers removed the necessity to loop, without having the courage to dismantle the scaffolding of the loop. A judicious comment Do-while() /* Allow early exits */ may be appreciated by future generations. Mind you, I’m old enough to remember when you could goto a label near the end of the function without having people slap their foreheads in despair and disgust. It’s all about which coding principles are more important, and by more important, I mean more maintainable.
@zf4hp246 ай бұрын
@@albertbatfinder5240 Single return was encouraged early on due to higher level languages needing formal and rigid prolog and epilog handling of the stack, register saving and restoration and exception block management prior to issuing the simple "ret" instruction. Having multiple returns usually resulted in branch instructions to some common exit point at the bottom of the function. So no real gain or change there. The problem with multiple returns is unwinding any cummulative initializations or state changes to the larger program requires multiple "gotos" to a bunch of "cleanup" labels, each with their own block of "undo" code. So, if you open a file handle and then decide to eject, you need to branch around your good code to, say, a "CloseHandle" label and execute the file close. 3 or 4 of those "undo" blocks and it starts to look like its own mess. Is there any performance hit either way? Probably not. As a C/C++ systems programmer, I'm a follower of Dykstra. I haven't used a "goto" in 20 years. And then I think it was only once. I felt so dirty afterward. ;^)
@abner20bushi2 жыл бұрын
That is pure logic. We are so conditioned (pun intended) to check what IS that we do that even when it's more logical to check what IS NOT. Excellent video man.
@javasbot51972 жыл бұрын
This is a good way! :) IMHO you could improve it with case-switch: removing all those 'if' and using a single 'return' a the end.
@jackdavenport50112 жыл бұрын
I always use guard clauses in my code. It just makes more sense to me to bail out early than to nest all my code inside of conditionals. Obviously there’s a time and a place for them but this is a perfect example!
@JACKHARRINGTON2 жыл бұрын
This is about the first practical thing that I’ve learned about coding.
@Exas4000 Жыл бұрын
this is the kind of thing that make sense, but didn't think about until now. Thank you very much. Not a solve all for everything, but i feel like i can do great work with it.
@SelaMalka2 жыл бұрын
Brilliant, please make more videos man, you're explaining so well!
@JamesMakesGamesYT2 жыл бұрын
Thanks! Have a few more videos in mind, but they might be a bit delayed
@jeroenvanwees32502 жыл бұрын
This is great! I have used guards clauses before, but not consciously. From now on I will.
@EnricoDias Жыл бұрын
Better yet, use chain of responsability. A list of classes implementing the same interface, each one checking for a specific condition. The method walks the list of classes before performing the action and returns early if any of them fail. That way you just need to add a new entry to the class list when adding a new restriction, leaving the original method untouched.
@pmoneyish686910 ай бұрын
This is interesting. The question I have around this would be how is each condition class getting the data to do the checks?
@LimitedWard2 жыл бұрын
Worth noting this technique applies to all areas of software engineering, not just game dev. I employ this same method all the time in backend web development, and I call it out whenever I see someone doing it wrong in pull requests.
@pourmydrank2 жыл бұрын
Obviously as a programmer you know these things are possible but you rarely ever think of it, good video and thanks for the tip!
@JamesMakesGamesYT2 жыл бұрын
Glad it was helpful!
@pliniomourao2 жыл бұрын
That is true specially when participating in a gamejam or have a deadline... unless this is a habit, you won't remember this good practice.
@ukaszzajac67042 жыл бұрын
ive been doing this subcontiously for a while thinking it is bad practice bcs a lot of callbacks and stuff that make the overall code and executable larger, i was constantly trying to stop but while writing i just did it over and over, its nice to see that ive actually been doing good
@Exilum2 жыл бұрын
It's unlikely I'd use guard clauses for this specific example (at least not in this way), but I do like using it in methods for errors, obvious cases in which you don't need to run what's behind, etc. Makes it more easy to separate things.
@unarei2 жыл бұрын
This seems like a pretty nice use case for them for me - you're attacking only if a set of preconditions are met. I probably wouldn't do it for the mousedown but for all the rest it makes sense
@Exilum2 жыл бұрын
@@unarei If you have separate methods for each input it makes sense. Because you tend to return, it can't work if you have more than one utility per method.
@unarei2 жыл бұрын
@@Exilum Yeah. I guess if you don't want to split it out, you can put it into an if-else chain instead of whatever mess the original code was in this video
@chimz80572 жыл бұрын
Ah, short videos with no time wasted. Subscribing for that simple reason
@DarkryeXII2 жыл бұрын
Been doing it for years, never knew it's an actual thing lol Great video
@lucasfarias11482 жыл бұрын
Simple, clear, straight to the point. I really like it, keep it up!
@XDubio2 жыл бұрын
I have to maintain code with a lot of these nested condition structure. Thanks for making the world a better place!
@wa1gon Жыл бұрын
That is a good start. I would also add that all the if should be extracted to a guard method that returns a tuple (bool isAttackable, string message) = CanAttack(..); Methods must only do one thing. This one is doing two: 1. checking to see if you can attack, then if you can then attack. This makes the code much more testable.
@DanieleNiero2 жыл бұрын
Did people forgot operators such *or,* *and,* etc? They are there so you can avoid these types of if-nesting.
@yidscq79902 жыл бұрын
Your voice is so cool and your content is actually useful.
@CrippleX892 жыл бұрын
In Swift, ‘guard’ is actually a language keyword. It takes a set of conditions and it requires to break out of the block (e.g. return from the method). imho that’s a very nice feature, it makes the core even easier to understand.
@juanpuppinmonteiro2 жыл бұрын
Thank you, it will help me a lot! In a kind of way, it's a very obvious solution, but it's one of those that I've never thought about.
@JamesMakesGamesYT2 жыл бұрын
Glad the video helped!
@SanderDecleer2 жыл бұрын
Code readability is something that separates junior from more experienced coders. This is one tool to make code easier to read and maintain. My only further suggestion in this example would be to group all your guard clauses into a single method. Then the intent of the code would be even clearer: if(!ValidateAttack()) return; Attack(); If I'm glancing at your code I'm not concerned with why the attack should not be valid, only with that it could be invalid. Great tutorial!
@JamesMakesGamesYT2 жыл бұрын
That's a great idea for further refactoring of the code! I like how even something as simple as guard clauses can open your eyes to further improvements that you wouldn't have spotted before
@SanderDecleer2 жыл бұрын
@@JamesMakesGamesYT Iterative refactoring is a gift that keeps on giving
@a-minus-b-equals-a2 жыл бұрын
@@SanderDecleer Given that we're in the context of Update(), I'd argue that 'if(ValidateAttack()) { Attack(); }' would allow better extensibility. Said that, I'd probably extract it to its own AttackIfValid() method, where using ValidateAttack() as guard clause makes more sense.
@SanderDecleer2 жыл бұрын
@@a-minus-b-equals-a once more than just attacking is used in the update I fully agree with you. I personally would make a method like HandleAttack() or something, this could be placed in the update together with HandleMovement, HandleInteraction... I guess this comes down to preference and convention within your team, the main goal of having more readable code has been achieved. Refactoring between my preference, yours, or most sane others would be trivial.
@vietanhnguyen14152 жыл бұрын
Short Video but make a huge impact on my knowledge. Sir, you are a lifesaver!!!
@CubesUnpacking2 жыл бұрын
I'm trying to develop a game, making it first time, so your advices very useful, thank you!
@pliniomourao2 жыл бұрын
It is always good to have a reminder of good practices and patterns. thank you for sharing!
@GUMMY_MKII2 жыл бұрын
// Really useful, clean and optimized! // I love short tutorials like this!
@trashcaster2 жыл бұрын
A commented comment? Clever
@zendakk2 жыл бұрын
-- Agreed, also applicable to e.g. Lua { and even good ol' Pascal, } # anywhere, really.
@Dreadnaut25602 жыл бұрын
@@zendakk
@therickestrick3832 жыл бұрын
I was stunned for a moment, why didn't I think of that.. my codes were spaghetti.. And thanks for making it quick!
@JayadevHaddadi2 жыл бұрын
I have been using this for ages and I love it. It is the first time i know what it is called!! Guard clause !!!:))) 👍😊❤️
@PvPNetwork2 жыл бұрын
I remember going from always doing your first example, to learning about the second. I always love these moments
@aprimic2 жыл бұрын
I've used them but without knowing how effective they can be and your video shows it! I'll use them more!
@tyt-no-udee-nick2 жыл бұрын
This approach works perfectly in almost any language and technology. I'm used to be a React-developer and my code became much clearly when I started to use guad clauses
@vinodakula38242 жыл бұрын
Awesome video. So informative about writing beautiful and maintainable code. Thanks. Please keep these coming.
@TMPfernando2 жыл бұрын
I never thought about using return this way... nice trick.
@mehmetb84702 жыл бұрын
Thanks from Turkey. I subscribed. I will look forward to see more of this kind of content.
@jackdog062 жыл бұрын
oh wow, hadn't even considered that before. Looks so much nicer. genuinely a life saver.
@FabiulousGames2 жыл бұрын
Great vid, I recently started using Guard Clauses and I can confirm that it has improved my workflow a ton
@gordonzar9922 жыл бұрын
How long have you been developing games again?
@flootypie Жыл бұрын
It's interesting how things change. When I went through Uni (many many years ago) we were taught that a method should only ever have one exit point, and doing otherwise was absolutely forbidden. Glad to see more flexibility in use these days, although I can see how having multiple exit points could also cause problems...but I agree it's an improvement.
@JamesMakesGamesYT Жыл бұрын
That’s a good point, there’s a lot of changes as new technologies and methodologies emerge. My understanding of the “only one exit point” rule is that if you have a big method it can be confusing if you’re returning “7” on the first line and “13” on the 30th line. If you try to keep your methods small then the guard clauses can really make your code a lot tidier.
@flootypie Жыл бұрын
@@JamesMakesGamesYT Yes, I've certainly come to agree. My favourite "new discovery" is writing self-evident code with as few comments as possible. The reduction of the old pressures of size and efficiency over everything else allow many convenient freedoms. Rediscovering coding after a 30 year break is very interesting.
@rohanphaff26402 жыл бұрын
Much love!!! I really needed this one to clean my code up :D
@sundarakrishnann82422 жыл бұрын
a very nice, short and informative video! You explained so well in such a small amount of time! Thanks
@ProjectPhysX2 жыл бұрын
I use these all the time in OpenCL. Didn't know they are called guard clause though. Good to know!
@danser_theplayer01 Жыл бұрын
I do this a lot with a few simple guards like if ANY of these trigger then exit the function instead of doing what you want. But I don't know how you can use them with finer detail instead of basically making a giant OR guard.
@Vaaaaadim2 жыл бұрын
I am not a game programmer, but I've certainly used this pattern before, didn't know they were called guard clauses. The main places I've used it is in loops in combination with the "continue" statement.
@Povilaz2 жыл бұрын
When I began programing _this_ is how I used to write my code, but over the years I slowly changed into doing the layered method. Idk why that's interesting.
@torikenyon Жыл бұрын
Remember to EQ your voice! I was watching this on my TV and it triggered the subwoofers to shake the floor due to unneeded sub-bass frequency information that’s not actually part of the sound of your voice. A high pass filter around 100 Hz should do the trick
@JamesMakesGamesYT Жыл бұрын
Thanks for the tip! Audio is something I've tried to get better at with each video
@marcelocosta96202 жыл бұрын
Wow! This opened my mind now! Thanks for the tip.
@mattsponholz83502 жыл бұрын
Early going I used to cringe at this technique but it's honestly a life saver; especially, if you bring someone else on the project.
@Kitsomo2 жыл бұрын
I strongly believe you have the best tutorials i ve seen so far. This is a pattern people should use more in their codes . Cannot count the times i ve opened my old game jams and seen 10 if statements in a row.
@JamesMakesGamesYT2 жыл бұрын
Thanks for the kind words! Trying to create more of these types of videos in the future
@jabvzla2 жыл бұрын
It is possible to add one more step, it adds all the conditions in an array and applies the "All" (or "every" in javascript) method. This even giving you the possibility to add conditions from other places.
@nickygdev2 жыл бұрын
Love guard clauses. One of Riders best features is pointing them out
@netrogamedev32572 жыл бұрын
thanks james! this is gold for me as a self taught programmer!
@megascan2 жыл бұрын
when you unintentionally already operate like this since you found it neat
@심심이172772 жыл бұрын
Unity 관련 영상이지만 엄청 유용하게 활용할 수 있겠네요. 감사합니다!
@ethanwobser87762 жыл бұрын
I have heard of something like a clause that can clean up code I didn't know exactly what they were talking about back in the day but now I just started to learn Unity & C++ I kinda understand what is happening
@Konitama2 жыл бұрын
Feel like this will only work if the method doesn't have other stuff going on in it as well... Otherwise all these returns are going to cause a lot more confusion when you're trying to do something else but it never executes the code because some other thing way up the list is causing the whole method to end prematurely.
@Schnorzel13372 жыл бұрын
Well if one function does more than one thing, you should replace it my multiple functions anyway.
@Frank_G_Finster2 жыл бұрын
Thank you for the tip! It really makes life easier as a newbie coder.
@tjdewolff5104 Жыл бұрын
For the very same reasons you mention, like "readability" and " maintainability", I convert these multiple "return" functions into (apply drumroll here...) yes, NESTED(!) code! For some 4 decades now. In the process of conversion I discovered many an error like memory leaks. Applying multiple return-clauses in a function tend to obscure these clauses more often then not, eliminating readability. A return-clause should only be applied as the final clause in a function and the only when a value is to be returned. That value, by the way I explicitly demand to be contained in a variable, which is declared in the very first line of the function and is set to a recognised error value. This line is to be followed with a blank line and that sets the returnvariable apart. Literaly. What's more, nesting code brings you the benefitsof "just in time" declaration of variables. Think in terms of congruency of lifetime and scope. This you will NEVER fully achieve in this video. My 2 cents. Tjitte I work in 'C' only.
@dhrubasaha082 жыл бұрын
Hey, I'm newbie at this...but I have a question why do you use only if instead of else if and else after 1st if ?
@JamesMakesGamesYT2 жыл бұрын
Hey, the reason we only use an if instead of else if is because of the "return;" within each if statement. If the condition is true, we return from the statement so no further code is executed. Hope this cleared things up!
@dhrubasaha082 жыл бұрын
@@JamesMakesGamesYT thank you so much 💖
@JustinBieshaar2 жыл бұрын
Great video! We use the exact same method in games company I work for. We are actively reviewing on clean code approaches like this. Good you point this out! 👍
@Stratelier2 жыл бұрын
Talk about a helpful tip for programming in general! I remember some old projects in Visual Basic where I often needed to populate elements on a form with values pulled from an array, but doing so (necessarily) triggers the elements' defined "changed" event (which in this case updates said array with those values). As the versions of that language (VB2, 4, and 6) did not support programmatically adding/removing event handlers, my hack was: prior to populating the form elements, I set a global form variable (I called it "SkipEvents") to indicate there is an automated process running, and each "change" event routine likely to be triggered during that process would immediately check this variable first and if set, it would do nothing but return. (Not too different from using a *try...catch* block when you're running a routine that could reasonably experience errors.)
@Ryöken175 ай бұрын
It's cool in a way, but there is a priority, can't you have an if and a print depending on wich one triggers ?
@sebimed59172 жыл бұрын
Okay, but what if my update method needs to check more than just the attack action, like jumping, rolling, etc. It can't just return if one of the 10 possible buttons isn't pressed so how would you handle that?
@JamesMakesGamesYT2 жыл бұрын
You could extract the guard clauses out to a method that returns a bool called "CanJump", "CanRoll" etc. Instead of a return in the guard clauses you would have a return false and then a return true at the bottom of the "CanJump" method like this: void Update() { if (IsJumpButtonPressed && CanJump()) { Jump(); } } private bool CanJump() { if (isJumping) { hintTextUi.SetText("You are already jumping"); return false; } if (!HasStamina()) { hintTextUi.SetText("You have no stamina"); return false; } return true; } Hope this cleared it up
@sebimed59172 жыл бұрын
@@JamesMakesGamesYT I see, that would actually be a good way to make my player controller script more readable. Thanks for the answer, much appreciated 👍
@jackoberto012 жыл бұрын
@@JamesMakesGamesYT Alternatively you could extract a method like void AttackLogic(), void JumpLogic(), etc with all the input actions and in there add the guard clauses I try to almost never put conditions in Unity Event functions like Start and Update because you know you might need to change them later
@tycho252 жыл бұрын
I was just wondering about this. Nice to know.
@atajuan2 жыл бұрын
I love these kind of stuff. Thanks for sharing.
@MohiDev2 жыл бұрын
Wow! In 2 mins I learned how to use if statements correct (Thats good that i don't have situations like that).
@SHOOTINGDNA2 жыл бұрын
Do you know if you use rider ide it suggest such good practices. By just two key press you can convert if conditions to guard clauses.
@Furki4_42 жыл бұрын
I'm just a beginner at coding and suffering from if-else statement's jumble. I'll try it and hope that it'll help me.
@Known_as_The_Ghost2 жыл бұрын
I want to learn Unity. Whenever I decide to do this, this will help me quite a bit. :)
@JamesMakesGamesYT2 жыл бұрын
Thanks, I'm glad the video helped! Now is a really good time to learn Unity, there's a lot of great resources online to learn for free. Unity have example games that you can download and add your own mechanics to, like a Mario kart clone and a FPS
in addition i like: write return statements on same line as clause without brackets, use throw in the same fashion
@gabrielaugusto10392 жыл бұрын
Guard clauses are really helpful, a thing that all programmers should know, and it was well explained, very good
@LeonardoHernandezpages2 жыл бұрын
What about workflow, when you need condition A absolutly to happen in order to execute condition B. And so on so forth
@ThatGuyNamedBender2 жыл бұрын
Although I've never knew what it was called I have been using guard clauses. It made logical sense, in order to speed up execution (especially on an update/tick method) you want to return as soon as possible. I understand what you were trying to teach in this video (and I'm sure it's not the point but just something I noticed) you only only have it check for one button which makes sense for the purpose of this video but in the case of checking for multiple controls, a switch statement would be better and then set the default condition of the switch statement have the return as you don't want more if statements in your code as if statements are slower to run(especially if you are checking for control inputs) for every key when you can have a switch statement to handle all input. Maybe even a general boolean for if a key has been pressed then just return if that bool is false. Like I said, I know that's not the point of this video but just thought I'd share an example for handling controls. Cheers!