Learn from my mistakes in this post mortem of my first Unity game, Perfection, and learn tips to improve your own games performance! Check out the free horror indie game Perfection: yagmanx.itch.io/perfection Apologies that some of the examples are low quality, I also wrote this post mortem in a written blog with higher quality images as references to all of the points made: medium.com/@yagmanx/10-tips-how-to-improve-a-unity-games-performance-to-perfection-noob-friendly-9b906082bf82
If you want your GameObjects to be visible without being public, you can put [SerializeField] before. It will be visible in the inspector but still private.
It's not performance related, but using public is bad practice in 90% of cases. Using serializedField + Setters and Getters is a much better approach for clean code and decoupling
I had no idea I was using dependency injection until you mentioned this and it triggered my curiosity, so I googled it to see what it was. I am someone who tries to think before coding to see if there is any other way I could do something to minimize code and improve readability. Crazy how the mind comes from alone to these solutions and you don't even know there is always an existing term for that.
@@chrono9503 because it's not the right encapsulation most of the time. Public means the property is exposed to reading and writing by a foreign class, which you don't want most of the time
I'm maybe a bit late on this video but one thing that helped me a lot when i started, was learning about Object Pooling. Basically if you have certain objects that have to appear and then disappear frequently (like enemies for example that appear when spawning and disappear when dying), instead creating and destroying the object simply activate it and deactivate it. Usually i have a script that manages a certain amount of objects that are deactivated on the start of the game and when i need one or multiples of it, I ask the ObjectPoolManager for those objects, set them active, set up any components they might need, initialize their starting parameters and send them on their way. And if they have to disappear, just deactivate them because the ObjectPoolManager has a reference to them and can easily find them for future activation.
This is so extremely helpful! When I'm watching other devlogs they always get to a point where they simply "optimize", but they never explain what there doing! This is an extremely useful checklist to go through for all your games and I definitely plan to integrate this into my workflow! Thanks again for the great video!
if you write a bit of code you can actually add sorting orders to 3d meshes as well which is incredibly useful and I never understood why it wasn't buitlin.
Hey there, just an extra tip. I see a lot of professional games using different meshes for an object visual aspect and its collisions. Making a simpler more lightweight mesh for an object's collisions could help you optimize the game a bit while keeping mesh colliders.
would still be more performant to just use a box collider or set of box colliders, the code that has to run for mesh collision is just more advanced than checking if a point is within the bounds of a cube.
@@bradjones7491 Any documentation on the algos used for that calculation? I'm certainly curious what the Big-O is (you are certainly right, Im just curious to what extent the difference in performance is)
@@0xlapras646 I mean you would just have to look up how to do it from scratch, but checking boundaries of a cube is mathematically significantly simpler than check the bounds of a complex mesh. for example you could easily determine if a point falls within a volume of 1, but a mesh collider has a non standard volume so you would first have to determine the volume before checking the bounds. Mesh colliders are used extremely sparingly in general, and mostly just for simple shapes like ramps and sometimes terrain. As for the extent of the difference I couldn't say for sure but I'd assume it would be fairly significant since almost every AAA game in existence utilizes the multiple simple colliders method. Mesh colliders should only really be used when the alternative is prohibitive, such as with a massive object like a terrain, where aligning individual colliders would take thousands of hours. Basically mesh colliders are time savers, but are overutilized by people who get lazy, and by doing just a bit more manual setup you can often avoid the additional overhead. Another thing to consider is that often times mesh colliders fail at detections where a box collider would not. While it's pretty unordinary and example of this can be achieved by moving an object at incredible speeds, if the wall is a mesh collider it has a significantly higher rate to allow the object to pass through than a cube. and This is because mesh colliders don't really have thickness so if the physics calculation somehow places that object on the other side then the collision will not be detected, whereas with a cube the object would need to reach significantly higher speeds to breach it's entire bounds, and you could make a wall have theoretically infinite thickness to make it basically impossible to clip into. As a side note about the fail rate of physic detection this mostly occurs because physics calculations are done on an independent update loop that has it's own time scale so a significantly large movement in a single update of that tick function could offset the object further than the collision is detecting thereby avoiding the collision detection entirely. This is because most physics systems don't calculate along the traveled vector when determining collision, rather they only check for the position at that frame of the tick update. That is to say, that if an object moves farther than the entire collision's size in less than 1 physics update tick, then that collision will not be detected. That also leads into another slight tangent about unity in particular, where people think that unity's physics engine is very inaccurate, but this is actually mostly caused by people never changing their physic's tick rate under the time settings in unity. By default I believe it is set to a tick rate of 0.10 which is 10 frames per second and is pretty inaccurate, allowing for most "fast" speeds to easily clip through collisions.
I don't know what I'm doing when it comes to programming(and anything else) but this video was sooo good. You've structured and inform everything in a super easy a digest way. You go sister!
Very informative! With a background in 3D I was shocked at the number of polys on the plant. But if you don’t have a background in 3D it’s not very shocking I guess. Glad to see the improvements worked!
When you see the kind of optimizations and efficient modelling methods used in AAA games, you realize how much devs strive to minimizes polys and stuff. I've seen wireframe models of things that shocked me, because it did NOT look like it was that low poly in-game!
@@yagmanx I know I'm super late here but on the subject of that plant (and other models with similar poly count issues): On your decimate modifier at 7:19 you could select the "Planar" option and set its Delimit mode to "UV". This would decimate the model whilst performing calculations favoring the original UV layout more than other options would. Obviously not as good as making a low-poly version yourself, but it's a closer result that can work just fine with many basic props.
i followed you back when i was into programming and trying to make games. i switched back to what i have been doing for almost 2 decades which is art and making art, possibly for games. but i am alot happier. there are people who should create the code and there are people who like concepts only and not the technical and admirably complicated part of the game making process. seeing this makes it look even more layered than i had remembered. still love games though and happy to see what you are working on. my life was so much worse when i first started watching your videos. its gotten better but i am a ways off from my artistic goals. keep uploading videos especially upcoming projects related, its always cool to see.
This is really interesting to know. I'm so glad you're in a better place now, it can take a long time to know what really makes us happy. Best of luck for your future :)
19:36 i know its a bit late to respond but in case someone need it: the use of "find" in the "awake" will not necessarily degrade the performance of your game. it depends on what script using it. if you use "find" in a singleton, it will be fine. just don't use "find" in a script attached to dynamic game object. another thing, if possible, try to use "FindObjectOfType" instead of "Find". i use "find" in the awake method of my level scene. although its not a singleton, but i consider it safe to put it there. no one will notice additional 0.5 sec delay during the scene loading :D
As for LOD'ing, I find it better to have the high quality / mid quality / absolute low quality. Mid quality should be the default, high should only be shown in either cutscenes or when very close to the model, so make sure your decimated models are in the 'mid' quality to make it the default. Low quality should be barely there, just to indicate that something's there. The best way to verify LODs is by switching to wireframe mode (or use wireframe selection) and move the camera backwards until the wireframe becomes a solid color, then you can switch to a lower LOD. I've seen asset store models that use like 5 LODs which is doing its job to optimize, but not as good as it COULD be, by having that many different models compared to all the vertices rendered at real time, the 2nd and 4th LODs will barely make any difference, but just add heap to memory, which as I said, still optimizes, but it nerfs the potential result.
Helped me a lot! Especially the part where you mentioned that every single mesh in your game was a separate mesh despite them being exactly the same. I went through the many buildings in my game and noticed that every single one had a separate mesh (something dumb that probuilder did), so I made all of them into a single mesh and it helped an unholy ton with the performance!
I suggest doing probuilder - export and export all of those meshes to a fbx or obj file. Afaik probuilder for some stupid reason rebuilds your meshes at runtime every single time the game (scene) is loaded.
@@janda2304 Would be good if more game dev tutorials would warn you about it lol. In my first few days of Unity I was told to use probuilder and only 2 years later am I finding out it's a bad idea
Great video! I know it’s been a lot of work to get it to this level of performance, and I commend you for your hard work and dedication. It’s not easy to go back to an old project and work on it again after many months/years have gone by, so amazing work! I work as an engine programmer myself and, as you can imagine, performance matters a lot to me. So for me it was really nice to see a video like this and I hope you continue your journey into optimizations and performance. If you’re interested, one of the things you can look into is Data-Oriented Design. It’s a pretty interesting topic (at least to me😅) that approaches performance in terms of hardware characteristics and how memory works under the hood. I know Unity has an implementation of an ECS nowadays (which uses Data-Oriented Design principles behind the scenes). I don’t know how good or practical the implementation is, because I’ve never used it myself, but I believe they’ve really focussed on it heavily in recent years. So that might also be an interesting area to explore in the future.
Do you think such architecture can be relevant in this kind of game? I haven't deep dive into the topic yet, but to me it seems like only games with a massive amount of objects can really benefit from it (or in competitive multiplayers where performance is everything, but it sounds like hell to design and maintain)
Love to see that you're still around and uploading! Looking forward to giving this a watch! Even though I have absolutely 0 plans to do anything with the knowledge you're about to share with me, I love content like this. Always awesome to see behind the scenes on game development!
I currently have no use for this information but i love optimisation so much that i fully enjoyed the video. Great work :D Oh and i love the energy you bring to the video.
Great video 🧡. I have one tip for artists and one for programmers: Here's a tip for any artist who is going to attempt to make a game - TAKE A COURSE IN PROGRAMMING! I work with and have had to optimize levels created by artists who didn't know the meaning of the word "performant". So please just take a small course in programming. It'll help you immensely. And for all the programmers out there, here's a different tip : complex =/= good. Don't write extremely complex, hard to read code if you can achieve the same result by simpler, more basic means. Keep It Simple and Stupid - K.I.S.S There are so many Unity store assets that are just horrible when used without thinking - both in terms of art assets, AND in terms of tools and systems. You would be surprised at the number artists who don't know what being performant means, and ALSO, you would be surprised at the number of programmers who don't know how to keep code simple and clean.
6 Ways To Guard Your Energy 1. Trust with your intuition 2. Don’t engage in negative gossip 3. Go in nature you’ll never be alone 4. Meditation 5. Eat Clean 6. Don’t sleep next to your phone
22:09 - "If you know a better way than to turn things off with collision let me know" - I'd imagine that the best way is finding if the centroid of your player is within a bounding box. I'm not sure how you'd do this in unity though, but even using collision with a point object would be better than collision with your player object.
If I understand the problem correctly about the collision thing at 22:15 you might want to do a distance check between the object and the player first to see if the object is even close enough to worry if its colliding. If the player was moving really fast that might cause the player to move right through things but it didn't seem like a problem your game would deal with.
Holy crap this is so useful! I'll be honest that I had to pause every section and look up what you're talking about, but holy crap! I'm trying to make a low-poly action game that's as easy on computers as possible so this is insanely useful!
Wow. This video is awesome! I haven't even made a game yet, but I'm already spinning these ideas into my thought process for when I find myself working out how to implement features or problem solve. Very nice!
Hey, just wanna say thank you for this tips for designing Unity Games, right now im designing a tool for simulation of a hospital enviroment using unity and these tips really help a lot, hope to see more on game design tips !
8:56 this is really Important for 3D Artists this was exactly the reason why my first game couldn't get higher than 20 fps I build my whole level in MAYA because my teacher never told me there is something called draw calls and the general workflow of 3D Assets / props for Game Engines My 3D models where optimized af and I didn't understand why my ~1000 poly assets killed the performance. No one told me the workflow that you usually only export the .fbx, then create a prefab / blueprint in Unity and not drawing every mesh multiple times into the scene and instead reuse them. Also a big problem was the materials. Materials are probably the main reason your fps drop like sh*t. Using multiple materials for example on a chair and not using base materials that can be drawn on many different assets for stuff like wood, metal etc. killed my performance. Before I knew there was something called color IDs I created a material for every single thing that had a slightly different color. And with over 200 Materials (2048px) I know now why I had 20 fps.. anyways I didnt understood why my relativ small scene had such bad performance but after hearing about drawcalls, materials optimization and a work of 20h we finally got a good performance ^^
this was truly the most enjoyable video that i've ever watched the entirety of without understanding. :D this was presented really clearly and articulated accessibly.
Instead of checking in update for events, use actual events. Also, read documentation. You don’t need, for example, find object with name “Camera”, use Camera.main. And avoid using strings as parameters at all costs. What if you renamed your object or have object with same name? Right. Always think ahead when coding
I'm an effects artist, you can also batch particle materials by making basically a sprite sheet of textures and using the separate cells as particle textures. This is really good for mobile effects.
Glad I caught your upload before work this time! I’m unsure about what I wanna do at the moment. But I know I want to go into digital art and have considered making my own game. But I don’t know a damn thing about making games, I’d rather work on the artistic side of things. This information is useful though, in case I do try to make something out of my ideas. Thanks, stranger. Take care and be safe
Take it one step at a time. It sounds like you know roughly what you want to do. Maybe just find a weekend to play around in unreal / unity and see how you find the game engine? Try and stick to small, manageable projects or even follow a tutorial and then mix it up to add your own style. Have fun! Wish you the best :)
@@yagmanx I’m unsure if those programs do it but I think if I ever do make a game it’d be pixelated. If you’ve ever heard of Octopath Traveller, that’s the closest thing I’ve seen to the art style I would like. Not exact, but definitely close to it. Not sure if those engines offer that kinda stuff. Either way it’s like 5 years away lol. Thank u stranger for your kind words
Wow, great work! You're skilled in video making and explanation, as well as game dev. I want to be like you when I grow up. I'm only 64, so I have some growing up to do.
What I would add, and I know that my comment is a couple of years late but... One of the things I learned in optimizing our games was 1) use object pooling; and 2) never let the system do it's own Garbage Collection. Managed code, especially on non-pc platforms, will wait until the absolute last minute and then Collect. This invariably results in it dropping fps down to about 5fps for a second or two (dependent on the amount of garbage that the game makes). What you can do instead - put your own garbage collector (GC code) into a coroutine, and then adjust the timing to strike the best balance. (To anyone new, you don't want to run you GC every frame, because it has its own overhead; hence finding the optimal balance.) This is especially important if you destroy a lot of objects, especially ones that cannot be pooled. Like destructable scene objects, those wouldn't be pooled. Hope this helps out!
Thank you so much! I learned so much in this video and my framerate, on average, has increased by 20fps. Until this video, I didn't know about Occlusion Culling so I decided to write a script that would only render parts of the level the player was in. It was basically a worse version of Occlusion Culling. Soooo there goes hours of my life I will never get back.
22:25 - 9: Optimise GameObject Components. great, no rigidbodies needed except for player and enemies, a box collider will do for platforms and ground. thanks for the tip
19:50 "I thought i was smart for using Find() because i didn't want to put in all those references." Same, i also hate references by hand. It also introduces new points of failure. What i do since recently is this: 1. [HideInInspector] GameObject object; 2. if(object == null) Find("ObjectName"); HideInInspector is like a SerializeField. So it will keep it's value but is hidden. Though i usually don't use Find. Just GetComponent and i also [RequireComponent] that component. This way it's failsafe. I try to make my scripts in a way that you can just slap them on and don't have to remember providing anything.
I'm very happy to hear this and totally agree! I use Unreal too and learning all of these techniques myself has definitely helped keep my Unreal projects performant
3:37, I think that burp was important for you to keep in. It addresses the underlying point of this video. Taking a step back to flush out the unnecessary processes. Your burp was akin to the background processes that hadn’t been ironed out and were just floating around inside the game.
3:45 inactive gameobjects dont get their Update called 8:08 Loding can be used with decimated models like that plant with 6 steps unsubdivide. You just put good looking upclose model in LOD0 and that ugly polygons in LOD1 and set distances. This way plant will be ugly at distance but it wont be noticable cause there wont be enough pixels to show its uglyness
Please correct me if I am wrong. To add to this comment for future readers: I think it would be good to define "inactive" here. This would be a GameObject or an ancestor that has enabled set to false, or SetActive(false), or if the specific script component with the Update() is disabled. Since Occlusion Culling was a topic in the video, I believe a mention here is helpful. A culled object just has it's Renderer disabled, but its scripts and colliders might still be running and so is, therefore, active.
@@MegamanXGold both works, if you disable the script then it won't run the update function, if you disable the gameobject none of the components including scripts will run (there are some exceptions such as certain events).
Salut Bigkam! Heureux que tu as aimé la Pixel Days qui reste en 2022 un must! Vraiment honoré de t'avoir croisé et d'avoir tourné une vidéo qui (spoil) sortira mardi 3 mai! En espérant pouvoir à mon tour me déplacer chez vous, à la Hedge convention par exemple j'en rêve! A plus l'ami Alexis
The global personality data workaround fixes the framerate issue, but introduces weird dependency issues. No bigs for a little game, but in a big game or if you want reusable code, you don't want your player to be controlling external systems. You can run into issues where multiple scripts are editing the same global values on top of one another, adding/removing/changing these external systems forces you to edit every script that references them, and if you want to bring the player script into a different game, you either have to bring the entire dependency chain, or refactor the player. A message bus (observer pattern style) is a great solution. Your player broadcasts that it jumps and any object listening for a "player jumped" event will do their thing. The player doesn't care who's listening, so the only dependency is the bus architecture. This will also help with juggling find commands.
Hello, perhaps if something is not active in your scene or a script hasn't been activated yet then you can turn off other things in your scene based on a specific variable rather than relying on those collision boxes to turn off others. So basically a variable can be changed when someone enters a door and the code can check if the door script is now active or if the variable is true ( for example) and then have it effect another variable which will turn certain collisions off (once again, for example).
Setting up game events might be better than setting variables that need to be frequently checked. var doorOpened = new Event(); void DoStuff() { // stuff } doorOpened.AddListener(DoStuff); void OnDoorOpened() { doorOpened.Invoke(); } The example could be better but I'm not at my PC. Worth checking out, though :)
Awesome work altogether. If you weren't a computer programmer... many of my friends and I would have absolutely mistaken you for somebody else we met, whereas the main difference... the other seriously thinks of herself as the most perfect there is, meanwhile... also told me I'm stupid not to ever become her man.
Greetings! Thank you for the video! On 10:35 you say that with static batching culling won't work, but on StaticBatchingUtility page in documentation is written that each object in a batch will be culled individually, or it is the case for runtime static batching only? Can you give your comment on that, please? :)
Thanks for your tips, I had to optimize my game for the Oculus Quest. Very important: remove mesh colliders from models that you buy, sometimes they come by default with mesh colliders and you even dont know.
This wouldve taken ages to refactor and then you made a whole 30min video about it to 🤯 I wouldve given up at after looking at the profile haha. Kudos to you!
Better script off button :- Layermask and coroutine Reroute the routine through itself so for example Coroutinename() Yield return new waitforseconds (2f) If(layermask.Equals(stoodupon); { Turnoff(); //logic to turn off stuff Resetroutine(); // don't do it inside itself youll get a stack overflow Yield break //this stops garbage } And there we go Set up a layer on the ground or the door you want to turn stuff on with Make a.simple.check in your update on your movement controller If mask is stood on set.bool Stood upon =!stood upon This way your only calling a check once every two seconds Instead of 120 times every 2 seconds Hope it helps Play with it Coroutines are powerful tools 🔧 👏 Edit You may write another coroutine for the bool switch that also only happens once every 2 seconds instead of update too Though it's a single line of code and won't affect performance but a touch
I see you have used Unity.Random to randomize Lights but they become very jittery to achieve smooth randomness you may want to look into Perlin Noise (Mathf.Perlin).
Thank you for this helpful Video! 👍 I'm working as a XR Developer and I had performance issues with my game on my standalone PICO VR Headset, where high FPS is needed.
Great video on some optimization fundamentals. I'd also look into Tasks as an alternative to coroutines. They offer things that coroutines can't like return values, and they work asynchronously so you can await on them. A little bit trickier to implement, but you won't be sorry for learning it. Also, Camera.main will return you the main camera, so you don't need to FindObjectOfType, but a better approach may be to use a singleton pattern to manage things you need direct access to, or a static class which can store information you use consistently. Great video though and good luck with your game :)
@@Lordilucas12 Very similar in terms of operation, but less garbage collection with Tasks (and less garbage collection ultimately means faster), and they have more options for returns / awaits. They are a little trickier to use, but they are also a little cleaner to use once you have it setup. It really depends on the use case you are after.
Coroutines CAN have return values, you just have to write your own StartCoroutine alternative which intercepts the return ... Here's a pseudo-code example of how it works: if ( coroutine.MoveNext() && coroutine?.Current is T returnValue ) { return returnValue; }
this is so fucking good/helpful, thank you/please release more shit appreciate the broad range of things you cover for performance savings & real life example
Been using Unity for almost over one year now. If Blender Game Engine still existed, but better, I wouldn't, tho. Still Unity is the best free alternative there is. I recall BGE being super limited as far as performance is concerned, not to mention its asset limitations. The fact that you could model right there and then just use the model directly and its logic bricks that did wonders with no script required were awesome. I love coding anyway.
converting the material of repeating object to material instance, ca would improve greatly performance without changing polycount . very well done video.
Great video and very helpful, i struggled in my game when i used a second camera for water reflection; im gonna see if i can turn it off and only use it when the player is near by, but the problem is that my game is multiplayer so its kinda tricky and its a racing game. What im worried about is that when the player is near the water and the cam turns on, he would get a sudden loss of fps. Guess i would have to try and see how it looks. As for a side note, i prefer to avoid using many public variables (min 20:54), only when need to be read by other script, and use instead SerializedField, as it shows in the inspector as well and can drag and drop keeping it private. Example: [SerializeField] private GameObject myObject;
Apologies about that, heres a link to the written version where the code is easy to read in higher res, hope it helps! : yagmanx.medium.com/10-tips-how-to-improve-a-unity-games-performance-to-perfection-noob-friendly-9b906082bf82
Hi, About 4: Optimise Your Models, when you Retopology in blender with the decimate modifier (or any other way like manually or with Add On's that do a really better job like Quad Remesher (payed) or Instant Mesh (free) ) you should bake the texture maps (Color and Normal specially and the others depends on what's available like AO, Cavity, Roughness, Metallic) from the original model to the new one and if both of the models share the same silhouette they will be identical after rendering (in game).
You can actually hook your scripts into the occlusion events to make them turn off when the object is occluded by the camera, not always practical but when it is it saves immense time and performance. You could attach that to all the interactables in your game for example and the detection code input will only run when the object is being rendered, on top of that you could go a step further even and have entire gameobject turn itself off and on, which means non of those components are taking up performance unless they are being rendered. This will probably give you a good 30 fps if done right. I once made a 2d game in unity that ran at 500fps using optimizations and turning off vsync, obviously not practical but it was mostly to a test for myself to see how optimized I could get something to run. Funny thing was if the game was paused the frame rate counter actually went all the way to infinity.
Currently to disable scripts, I do a sort of ping. It's still physics though. On a long delay, I have it send out a big overlap sphere. That sphere uses a layer mask to only look for stuff on the "player" physics layer. So it is just looking for the only object that exist on that layer. And if its in range, it turns on/off. I use the update method sparingly, so this is mostly just for enemies. I guess this is basically the same thing setting up trigger box does, but it's on an even longer delay than the physics update, so it could be better? And you don't have to set up all of the triggers of course. You could further improve it by reducing the number of checks. I would move the ping system to its own component and object. You would feed it an array of whatever you want to toggle for the whole room or world chunk. Kind of like setting up Occlusion volumes. Having the pings come from the player looking for stuff, would be nice. But then you have to start micro managing a list, which is just yucky to me. You could also just make it check the distance to the player and circumvent the physics system entirely. But 1: I think overlap sphere is actually faster than doing a magnitude check because it won't do a square root function. And 2: This could work with multiple player characters. Even if this isn't a multiplayer game, I might want to control other entities. I feel like physics is THEE way to do this, don't doubt yourself.
The mesh collider bit is actually so important, it's asked in job interviews. Usually something like which collider is best for performance? It's the box collider. Honestly I thought this is basic knowledge, how did you not meet with this bit of information?
Learn from my mistakes in this post mortem of my first Unity game, Perfection, and learn tips to improve your own games performance!
Check out the free horror indie game Perfection: yagmanx.itch.io/perfection
Apologies that some of the examples are low quality, I also wrote this post mortem in a written blog with higher quality images as references to all of the points made: medium.com/@yagmanx/10-tips-how-to-improve-a-unity-games-performance-to-perfection-noob-friendly-9b906082bf82
Well you're stupidly good looking. And a genius by the looks of things. You won the jackpot by all standards.
Ok, made in Unreal I hate Unity...(the interface is total from '90s).
This is great reminds me of Brackeys who I miss.
@@davedogge2280 Thank you, that's a wonderful compliment as I also miss Brackeys! His videos helped me so much throughout my university course
@@themarlboromandalorian There's a time and a place for every statement.
You succeeded at neither the time, nor the place. 👎
If you want your GameObjects to be visible without being public, you can put [SerializeField] before. It will be visible in the inspector but still private.
It's not performance related, but using public is bad practice in 90% of cases. Using serializedField + Setters and Getters is a much better approach for clean code and decoupling
Or use Dependency Injection and get rid of the 90% of the inspector setups
I had no idea I was using dependency injection until you mentioned this and it triggered my curiosity, so I googled it to see what it was.
I am someone who tries to think before coding to see if there is any other way I could do something to minimize code and improve readability. Crazy how the mind comes from alone to these solutions and you don't even know there is always an existing term for that.
@@FlotzOnYou why is using public bad?
@@chrono9503 because it's not the right encapsulation most of the time. Public means the property is exposed to reading and writing by a foreign class, which you don't want most of the time
I'm maybe a bit late on this video but one thing that helped me a lot when i started, was learning about Object Pooling.
Basically if you have certain objects that have to appear and then disappear frequently (like enemies for example that appear when spawning and disappear when dying), instead creating and destroying the object simply activate it and deactivate it.
Usually i have a script that manages a certain amount of objects that are deactivated on the start of the game and when i need one or multiples of it, I ask the ObjectPoolManager for those objects, set them active, set up any components they might need, initialize their starting parameters and send them on their way. And if they have to disappear, just deactivate them because the ObjectPoolManager has a reference to them and can easily find them for future activation.
Very powerful!
Thank you
This is so extremely helpful! When I'm watching other devlogs they always get to a point where they simply "optimize", but they never explain what there doing! This is an extremely useful checklist to go through for all your games and I definitely plan to integrate this into my workflow! Thanks again for the great video!
Glad it was helpful!
Currently embarking on my third attempt for making a game in unity - your channel is a life saver! I had no idea you could use layers for 3D elements!
if you write a bit of code you can actually add sorting orders to 3d meshes as well which is incredibly useful and I never understood why it wasn't buitlin.
Hey there, just an extra tip.
I see a lot of professional games using different meshes for an object visual aspect and its collisions.
Making a simpler more lightweight mesh for an object's collisions could help you optimize the game a bit while keeping mesh colliders.
This is a very good point! Thanks for pointing it out :)
would still be more performant to just use a box collider or set of box colliders, the code that has to run for mesh collision is just more advanced than checking if a point is within the bounds of a cube.
@@bradjones7491 Any documentation on the algos used for that calculation? I'm certainly curious what the Big-O is (you are certainly right, Im just curious to what extent the difference in performance is)
@@0xlapras646 I mean you would just have to look up how to do it from scratch, but checking boundaries of a cube is mathematically significantly simpler than check the bounds of a complex mesh.
for example you could easily determine if a point falls within a volume of 1, but a mesh collider has a non standard volume so you would first have to determine the volume before checking the bounds.
Mesh colliders are used extremely sparingly in general, and mostly just for simple shapes like ramps and sometimes terrain.
As for the extent of the difference I couldn't say for sure but I'd assume it would be fairly significant since almost every AAA game in existence utilizes the multiple simple colliders method.
Mesh colliders should only really be used when the alternative is prohibitive, such as with a massive object like a terrain, where aligning individual colliders would take thousands of hours.
Basically mesh colliders are time savers, but are overutilized by people who get lazy, and by doing just a bit more manual setup you can often avoid the additional overhead.
Another thing to consider is that often times mesh colliders fail at detections where a box collider would not. While it's pretty unordinary and example of this can be achieved by moving an object at incredible speeds, if the wall is a mesh collider it has a significantly higher rate to allow the object to pass through than a cube. and This is because mesh colliders don't really have thickness so if the physics calculation somehow places that object on the other side then the collision will not be detected, whereas with a cube the object would need to reach significantly higher speeds to breach it's entire bounds, and you could make a wall have theoretically infinite thickness to make it basically impossible to clip into.
As a side note about the fail rate of physic detection this mostly occurs because physics calculations are done on an independent update loop that has it's own time scale so a significantly large movement in a single update of that tick function could offset the object further than the collision is detecting thereby avoiding the collision detection entirely. This is because most physics systems don't calculate along the traveled vector when determining collision, rather they only check for the position at that frame of the tick update. That is to say, that if an object moves farther than the entire collision's size in less than 1 physics update tick, then that collision will not be detected.
That also leads into another slight tangent about unity in particular, where people think that unity's physics engine is very inaccurate, but this is actually mostly caused by people never changing their physic's tick rate under the time settings in unity. By default I believe it is set to a tick rate of 0.10 which is 10 frames per second and is pretty inaccurate, allowing for most "fast" speeds to easily clip through collisions.
I don't know what I'm doing when it comes to programming(and anything else) but this video was sooo good. You've structured and inform everything in a super easy a digest way. You go sister!
Very informative! With a background in 3D I was shocked at the number of polys on the plant. But if you don’t have a background in 3D it’s not very shocking I guess. Glad to see the improvements worked!
Thanks I'm glad to hear it. Yes, it was quite a shock! Had to just remove that plant in the end 😅
When you see the kind of optimizations and efficient modelling methods used in AAA games, you realize how much devs strive to minimizes polys and stuff. I've seen wireframe models of things that shocked me, because it did NOT look like it was that low poly in-game!
Just from personal modeling experience and 2 years of a grade school 3d class, I too was blasted back by the polys of the plant 😂
@@MFKitten you'd be amazed at what a good texture/shader combo can do.
@@yagmanx I know I'm super late here but on the subject of that plant (and other models with similar poly count issues):
On your decimate modifier at 7:19 you could select the "Planar" option and set its Delimit mode to "UV". This would decimate the model whilst performing calculations favoring the original UV layout more than other options would.
Obviously not as good as making a low-poly version yourself, but it's a closer result that can work just fine with many basic props.
i followed you back when i was into programming and trying to make games. i switched back to what i have been doing for almost 2 decades which is art and making art, possibly for games. but i am alot happier. there are people who should create the code and there are people who like concepts only and not the technical and admirably complicated part of the game making process. seeing this makes it look even more layered than i had remembered. still love games though and happy to see what you are working on.
my life was so much worse when i first started watching your videos. its gotten better but i am a ways off from my artistic goals. keep uploading videos especially upcoming projects related, its always cool to see.
This is really interesting to know. I'm so glad you're in a better place now, it can take a long time to know what really makes us happy. Best of luck for your future :)
you should try unity bolt
19:36 i know its a bit late to respond but in case someone need it: the use of "find" in the "awake" will not necessarily degrade the performance of your game. it depends on what script using it. if you use "find" in a singleton, it will be fine. just don't use "find" in a script attached to dynamic game object. another thing, if possible, try to use "FindObjectOfType" instead of "Find". i use "find" in the awake method of my level scene. although its not a singleton, but i consider it safe to put it there. no one will notice additional 0.5 sec delay during the scene loading :D
As for LOD'ing, I find it better to have the high quality / mid quality / absolute low quality. Mid quality should be the default, high should only be shown in either cutscenes or when very close to the model, so make sure your decimated models are in the 'mid' quality to make it the default. Low quality should be barely there, just to indicate that something's there.
The best way to verify LODs is by switching to wireframe mode (or use wireframe selection) and move the camera backwards until the wireframe becomes a solid color, then you can switch to a lower LOD.
I've seen asset store models that use like 5 LODs which is doing its job to optimize, but not as good as it COULD be, by having that many different models compared to all the vertices rendered at real time, the 2nd and 4th LODs will barely make any difference, but just add heap to memory, which as I said, still optimizes, but it nerfs the potential result.
Helped me a lot! Especially the part where you mentioned that every single mesh in your game was a separate mesh despite them being exactly the same. I went through the many buildings in my game and noticed that every single one had a separate mesh (something dumb that probuilder did), so I made all of them into a single mesh and it helped an unholy ton with the performance!
I suggest doing probuilder - export and export all of those meshes to a fbx or obj file. Afaik probuilder for some stupid reason rebuilds your meshes at runtime every single time the game (scene) is loaded.
@@janda2304 Would be good if more game dev tutorials would warn you about it lol. In my first few days of Unity I was told to use probuilder and only 2 years later am I finding out it's a bad idea
Great video! I know it’s been a lot of work to get it to this level of performance, and I commend you for your hard work and dedication. It’s not easy to go back to an old project and work on it again after many months/years have gone by, so amazing work!
I work as an engine programmer myself and, as you can imagine, performance matters a lot to me. So for me it was really nice to see a video like this and I hope you continue your journey into optimizations and performance.
If you’re interested, one of the things you can look into is Data-Oriented Design. It’s a pretty interesting topic (at least to me😅) that approaches performance in terms of hardware characteristics and how memory works under the hood. I know Unity has an implementation of an ECS nowadays (which uses Data-Oriented Design principles behind the scenes). I don’t know how good or practical the implementation is, because I’ve never used it myself, but I believe they’ve really focussed on it heavily in recent years. So that might also be an interesting area to explore in the future.
Thank you for the advice!
Do you think such architecture can be relevant in this kind of game? I haven't deep dive into the topic yet, but to me it seems like only games with a massive amount of objects can really benefit from it (or in competitive multiplayers where performance is everything, but it sounds like hell to design and maintain)
Love to see that you're still around and uploading! Looking forward to giving this a watch! Even though I have absolutely 0 plans to do anything with the knowledge you're about to share with me, I love content like this. Always awesome to see behind the scenes on game development!
Ok, I've watched this video for about 1-2 seconds and already.... clicked Like and subscribed! Thank you for instant atmosphere of joy and positivity.
The way you are decimating the models is perfect for LOD! I would highly suggest checking it out if you haven't already.
I currently have no use for this information but i love optimisation so much that i fully enjoyed the video. Great work :D
Oh and i love the energy you bring to the video.
it s really cool watching your journey from a game fan to a professional game creator .... plz post more unreal & unity content
Great video 🧡. I have one tip for artists and one for programmers:
Here's a tip for any artist who is going to attempt to make a game - TAKE A COURSE IN PROGRAMMING! I work with and have had to optimize levels created by artists who didn't know the meaning of the word "performant". So please just take a small course in programming. It'll help you immensely.
And for all the programmers out there, here's a different tip : complex =/= good. Don't write extremely complex, hard to read code if you can achieve the same result by simpler, more basic means. Keep It Simple and Stupid - K.I.S.S
There are so many Unity store assets that are just horrible when used without thinking - both in terms of art assets, AND in terms of tools and systems. You would be surprised at the number artists who don't know what being performant means, and ALSO, you would be surprised at the number of programmers who don't know how to keep code simple and clean.
6 Ways To Guard Your Energy
1. Trust with your intuition
2. Don’t engage in negative gossip
3. Go in nature you’ll never be alone
4. Meditation
5. Eat Clean
6. Don’t sleep next to your phone
The fact that you exists gives me hope lol. i'm not chasing unicorns lmao!
Ooh, and nice tutorial btw !
22:09 - "If you know a better way than to turn things off with collision let me know" - I'd imagine that the best way is finding if the centroid of your player is within a bounding box. I'm not sure how you'd do this in unity though, but even using collision with a point object would be better than collision with your player object.
Collision detection with triggers would be better, due to unity using an octree internally to do the same thing a lot more optinized
If I understand the problem correctly about the collision thing at 22:15 you might want to do a distance check between the object and the player first to see if the object is even close enough to worry if its colliding. If the player was moving really fast that might cause the player to move right through things but it didn't seem like a problem your game would deal with.
Holy crap this is so useful! I'll be honest that I had to pause every section and look up what you're talking about, but holy crap! I'm trying to make a low-poly action game that's as easy on computers as possible so this is insanely useful!
Wow. This video is awesome! I haven't even made a game yet, but I'm already spinning these ideas into my thought process for when I find myself working out how to implement features or problem solve. Very nice!
Thank you and good luck with any future games!
@@yagmanx thank you for the reply and the kickass video!
Hey, just wanna say thank you for this tips for designing Unity Games, right now im designing a tool for simulation of a hospital enviroment using unity and these tips really help a lot, hope to see more on game design tips !
I'm so glad to hear that these tips could help you! Best of luck for your tool :)
8:56 this is really Important for 3D Artists
this was exactly the reason why my first game couldn't get higher than 20 fps
I build my whole level in MAYA because my teacher never told me there is something called draw calls and the general workflow of 3D Assets / props for Game Engines
My 3D models where optimized af and I didn't understand why my ~1000 poly assets killed the performance. No one told me the workflow that you usually only export the .fbx, then create a prefab / blueprint in Unity and not drawing every mesh multiple times into the scene and instead reuse them. Also a big problem was the materials. Materials are probably the main reason your fps drop like sh*t. Using multiple materials for example on a chair and not using base materials that can be drawn on many different assets for stuff like wood, metal etc. killed my performance.
Before I knew there was something called color IDs I created a material for every single thing that had a slightly different color. And with over 200 Materials (2048px) I know now why I had 20 fps..
anyways
I didnt understood why my relativ small scene had such bad performance but after hearing about drawcalls, materials optimization and a work of 20h we finally got a good performance ^^
I didnt even understand like half of what you said, but for some reason I watched through the whole thing. Well written!
Thank you a million, you made the job easier in talking about all the optimization issues in one video, you made our life easier , thank you🙏 😍
Great content, found it right before I start my first big project. Love your video style, quirkiness, personality. I'm now a fan. Much love!
Thank you for the tips and for breaking it down! Optimizing has always been a little bit of a mystery to me.
Awesome video showing the tips than you used for optimize your game!! Thanks for sharing it!!
Also good luck working on "Perfection" new content!!
this was truly the most enjoyable video that i've ever watched the entirety of without understanding. :D this was presented really clearly and articulated accessibly.
Haha glad to hear it lovely 💖
Really great video. I love your enthusiasm about gamedev which I share and your tips were very well explained. Eye opener to be sure.
Instead of checking in update for events, use actual events.
Also, read documentation. You don’t need, for example, find object with name “Camera”, use Camera.main.
And avoid using strings as parameters at all costs. What if you renamed your object or have object with same name? Right.
Always think ahead when coding
Exactly what I needed to know to push the performance of my VR game. Thank you!
Thank you so much for your sympathy, energy and shared knowledge. Great video!!
really great video >w< i really need to use the profiler more. also your eye shadow is so good omg t_t
Love the honesty with the light maps - really made me laugh. Faking it with post processing in this context sounds good to me 😂
I'm an effects artist, you can also batch particle materials by making basically a sprite sheet of textures and using the separate cells as particle textures. This is really good for mobile effects.
...and use one material.
Glad I caught your upload before work this time!
I’m unsure about what I wanna do at the moment. But I know I want to go into digital art and have considered making my own game. But I don’t know a damn thing about making games, I’d rather work on the artistic side of things. This information is useful though, in case I do try to make something out of my ideas. Thanks, stranger. Take care and be safe
Take it one step at a time. It sounds like you know roughly what you want to do. Maybe just find a weekend to play around in unreal / unity and see how you find the game engine? Try and stick to small, manageable projects or even follow a tutorial and then mix it up to add your own style. Have fun! Wish you the best :)
@@yagmanx I’m unsure if those programs do it but I think if I ever do make a game it’d be pixelated. If you’ve ever heard of Octopath Traveller, that’s the closest thing I’ve seen to the art style I would like. Not exact, but definitely close to it. Not sure if those engines offer that kinda stuff. Either way it’s like 5 years away lol. Thank u stranger for your kind words
Wow, great work! You're skilled in video making and explanation, as well as game dev. I want to be like you when I grow up. I'm only 64, so I have some growing up to do.
Thanks for sharing your experiences with us!
Thank you , you have no idea how much this helped and on what project!!! You are amazing have a great day.
Never thought I'd fall in love through a Game dev tips video.
Finally, a real solution to a real problem. Great Video!
I always like to do a quick performance test after adding anything so that I intuitively know what's draining performance
What I would add, and I know that my comment is a couple of years late but... One of the things I learned in optimizing our games was 1) use object pooling; and 2) never let the system do it's own Garbage Collection. Managed code, especially on non-pc platforms, will wait until the absolute last minute and then Collect. This invariably results in it dropping fps down to about 5fps for a second or two (dependent on the amount of garbage that the game makes). What you can do instead - put your own garbage collector (GC code) into a coroutine, and then adjust the timing to strike the best balance. (To anyone new, you don't want to run you GC every frame, because it has its own overhead; hence finding the optimal balance.) This is especially important if you destroy a lot of objects, especially ones that cannot be pooled. Like destructable scene objects, those wouldn't be pooled.
Hope this helps out!
Very well explained at a level that I find accessible.
Really informative! Gret work putting this together
Bit of a gold mine this, i watched it on sat after 10g of mushies and thought id landed in the future. This is great.
Thank you so much! I learned so much in this video and my framerate, on average, has increased by 20fps. Until this video, I didn't know about Occlusion Culling so I decided to write a script that would only render parts of the level the player was in. It was basically a worse version of Occlusion Culling. Soooo there goes hours of my life I will never get back.
22:25 - 9: Optimise GameObject Components. great, no rigidbodies needed except for player and enemies, a box collider will do for platforms and ground. thanks for the tip
19:50 "I thought i was smart for using Find() because i didn't want to put in all those references."
Same, i also hate references by hand. It also introduces new points of failure.
What i do since recently is this:
1. [HideInInspector] GameObject object;
2. if(object == null) Find("ObjectName");
HideInInspector is like a SerializeField. So it will keep it's value but is hidden.
Though i usually don't use Find. Just GetComponent and i also [RequireComponent] that component. This way it's failsafe. I try to make my scripts in a way that you can just slap them on and don't have to remember providing anything.
this video was Perfection
I'm using your videos as a citation on my thesis :))
What's nice is that most of the stuff you say here actually applies to any other fully fledged engine as well (unreal for example).
I'm very happy to hear this and totally agree! I use Unreal too and learning all of these techniques myself has definitely helped keep my Unreal projects performant
3:37, I think that burp was important for you to keep in. It addresses the underlying point of this video. Taking a step back to flush out the unnecessary processes. Your burp was akin to the background processes that hadn’t been ironed out and were just floating around inside the game.
it also scared the shit out of me!
Thank you for sharing, I will release a small indie game soon, and your advice was really helpful!
Really nice recap useful for all type of users !
3:45 inactive gameobjects dont get their Update called
8:08 Loding can be used with decimated models like that plant with 6 steps unsubdivide. You just put good looking upclose model in LOD0 and that ugly polygons in LOD1 and set distances. This way plant will be ugly at distance but it wont be noticable cause there wont be enough pixels to show its uglyness
Please correct me if I am wrong. To add to this comment for future readers:
I think it would be good to define "inactive" here. This would be a GameObject or an ancestor that has enabled set to false, or SetActive(false), or if the specific script component with the Update() is disabled.
Since Occlusion Culling was a topic in the video, I believe a mention here is helpful. A culled object just has it's Renderer disabled, but its scripts and colliders might still be running and so is, therefore, active.
@@MegamanXGold both works, if you disable the script then it won't run the update function, if you disable the gameobject none of the components including scripts will run (there are some exceptions such as certain events).
you could take it a step further and just replace the model with a 2d image if it's far enough away and people probably won't notice.
Salut Bigkam! Heureux que tu as aimé la Pixel Days qui reste en 2022 un must! Vraiment honoré de t'avoir croisé et d'avoir tourné une vidéo qui (spoil) sortira mardi 3 mai!
En espérant pouvoir à mon tour me déplacer chez vous, à la Hedge convention par exemple j'en rêve!
A plus l'ami
Alexis
Thank you! Great video. I’m a beginner and this has been so helpful. :)
Woow very nice, It's interesting to see you working with unity in your channel, I love c# so this video it's more interesting for me ;)
The global personality data workaround fixes the framerate issue, but introduces weird dependency issues. No bigs for a little game, but in a big game or if you want reusable code, you don't want your player to be controlling external systems. You can run into issues where multiple scripts are editing the same global values on top of one another, adding/removing/changing these external systems forces you to edit every script that references them, and if you want to bring the player script into a different game, you either have to bring the entire dependency chain, or refactor the player.
A message bus (observer pattern style) is a great solution. Your player broadcasts that it jumps and any object listening for a "player jumped" event will do their thing. The player doesn't care who's listening, so the only dependency is the bus architecture.
This will also help with juggling find commands.
Doing some research before deciding whether to embark on my own game development journey. This has shown me there's a lot more to understand 😂
Hello, perhaps if something is not active in your scene or a script hasn't been activated yet then you can turn off other things in your scene based on a specific variable rather than relying on those collision boxes to turn off others. So basically a variable can be changed when someone enters a door and the code can check if the door script is now active or if the variable is true ( for example) and then have it effect another variable which will turn certain collisions off (once again, for example).
Setting up game events might be better than setting variables that need to be frequently checked.
var doorOpened = new Event();
void DoStuff() {
// stuff
}
doorOpened.AddListener(DoStuff);
void OnDoorOpened() {
doorOpened.Invoke();
}
The example could be better but I'm not at my PC. Worth checking out, though :)
Awesome work altogether. If you weren't a computer programmer... many of my friends and I would have absolutely mistaken you for somebody else we met, whereas the main difference... the other seriously thinks of herself as the most perfect there is, meanwhile... also told me I'm stupid not to ever become her man.
Greetings! Thank you for the video!
On 10:35 you say that with static batching culling won't work, but on StaticBatchingUtility page in documentation is written that each object in a batch will be culled individually,
or it is the case for runtime static batching only?
Can you give your comment on that, please? :)
Thanks for your tips, I had to optimize my game for the Oculus Quest.
Very important: remove mesh colliders from models that you buy, sometimes they come by default with mesh colliders and you even dont know.
This wouldve taken ages to refactor and then you made a whole 30min video about it to 🤯
I wouldve given up at after looking at the profile haha. Kudos to you!
Haha honestly, I almost gave up a few times but I'm too stubborn 😂 Thank you for noticing the hard work that went into it. I hope it can be helpful 😊
Love the fact that she made it very relatable 😆
Lots of good information. Have a new subscriber!
great optimisation tips and well described. cheers.
Super useful tips - thanks! Can feel the game breaking bug "kick in the face"...
Better script off button :-
Layermask and coroutine
Reroute the routine through itself so for example
Coroutinename()
Yield return new waitforseconds (2f)
If(layermask.Equals(stoodupon);
{
Turnoff(); //logic to turn off stuff
Resetroutine(); // don't do it inside itself youll get a stack overflow
Yield break //this stops garbage
}
And there we go
Set up a layer on the ground or the door you want to turn stuff on with
Make a.simple.check in your update on your movement controller
If mask is stood on set.bool
Stood upon =!stood upon
This way your only calling a check once every two seconds
Instead of 120 times every 2 seconds
Hope it helps
Play with it
Coroutines are powerful tools 🔧 👏
Edit
You may write another coroutine for the bool switch that also only happens once every 2 seconds instead of update too
Though it's a single line of code and won't affect performance but a touch
I see you have used Unity.Random to randomize Lights but they become very jittery to achieve smooth randomness you may want to look into Perlin Noise (Mathf.Perlin).
Thank you! I shall use this in the future!
Thank you for this helpful Video! 👍
I'm working as a XR Developer and I had performance issues with my game on my standalone PICO VR Headset, where high FPS is needed.
Great video on some optimization fundamentals. I'd also look into Tasks as an alternative to coroutines. They offer things that coroutines can't like return values, and they work asynchronously so you can await on them. A little bit trickier to implement, but you won't be sorry for learning it. Also, Camera.main will return you the main camera, so you don't need to FindObjectOfType, but a better approach may be to use a singleton pattern to manage things you need direct access to, or a static class which can store information you use consistently. Great video though and good luck with your game :)
aren't tasks internally ran kind of like coroutines? It might be easier to optimise code with tasks but it's not directly faster right?
@@Lordilucas12 Very similar in terms of operation, but less garbage collection with Tasks (and less garbage collection ultimately means faster), and they have more options for returns / awaits. They are a little trickier to use, but they are also a little cleaner to use once you have it setup. It really depends on the use case you are after.
Coroutines CAN have return values, you just have to write your own StartCoroutine alternative which intercepts the return ... Here's a pseudo-code example of how it works:
if ( coroutine.MoveNext() && coroutine?.Current is T returnValue ) {
return returnValue;
}
Pretty good! Unity beginners should see this video! BTW, you should switch your unity editor to Dark theme :)
You really managed to implement all the worst performing methods in that game It's a great experience though, thanks a lot for sharing!
Using Blender for a custom collider is definitely a W.
this is so fucking good/helpful, thank you/please release more shit
appreciate the broad range of things you cover for performance savings & real life example
3:37 diablos señorita
Been using Unity for almost over one year now. If Blender Game Engine still existed, but better, I wouldn't, tho. Still Unity is the best free alternative there is. I recall BGE being super limited as far as performance is concerned, not to mention its asset limitations. The fact that you could model right there and then just use the model directly and its logic bricks that did wonders with no script required were awesome. I love coding anyway.
converting the material of repeating object to material instance, ca would improve greatly performance without changing polycount . very well done video.
Great video and very helpful, i struggled in my game when i used a second camera for water reflection; im gonna see if i can turn it off and only use it when the player is near by, but the problem is that my game is multiplayer so its kinda tricky and its a racing game.
What im worried about is that when the player is near the water and the cam turns on, he would get a sudden loss of fps. Guess i would have to try and see how it looks.
As for a side note, i prefer to avoid using many public variables (min 20:54), only when need to be read by other script, and use instead SerializedField, as it shows in the inspector as well and can drag and drop keeping it private. Example: [SerializeField] private GameObject myObject;
Found this channel from BE AMAZED and its quite good... game dev + gameplay sign me up...
Thanks for checking the channel out ☺ glad you like the content!
what the heck happens to the video resolution at 3:39, right after the burp, code is barely readable
Apologies about that, heres a link to the written version where the code is easy to read in higher res, hope it helps! : yagmanx.medium.com/10-tips-how-to-improve-a-unity-games-performance-to-perfection-noob-friendly-9b906082bf82
Hi, About 4: Optimise Your Models, when you Retopology in blender with the decimate modifier (or any other way like manually or with Add On's that do a really better job like Quad Remesher (payed) or Instant Mesh (free) ) you should bake the texture maps (Color and Normal specially and the others depends on what's available like AO, Cavity, Roughness, Metallic) from the original model to the new one and if both of the models share the same silhouette they will be identical after rendering (in game).
not exactly identical but it does carry over a ton of detail.
What an adorable burp! Loved it!
I love your energy
I needed this
I started watch the video for fix my game but after few moments i found my self just looking at you and forggot the toturial so beautifull 🥺
You can actually hook your scripts into the occlusion events to make them turn off when the object is occluded by the camera, not always practical but when it is it saves immense time and performance. You could attach that to all the interactables in your game for example and the detection code input will only run when the object is being rendered, on top of that you could go a step further even and have entire gameobject turn itself off and on, which means non of those components are taking up performance unless they are being rendered. This will probably give you a good 30 fps if done right. I once made a 2d game in unity that ran at 500fps using optimizations and turning off vsync, obviously not practical but it was mostly to a test for myself to see how optimized I could get something to run. Funny thing was if the game was paused the frame rate counter actually went all the way to infinity.
1:09 The Witcher 3 quest completed! ;)
Currently to disable scripts, I do a sort of ping. It's still physics though. On a long delay, I have it send out a big overlap sphere. That sphere uses a layer mask to only look for stuff on the "player" physics layer. So it is just looking for the only object that exist on that layer. And if its in range, it turns on/off. I use the update method sparingly, so this is mostly just for enemies. I guess this is basically the same thing setting up trigger box does, but it's on an even longer delay than the physics update, so it could be better? And you don't have to set up all of the triggers of course.
You could further improve it by reducing the number of checks. I would move the ping system to its own component and object. You would feed it an array of whatever you want to toggle for the whole room or world chunk. Kind of like setting up Occlusion volumes.
Having the pings come from the player looking for stuff, would be nice. But then you have to start micro managing a list, which is just yucky to me.
You could also just make it check the distance to the player and circumvent the physics system entirely. But 1: I think overlap sphere is actually faster than doing a magnitude check because it won't do a square root function. And 2: This could work with multiple player characters. Even if this isn't a multiplayer game, I might want to control other entities.
I feel like physics is THEE way to do this, don't doubt yourself.
The mesh collider bit is actually so important, it's asked in job interviews. Usually something like which collider is best for performance? It's the box collider.
Honestly I thought this is basic knowledge, how did you not meet with this bit of information?
Great video! Game design is so interesting. Cheers.
Love these types of videoes! 🙏🙏