Copyright (c) 2020 Me First LLC
Unity is extremely flexible and things can be accomplished in multiple ways. One downside is that your inspector can become very messy if your prefabs and scripts don't adhere to a standard.
Here are some tips:
🚀 Always place your script at the top of the inspector and on the root of your Prefab. Digging through game objects and discovering multiple scripts controlling a single prefab is not fun. It's also fun scrolling down the inspector looking for something important.
🚀 Use the attribute Header to mark the beginning of a section. I don't recommend grouping your variables into a class or struct unless your code architecture demands it. Header does not require any extra heap allocations and allows quick moving of variables. Do not create data structures just for editor appearance.
🚀 Clearly define what serialized variables should be touched by designers vs developers. If you have non-programmers on your team that will tweak prefabs, come up with a clear naming standard so they know they can tweak the settings without breaking the prefab. e.g. Anything with the name "Settings" can be touched by designers.
🚀 Use attribute Tooltip on all variables that will be touched by designers. Comments in code will be hidden from designers and placing a Header on each variable will eat up much space in the small Inspector window. In the perfect scenario, a designer knows that with any setting they can tweak, they can also hover the mouse to learn more details.
🚀 Use OnValidate to sanitize values and verify your serialized variables are correct. It's much better to get logged errors before runtime, and this will help prevent wasted time and confusion.
➡️ Follow @mefirstgames
#gamedev #indiegamedev #indiegame #games #gamer #coder #coding #programmerlife #unity3d #webdev #codinglife #programmer #coding #fun #softwareengineer #software #coder #programmer #unity #indiegamedev #webdev #gamer #stem #learn #learn2code
Unity LTS (Long Term Support) does not always have the latest and greatest features, but all Unity developers should seriously consider using LTS over the latest release.
I've talked about what LTS is in a prior post, but now I want to list the reasons why I'm personally sticking with 2019 LTS and won't upgrade until 2020 LTS is released.
📌 I early adopted 2019 in multiple projects, and it resulted in more headaches than good.
📌 It is common for bugs to arise in versions prior to LTS, e.g. 2019.[1-3].x
📌 New editor bugs can slow your development and unexpectedly break features.
📌 I found myself upgrading Unity often to get the latest bug fixes, but sometimes a new version would introduce another bug.
📌 In retrospect, the frequent upgrades were a huge waste of time. A smarter strategy is to simply wait and upgrade between proven stable versions.
📌 Packages also had to be constantly upgraded, and this led to even more unknowns.
📌 I used the SRP package in a VR project, and it had many runtime bugs. This specific package had so many issues and changed so much that Unity eventually rebranded it to URP.
📌 Features in the latest Unity, like 2020 make it very tempting to upgrade. However, make no mistake, these features will likely not be stable until late 2020.3.10+ or 2020.4.x LTS versions.
📌 Before you write off 2019 as a special case, many devs are having similar issues with 2020.
📌 Even Unity themselves, recommends releasing games on LTS.
⭐️ As a game developer, it's without a doubt that time is your most valuable asset. Early adopters will lose much time dealing with upgrade issues and bugs.
⭐️ For games released with a decent player base, I highly recommend sticking to Unity LTS unless you absolutely need to upgrade for specific features.
⭐️ For early adopters, plan and schedule accordingly to account for extra upgrade time. Also, bring a machete because you're blazing a trail.
🚀 Zenject, now known as Extenject is a dependency injection framework built specifically for Unity. Check out my previous post on dependency injection if you don't what know it is.
🧠 Completely free under the MIT license, Zenject allows you to loosely couple code and increase the flexibility of your code.
📌 Inject variables directly into MonoBehaviors and C# classes.
📌 Conditionally bind variables by type, name, parent, and more.
📌 Dynamically create objects via factories.
📌 Setup memory pools for object pooling.
📌 Unit test support and framework for easily testing your scenes and prefabs.
😃 My Experience
📌 Zenject makes it easy to swap out dependencies for different instances, making it easier to change feature requirements on the fly.
📌 It can be a pain integrating external assets and hooking them up to the dependency tree.
📌 There have been some strange show-stopping bugs, but the framework has greatly improved stability.
📌 Performance overhead exists, and diving into the Zenject source code will cause headaches.
📌 Onboarding a new developer takes longer, especially if they have no experience with Zenject.
📌 Once you get rolling with Zenject, it becomes extremely powerful, flexible, and can definitely help game developers in rapid agile development.
🤞 Features I want
📌 The ability to visualize the dependency graph anywhere and anytime.
📌 More internal optimizations: bye-bye FindObjectsOfType for ZenjectComponent.
✅ Conclusion If you're doing a lot of OOP, then dependency injection is awesome. It does take time to wrap your head around Zenject and how a certain project is using it. I think it's a good option, but an option I'm not going to use in my current solo games. In a project with loose ever-changing requirements, using Zenject will definitely pay off. Just know that it's not yet widely adopted, and the average Unity Developer will need extra time to learn.
⭐️ Follow https://twitter.com/mefirstgames
Unity is a great game engine, but it's not perfect.
📌 Unity is limited to C#, thus it's harder to optimize code and memory allocations.
📌 It's not suited for a large open world, AAA games.
📌 Unity is a CPU hog on mobile devices, thus drains the battery quickly.
📌 The code is not open source and you can't make custom engine modifications.
📌 Garbage collection can slow down your game and many engine methods allocate on the heap.
📌 Asset Store is saturated with poorly designed assets.
📌 It still has many performance "gotchas."
📌 Terrain editor and other tools aren't as powerful as competitors, e.g. Unreal engine.
📌 Asset import and reimport times are long (this is a tad better now with asset database v2).
📌 Large projects are slow to open, modify, and compile.
📌 It can be expensive compared to some of the competitors, Unreal and Godot.
⚰️ Prefab conflicts will destroy your soul.
🚀 After many years of professional development with Unity, it is still my preferred engine for most mobile and indie games. I long for more optimization control in code, ❤️ C++, but the toolset for Unity is perfect for rapidly building my mobile and indie games.
🔥 Unity is not perfect, but has improved greatly and will continue to improve in the future.
YOU must decide how to architect levels when you're developing your game.
Whether it's using a scene, prefab, or implementing a custom format for each level, it is not always clear what is the best approach.
📌 Before we begin, let's clarify that there is never a one fits all rule. As an effective game developer, you must look at your circumstances and make your own design decisions.
🚀 Scenes Using a different scene for each level is a classic solution. Before nested prefabs were a thing, a scene could be additively loaded and contain only game objects for the specific level. Unity allows for asynchronously (kind-of) scene loading. However, there is extra overhead that is included in scenes that is not necessary if you're additive loading, e.g. lighting data. Games that are not pushing the performance limit can still use this technique and never have issues.
🧠 Prefabs Using prefabs for levels is now extremely easy and straight forward. A level prefab can nest other prefabs inside of it, e.g. You can place your SlimyBadGuy prefab inside your level. Although the prefab editor is powerful, sometimes it can be flakey or confusing on what values are overridden or applied. Pro tip: set up a scene as your prefab editor environment so your level will appear as it would in-game. With prefabs, you also don't need to worry about referencing objects across scenes. Beware referencing all prefabs from your main scene and having all prefabs and dependent resources loaded into memory.
🚀 Custom Format This should not be your default solution, however, it's great if you are randomly generating the level data or allowing your players to edit or build their own levels. It may also be required depending on your performance requirements; with a custom solution, you can implement true asynchronous level loading where each object in your level is instantiated in different frames.
⭐️ Whatever you decide make sure it works for you and your skill set, performance, and scheduling requirements.
⭐️ Follow https://www.instagram.com/mefirstgames/
📌 You can hit the ground running and quickly prototype or build small projects.
📌 Excellent cross-development support. Constantly updating build pipelines is a thing of the past.
📌 It has 2D and 3D support for graphics, lighting, and physics.
📌 Unity uses C#, a programming language with fairly high-level concepts, making it easier on noobs.
📌 The Asset Store is full of tools that you can use or at least use as a baseline.
📌 The online community is active and it's common to find answers to questions online.
📌 Unity has long term support, constantly fixes issues, and are planning major new features.
📌 Mobile friendly: the much-improved engine now runs fairly well on mobile devices.
📌 You can get it FREE if you're a student or looking to learn game development.
📌 Animations, particles, physics, and common game systems are built directly into the engine.
📌 Straight forward Editor UI and multiple IDE support.
⭐️ Unity is a great engine for indie and small games. If interested, it's worth a try.
💬 Leave a comment below: What do you like about Unity?
🚀 Like and repost for a friend for part 2:
😂 Every coder has been confronted by someone with a "life-changing" app idea. "Build this for me," they say. Although it can be annoying, you must understand that these people are cursed. They lack the ability, skill, and will to build or even spearhead the development of their own ideas. As a coder, you are at the forefront of turning ideas into reality.
🧠 You get to practice problem-solving. The sad truth is that the majority of people who go through school never learn the skill of problem-solving. Instead, they memorize facts, dates, and blindly accept the opinions of other people and take them on as their own. Problem-solving is a special thing, it gives you the ability to build and make a change, whether it's in software or the real world.
🤑 You have power in the market. In an ever-advancing world, a good coder is hard to come by. You'll have the power to say no to a job, acquire work in almost any city, and often have the ability to negotiate relocation packages. Just make sure you continually hone your skills as you fend off the frenzy of recruiters.
🚀 There are many more reasons to become a coder and we'll explore those in the future. If you want to learn or master coding, then you'll require practice. The sheer amount of hours you must put in to learn the concepts depends on your circumstance. In the world of Software Development, there are no excuses. It either works or it does not.
🔥 I'm Miller from @mefirstgames and we make games for me and you.
Dependency Injection (DI) is a design pattern in which an object receives other objects that it depends on.
A class doesn't know where it's dependencies came from and doesn't even need to pass dependencies to any child objects it creates.
⭐️ There are four roles an object may play in Dependency Injection.
📌 Service - The dependency or object to be used.
📌 Client - The object that is using and depending on the service.
📌 Interface - Defines how the client can use the service.
📌 Injector - The object responsible for constructing the services and injecting them into the client.
⭐️ If you're confused, no worries, here are examples of all the roles
📌 Service - Class Retriever, implements the IDog interface.
📌 Client - Class Walk, requires an IDog object.
📌 Interface - IDog, defines the methods for all Dogs.
📌 Injector - MyInjector, creates the correct type of dog and injects it.
⭐️ The power behind this design pattern is the loose coupling architecture.
💻 We could easily create a new type of dog, Pug, inject it, and the Walk class will work fine.
💻 Passing dependencies as arguments are no longer required.
💻 All dependency logic is offloaded into Injectors, allowing Dog to focus on being a dog.
💻 DI allows for factories to be injected also.
➡️ There is sometimes a performance cost depending on the implementation.
➡️ DI assets exist for Unity, we'll be covering this soon.
In C#, everything is associated with classes and objects. A class is simply a "blueprint" for objects, defining their values and behaviors.
🚗 We define a class Car. It has a value for gas and the ability to move.
🚙 We can instantiate many Cars. Each car is an object with the type of class Car.
✅ Thus, any changes we make in the class Car will be reflected in all the car objects we create.
⭐️ Variables, properties, and methods comprise a class.
📌 Variables hold the state (values) for the class.
📌 Properties usually are just wrappers for variables, preventing us from setting them to an invalid state.
📌 Methods implement behaviors. Your class may have methods to Move, Honk, Stop, Turn, etc.
⭐️ Private vs Public
📌 These special keywords change the access level to certain variables, properties, and methods.
🕵️♀️ Private - The type or member can only be accessed by code in the same class (or struct).
💁♀️ Public - The type or member can be accessed by any other code.
✅ Use these keywords to create an interface for your Class. So the inner details are all handled inside and external code won't change variables or call methods that put your class into an invalid state.
⭐️ Here are some interesting features we'll look up in the future. I suggest your research them beforehand.
📌 Classes may inherit behavior and values from another class. e.g. Horse class inherits from Animal class.
📌 Classes can be defined as static. Meaning, the class is the one-and-only one instance of itself.
📌 Classes have more access levels: Protected, Internal, and Protected Internal.
📌 Classes are always allocated on the Heap.
A loop statement allows YOU to execute a group of statements multiple times.
💪They are very powerful, especially if you need to execute a task N times or iterate over many objects.
⭐️ foreach loop
📌 Executes a block of statements for each instance in an array, list, or any IEnumerable.
👍 You'll see this loop often, using it to perform the same task for multiple objects.
⭐️ for loop
📌 This loop allows you to initialize variables and change them after each iteration until a condition is false.
👍 Use this if you need to keep track of the current index in an array.
👍 Good if you just need to iterate over any numbers.
⭐️ while loop
📌 Simply executes a block of statements until a condition is false. The condition is checked before the first iteration.
👍 Good for running tasks until some state has changed.
👍 e.g. Move player until they are dead. Eat food until full.
⭐️ do while
📌 Similar to the while loop, however, the condition is checked after the first iteration.
👍 Use this when you have a task you always want to run before the loop condition.
👍 e.g. Player enters input, if the input is not valid then try again, else exit the loop.
⭐️ Loops are both fun and powerful tools at your disposal.
⭐️ You may struggle with learning loops, that's ok. Things will click after hours of practice.
⭐️ If you find yourself repeating the writing them the same code over and over, consider a loop.
➡️ Follow @mefirstgames for more game dev tips.⠀
➡️ Free Unity Tools: https://www.mefirstgames.com/hierarchy-comments.html⠀
Me First Games is an independent game studio dedicated to creating unique and bizarre video games.
Star Impact is an upcoming adventure platformer coming to PC, Mac, and Linux.
Copyright (c) 2020 Me First LLC