Breaking up Code in Unity (Important game dev tips for beginners)

122,212
0
Published 2020-02-15
► Easily Make Platfomers in Unity - u3d.as/2eYe​
​​► Easily Make Car Games in Unity - u3d.as/1HFX
► Wishlist my game - store.steampowered.com/app/1081830/Blood_And_Mead/
►Join the discord community - discord.gg/yeTuU53

► Subscribe here for more valuale tutorials
bit.ly/2MpZ1ao

► Support me on Patreon:
www.patreon.com/lostrelicgames

► Project Files from this video:
drive.google.com/open?id=1qMCRIE6lu3G__ywQ6mpFesLK…

desc:
In this game dev tutorial I show how to break code up in unity, separating scripts into different logic groups and adding them to a player controller as different components.

#gamedev #unity3d #programming

All Comments (21)
  • @pt8306
    While your approach is certainly better than doing it all in one file, it still has a lot of dependencies. That is, the movement script still needs to know about the player script AND the input script in order to move. In some ways, you have actually made the dependencies worse, as everything now relies on the player script as well as any script that they would have relied on had you just referenced them directly. The only difference is they are getting it through the player script rather than accessing it directly. While this does have some positive implications for inheritence, as you can now specify subclasses in the player script and have your other script use those subclasses instead, there are still (in my opinion at least) better ways to do this. I would recommend making your scripts standard C# classes, rather than monobehaviours. This will lose your ability to drag and drop, but the benefits of having access to the constructor are worth it. Then, I would recommend passing in any needed dependencies through said constructors, creating (and passing) whatever is needed in the PlayerScript's Awake() function. For example, if the movementScript needs a character controller to move, it would be passed in as a constructor argument and assigned to a private variable within that class. By using this method, you can have your movement functions completely independent from input (and other scripts) entirely. This is good for things like code re-use, as your movement controller can now be used completely independently of your input source. The player script would be responsible for telling the objects how to move (by calling relevant functions in the movement controller) based on some events from the input controller. This way input can simply send events, no questions asked, the player can catch those events, and trigger movements based on them. Your input system can then be reused by any other monobehaviour that needs to capture input events, and your movement system can be reused for any charactercontroller independently of input (such as moving characters as part of a cutscene). You can even use interfaces or abstract classes here to completely overhaul functionality, something you can't do using monohebaviours since the unity inspector doesn't support interfaces at all. The only drawback is you lose drag and drop and instead have to create the other classes manually as part of your player script, but I feel the benefits are absolutely worth it, especially since you never have to worry about script execution order or any other unity shenanigans, and your object component heirarchy doesn't get bogged down with monobehaviours which really only exist to implement functionality and don't have/need options (they could all be set on the player component instead and passed to systems as needed instead).
  • @devyoung4049
    I attempted to break up my code following your video and failed the first time, 2 hours of work and I almost gave up.... But I kept trying and actually did it, I have clean code!!! I learned a lot and I'm inspired learn and code more. Thank you :)
  • @jampotjuh2465
    I'm glad I found out about this before getting too far into my project
  • @jeangodecoster
    For the record, whilst messing with script execution order IS a solution, it's a terrible solution. Mostly because it's something you don't see in the code, so problems linked to execution order are horrible to debug. And if someone else goes and mess with execution order (granted, that kind of problem doesn't happen in a solo project) you're up for a headache. GetComponent references should always be done in Awake, and pretty much any other case where you'd want to control the order in which some things happen can be dealt with in code with an Observer pattern.
  • @coobbyo
    I just discovered your videos and like most people here I'm so grateful you put so much emphasis on quality. While there are channels out there that use concepts of quality code, very few teach them. Thank you so much. I can't wait to learn more!
  • Your videos are so helpful my dude! moving from a web developer into game development it drives me mad how little information there is on good structure and best practices thanks again! :D
  • @Jazuhero
    Good job highlighting an important topic for making your Unity code more manageable! There's also a third method, which I prefer, of controlling the execution order of Start() functions of parent-child scripts such as those shown in this video. In this method you leave the parent script's start code in the Start() function, but rename the child scripts' private Start() functions as something else, such as public CustomStart() so that Unity will no longer call them automatically. Just remember to make the custom start functions public so you can call it from another script. Then, you can call the CustomStart() functions manually in your parent script's default Start() function. This way you have total control over the script execution order, and can even have the custom start functions called in the middle of the parent Start() function, exactly as you deem necessary.
  • @diliupg
    Excellent tutorial. Never knew we could set the execution order in the editor like that. Thanks a mil!
  • @marcossuel914
    i've been looking for this for so long, thank youuu :)
  • Very interesting video, but I think you are making a circular reference. I suggest for decoupled and performant code: 1. Store your input data on a scriptable object, and then reference only that scriptable object in your movement script. This way your InputClass writes data to the scriptable object and your MovementClass reads the data inside your scriptable object. 2. Try to not use an update() on each of your scripts, instead, call your function OnUpdate() and create another script (UpdateManager) that handles all of your scripts that need to run on Update(). For Unity it's better to handle one Update() that do a thousand of things that a thousand Updates() that do one thing.
  • @LostRelicGames
    I Hope you enjoy this! I truly appreciate each like and comment, they really help get this educational material in front of more people. <3 Have a great weekend guys, if you want to chat, you are very welcome at the discord! discord.gg/yeTuU53
  • @_ZEG
    Thanks a lot man! I am a programming noob myself and often run into problems because I don't exactly understand yet how I'm supposed to structure my code. Your video made that much more clear!
  • @dontownsend7748
    Very cool, didn't really understand the internal access modifier before this. Well-explained!
  • @Lucas-hh4oh
    Clean code is actually undervalued in indie game dev. Having object-oriented analysis and design skills really helps you to build the game and it will save you from hours of work.
  • Thank you. I learned to program not too long and the term of pumping everything into a single class was deemed as the creation of the blob God. Now knowing how to separate the player controller, I will try and write better code.
  • @smashies118
    How did you directly answer my question about script structure the day I thought to ask it? Awesome! You confirmed my thought process isn't crazy and stupid.
  • @quantumdev6577
    Awesome topic! Thank you for explaing all of this very well. I really appreciate that.
  • @saultoons
    Great tip! I've started my own game recently and have heard a lot about splitting code up into different classes like this but wasn't sure how it would be done. This video helped a lot! More like this please, and post on reddit - gamedev or unity or whatever I'm sure others would find this useful :)
  • @sanchez00253
    really interesting. thanks for sharing. even if i'm absolutely new in this wonderful world, i found this tutorials really intelligent and logic. this HELP a lot for who want( like me) understand and study. thanks.