I added a queues/pools for all my projectiles ... went from 5 FPS to 35 FPS !! It was amazing to see just how many projectiles get spawned in a shooter game :) Now I need to add pools for effects.
@GGFTV4 жыл бұрын
The way I help performance the most with my team that is really easy for the most part is to avoid Update() as much as possible (although you shouldn't completely do away with Update). Instead of checking every frame in Update() if something is done, add a delegate to the end of what you want to check, then use that to see if all your conditions are met. Will save a ton of checks every frame if done well.
@GameOfDead094 жыл бұрын
I agree with you. beginners or amateurs feel they should control everything. That's why they use the constant update function. Whereas, 95% are things that are triggered.
@GGFTV4 жыл бұрын
@@bezoro-personal Yep! I actually just optimized some code for a peer who was had a instance that searches for object of type. But they call that instance 26 times in an update function. That one update took 3ms to run. By just making it find that instance once and assigning it a variable (idk why it even has a findObjectOfType on the instance), the function went down to .1 ms to run. There is still a lot of room for improvement on that script, but man, what a difference
@aronlinde17234 жыл бұрын
First thing I do when I make a new script. Delete the Start and Update block (it's easy to read if I need them, but getting rid of them removes the temptation). Most MB scripts are often data objects for the editor or behavior classes, so they dont need those methods anyways. (Anyone know a way to have good editor friendly data objects that work like MB?)
@GameOfDead094 жыл бұрын
@@aronlinde1723 what exaxtly do you want to do? non MB already data classes. İ'm away from pc and im not sure but you can try "New" keyword with your Non mb script. Maybe u can use scriptableObjects they are data containers
@Paul-to1nb4 жыл бұрын
@@aronlinde1723 FYI - There's a way to make your own script templates so you can just get rid of start/update in your default: kzbin.info/www/bejne/g2TYgoiejNKpfdE As far as editor friendly data objects, you might want to look up how to use ScriptableObjects for data. You may look at Odin inspector/serialization too, (although it's pricy). It lets you serialize anything (although not in prefabs in Unity 2018+)
@CarlosZig4 жыл бұрын
The pooling using Queue is something that i am astonished with. Always had a problem with making a decent enough pooling and just worked without it. But with this? Time to re-learn something! great video as always!
@lemetamax4 жыл бұрын
I can't believe you taught Queues and I understood it in seconds! Every other place I searched made it a little too complicated.
@dmgiacomelli4 жыл бұрын
One thing I usually use to avoid debug logs in the final build is to use the Conditional attribute in a method Log and call it. The Conditional attribute indicates to compilers that a method call or attribute should be ignored unless a specified conditional compilation symbol is defined. [Conditional("DEBUG")] void Log(string msg) => Debug.Log(msg);
@user-ef6tm3ut4r4 жыл бұрын
*please part two*
@sagiziv9274 жыл бұрын
9:11 My quick tip is: When comparing 2 UnityEngine.Object don't use == or != operators because Unity overrides them and uses native code. Compare the HashCode of them, it is only an integers comparison and it is guaranteed to be unique.
@kkrup53954 жыл бұрын
Sounds like a great tip, sir. Do you have more?
@InfohazardGames4 жыл бұрын
Or Object.ReferenceEquals, to allow one or both to be null. Although neither will account for Unity's fake null thing.
@sagiziv9274 жыл бұрын
@@Dfjs427 In Unity, the HashCode is the object's instance id, and it always unique and good for comparison. docs.unity3d.com/ScriptReference/Object.GetInstanceID.html
@johnw31944 жыл бұрын
interesting..
@Tes2T4 жыл бұрын
Welcome back young Jason :) 200 thumbs up for putting timestamps in doobly-doo !
@friendofphi2 жыл бұрын
One thing about deep profile is that it has a big impact on performance so it may give you more details into specific areas that are the problem but isn't a good look at whether you do have any problems.
@UnGaming-eh7ht4 жыл бұрын
This is exactly what I've been looking for, as usual you are the person to come to when stuck.
@petrosaslanidis4 жыл бұрын
Congratulations for 100k and thank you Jason !
@magnusm43 жыл бұрын
My general beginner's list of performance improvements: LOD (Level Of Detail): Not necessary early or even your thing if you don't do modelling but having lower resolution or low poly at greater distances helps a lot in the long run, especially in open worlds. _Occlusion Culling:_ What you don't see is what you don't need. If you have seen the controversial Golden Eye speedrun then he looks down to make the game run faster. Culling renders only what's in front of the camera, anything behind isn't rendered either. There's another simpler version that doesn't take blocking objects into account and do render everything in front of you. But that's situational. _Box grid system:_ Doom, Minecraft and Terraria. Now an implemented feature so you have to make it. But the idea is that only objects within a square in a grid is activated and respond to collision. In Doom firing causes a ray to check what boxes it goes t hrough and those inside can get hit. Same in Terraria and Minecraft. Only you and stuff you fire makes a box active, otherwise lots of stuff runs in the background and just tanks performance. _Coroutines:_ Sadly I haven't implemented any yet. But as the Unity tutorial states. It's a great way to allow functionality without having to run an Update every frame to apply it. It also means much less code in your Update. Like for example a rocket projectile. You don't need an Update or Fixed update to move it, maybe you do if it has a Rigidbody. Haven't seen anything on it or tested, again, haven't tried. But in this case you can simply make it start the coroutine once and it runs by itself until it finishes, you can even set delays in it for, example, cast time. Work well with elevators too or moving platforms. Just make a static IEnumerator function that you give the lerp smooth and positions and it handles the rest. _E = MCsquared not square root:_ It's a simple and common one but use sqrMagnitude instead of Magnitude if you can. For distance with arrays maybe this is impossible but try and do sqrMagnitude as often as you can. It saves in the long run. Just don't ever do GetComponent in Update or FixedUpdate.
@divainsyoutube42544 жыл бұрын
I've been your subscriber for a long time and usually do not post comments on videos, but I never forget to Like! I want to let you know your hard work is appreciated and I thank you for that! It's not taken for granted! Even when I come today with experience, it's always fun to refresh the memory in your videos! I don't know if you'll respond to this or not, but I would love to read how you are lately? How is your work as a member of the Phanteon development team progressing? Wish you all the best!
@vivekgamedev4 жыл бұрын
Thank you sir for so many great tips. Seriously these were actually some awesome tips and with the use of profiler, they became perfect. Lastly, the Camera.main one was my favorite one. I didn't know that and now I know what might be causing me issues in FPS in my current game as I am constantly using it in an update.
@VBFilms4 жыл бұрын
I've been making a building/colony simulation game and been makong quite much of the stuff out from update function. I have a timer that uses events at 0,1 second 0,5s and 1,0s intervals and everything pretty much works around those timeframes.
@DylanBrams4 жыл бұрын
In a production environment you might want to set up your logs to log everything above Debug in priority, leaving in Warnings and Errors. Django manages this very well; once I get towards prod Unity environments I'll look into it with some detail.
@UnitCodesChannel4 жыл бұрын
Amazing tips, however, there is one common and elementary issue I'd like to address as well if I may, which is so basic yet not used effectively, is with collider detection as well: Please use: void OnCollision or OnTriggerEnter/Exit (collider/collision other) { if (other.CompareTag("AssignedTagName") { //do your thing } } _____________________ Use: COMPARETAG("tag") instead of: --------- TAG.EQUALS == "tag" _____________________ void OnCollision or OnTriggerEnter/Exit (collider/collision other) { if (collider.tag.equals == "AssignedTagName") { //do your thing } }
@mpbMKE2 жыл бұрын
Along the same lines, using TryGetComponent() instead of GetComponent() with a null check can also save some bytes of memory on null returns. It's a small thing, but lots of small things can add up!
@Oxmond4 жыл бұрын
Cool! Great performing tips Jason! 👍🤓
@Qmansvendetta14 жыл бұрын
Im in the Alpha stage and this really helps! Thankyou!
@mintydog064 жыл бұрын
Great video, thanks again. I'm going to look at your profile video now. I really want to get the most performance out of my game for a specific level I want to make.
@MohammadFaizanKhanJ4 жыл бұрын
Debug Logging one of the common mistake because it logs the data on a file that cause performance issue. Thanks for sharing how Linq is working.
@DevGods4 жыл бұрын
Congrats on 100k !!
@Faygris4 жыл бұрын
Thank you for another helpful video! In your videos I see you switching between Rider and Visual Studio a lot. Do you often use VS in your daily work or just for the videos?
@Speiger4 жыл бұрын
Tip to Pooling: If you use a pool only store "Finished" systems in there not even actively working ones, for the whole reason, yes the first one could be working but the second one is finished. On top of that a pool should be allowed to discard objects for example: A pool can store 10k particles but you have 1 spike that goes above 10k lets say 15k that means you have 15k particles in your pool while you need on average like only 800-1000 particles. That means there is roughly 15k useless objects in there that you don't need. Now that is something where garbage stays in your ram that you do not use but could be using for other things. Point of pooling is not to catch Every allocation, the point is to catch the 90-95% of allocations that you are using while the spikes get caught but do not leave a mess behind. So if you use on average like 1000 particles maybe with 2000-3000 particles at peak. Make a 3500-5000 instances pool that keeps memory efficient leaves buffers for spikes but if there is something really bad happening it does not leave you with a problem behind. So let a pool destroy items if their desired capacity of "readyToUse" objects is reached.
@HeathClose4 жыл бұрын
so does shutting down the debugger in one script do it for the entire build in xcode for ios? until I went through and removed that from all the scripts I put it in, my print statements weren't showing up in scripts I didn't have it in and I just spent the whole day trying to figure out why I couldn't debug this null exception that is only happening in the xcode build.
@cywizz20064 жыл бұрын
Hey Jason, great tips as usual! Talking about performance...have you been keeping an eye on the unity ecs developments? I saw you had a video a while ago, but do you think it matured a bit since then to warrant a followup video? Would be a great design/architecture video series?
@paulorodriguez62884 жыл бұрын
i just sped up my game fixing an issue on the triggerstay function, and i noticed right away using the profiler. first time using the thing and i'm already hooked
@dspartan0074 жыл бұрын
Excellent tips. I've been struggling with many of this issues at some point.
@Joooooooooooosh2 жыл бұрын
Regarding the LINQ expressions. The fact is, many of those methods will not allocate at all. The one that is giving you trouble there is orderby. Because there is no way to sort without creating a temporary collection to buffer the results. So I definitely would not go so far as to say avoid LINQ in general. In fact, since you're only taking the top result, this could be done without an allocation using MaxBy.
@ChronikSpartan4 жыл бұрын
Really useful mate. One question though, with regards to the GetComponent fix. Is there a solution for when we are trying to find active objects that are constantly changing, like number of people in a gym? Or do we just have to deal with that being in an update method?
@justinwhite27254 жыл бұрын
@7:26 probably the most useful frame in the entire video. Thanks. Though I've found debug logs to be useful even in apk test builds, but you have to know how to access the android logs (which is a huge pain)
@restushlogic57944 жыл бұрын
Love the video, but I'm not sure is correct to use object pooling. 122B is not that much right? Also, when a player exit game, the GC would be cleaned up right? And we don't know how performance improvement when using object pooling.
@canerozdemir41954 жыл бұрын
Don't use GetComponent in a function that is being called on the Update method. It constantly checks if there is a component and you can already receive that component in Start or Awake functions or you can receive those components once and dont call it again and again. Also, you can use TryGetComponent to check if there is a desired component attached to a gameobject. That way, you will be able to stop any crashes that can come up at any moment. Because if the component is not attached to a gameobject, the code execution will be interrupted.
@allaboutpaw93963 жыл бұрын
I like your videos and I learn few things at a time :) Thanks for your contribution. As a suggestion, don't make a huge logo on the top left. Better to be fade in and fade out every min. It's very unpleasant to have my screen covered with a huge logo.
@LogicBlade4 жыл бұрын
Great tips! Thank you!
@techstacker53614 жыл бұрын
Hey Jason, would you use *Unity 2020 1.6 f1* only for prototyping, or is it stable enough for real productions? Should we wait for *2020 LTS* ?
@mpbMKE2 жыл бұрын
In the example of removing Linq from Update(), would running the attendant foreach loop be more performant, or is there a better way to maintain the proximity detection functionality without relying on potentially hazardous loops inside Update()?
@aoiti2 жыл бұрын
Use distanceSqr instead of distance when finding closest or furthest
@agnesecaglio42534 жыл бұрын
wow, you are super clear and it was really helpful, thanks!
@fear-the-phantom Жыл бұрын
Someone else might have said it already, but if I'm not mistaken, calling this.transform is also a GetComponent. The transform is used so much, and it will eat up the performance.
@Unity3dCollege Жыл бұрын
It used to do that, but now transform gets cached
@fear-the-phantom Жыл бұрын
@@Unity3dCollege So you're telling me all the time I put in to cache transform was for nothing? 😂
@MaZyYTube3 жыл бұрын
Linq was really a problem for me when I was doing a multiplay network code. On my console c# it works prefectly but unity had really issues with linq. Max network objects were around 60. Now without Linq (and other optimization) it can hold up 3000 network objects.
@vitormaluco4 жыл бұрын
Hello Jason. I am curious how you do to profile WebGL(web) games. I have looked in the internet and have not found a video showing the process. Also i would like to know if you are aware of any issue between Chrome and WebGL. I have a webgl game that works fine in any browser, except chrome. The frame rates literally go to a crawl on it and i have no freaking idea why.(You can check it looking for "When in doubt... C4" on gamejolt)
@HeathClose4 жыл бұрын
does print carry the same performance hit as debug.log? if you have print all throughout your code, will that trick stop it from spamming like it does debug.log?
@neozoid70093 жыл бұрын
Why you always put underscore to all variable??
@pistoleta4 жыл бұрын
Could you show us how to use threading in a safe way on unity? Im using Tasks and for the moment I got them running but would be cool to see how you approach the problem of doing heavy operations in background.
@quentinjulien76334 жыл бұрын
Hey Jason ! Regarding LINQ, how would you rewrite this code so it doesn't generate garbage ? I use LINQ sometimes to order a list of characters according to their position so I can know their place in a race and I'm not sure what way would be more efficient.
@DoubleBob4 жыл бұрын
About the "#if UNITY_EDITOR": Is it deactivating all logging in all monobehavior or just in the one where it was called? If it's for all, then it should be probably in it's own class. Are there any other things you would put in such kind of class? Could you make a video about it what else you would put in it? e.g. I find it's important to set the localization for float parsing from outside files. Maybe forcing the quality settings (to avoid the low-quality preset from potential previous versions)
@AnunayMintoo4 жыл бұрын
Almost 100k subs niceeee
@tekilla784 жыл бұрын
I think worth to add is about cache transform
@ZaCkOX9004 жыл бұрын
I do everything the video shows but also stopwatch comparison so I know which functions are slower than others. Local rotation vs local euler angles... local euler angles is slower.
@dibbieknight78864 жыл бұрын
That makes sense, local Euler angles has to take a Quaternion and do math on it, then convert the result to the objects local orientation, and doesnt factor in possible Gimbal Lock, so I can see it being a much slower operation, whereas Quaternion is what Unity already reads by default (the Transform inspector, is actually Quaternions thats been simplified and wrapped so its more human readable, which means its slower than just displaying the Quaternion, but also much MUCH more confusing to understand)
@ZaCkOX9004 жыл бұрын
@@dibbieknight7886 Yes, I've known this for some time... thanks for commenting so others can read though.
@johnpekkala69414 жыл бұрын
Ive always thought that since debug messages are only for use in the game engine/editor and not in the finished game they would automatically get disabled on build. Appearently that is not the case. I see here it is very easy to disable them though. I always remove all debug code before a finished build anyway because it is just unnecesary to have in there then. However for larger projects with LOTS of code that might be lots of work also. Garbage collection is handy and indeed manual memory management like in C++ is very difficult but I wish there was a way for a programmer to have some control of when it is activated to not have it go off in performance critical situations like a semi manual control. The main reasons garbage collected languages have a bad rep performance wise compared to C++ is that it activates randomly whenever the CPU think it is time to free up memory regardless if it is in a critical moment of the game or not. The programmer have no control at all over the GC. There should be some command telling the GC to wait. Something like: GC.wait; Performance critical code; GC.run / GC.resume;
@invertexyz4 жыл бұрын
7:48 Strange that you discuss the LINQ here but completely ignore the even worse operation happening in that code example that is not only generating garbage but taking 0.02ms in your relatively simple scene, which is `FindObjectOfType()`. I would say this is a much more common novice error than LINQ from my interactions with new users over the years. Any time this code is shown in a video, it should be expressed that it should only really be used during level/game load. This method has to search through all the objects in your scene and check if they have that component. So it easily bloats in processing time the larger your scene gets, and then users might have dozens of units using this method to find other units of same type, like your code here could end up doing... Simplest solution for those reading this: Make a `static List listOfThisType;` inside the script of the type you want. Have the script add itself to that list on Awake() and remove from it in OnDestroy(). Now you always have a list of all objects that type, managed by themselves without noticeable overhead (unless you're getting into extreme tens/hundreds of thousands where you'd want to be using entities/jobs instead).
@leandro_damasceno4 жыл бұрын
Very usefull content! Thanks a lot for share :)
@shieldgenerator74 жыл бұрын
why shouldnt you use LINQ and what should you use instead?
@edi_gun_awan3 жыл бұрын
Thank you Sir!
@coryronald67624 жыл бұрын
Thank you for the video Looking forward to "Mad birds" part 2: The "right" way 😀 Almost 100k subs! Woohoo!
@ataulmustafa67744 жыл бұрын
Could you plz make a copy of the croods game i miss it very much plz???
@Dealtloft3 жыл бұрын
Thank you!
@shivsankarbiswas70424 жыл бұрын
is "Queue" similar to "List" ?
@Trynxy4 жыл бұрын
You can say that 'Queue' is a type of 'List', if it's clearer
@williamherring4 жыл бұрын
Imagine being at this mans level. Intentionally adding bugs that we work hours to fix...
@glenncomis22644 жыл бұрын
If you have a bunch of UI and your game is running slow on other devices, make sure to optimize your UI. Canvas redrawing could be a huge pain in the ass performance-wise. For anyone struggling with UI performance, I recommend checking out this video: kzbin.info/www/bejne/lajbmqedmd1gi6s, might be old but the given tips still apply for most UI related stuff.
@hosseinpan13854 жыл бұрын
Unintentional Debug.Logging! (and a trick to disable them) Should we use this in all scripts? or one will do the job for all the scripts?
@frankerzee10954 жыл бұрын
Jason what is your thoughts on null checks? I recently learned that null checks are deceptively slow in Unity because its checks the native object. I sometimes do null checks in an update loop as an early out and did some profiling and saw that it is a bit slow. Using ReferenceEquals seems to be a lot faster but can cause issues cause I believe it just checks the C# object and not the C++ object so it could be viewed as null on the C# side but not yet been cleaned up on the C++ side. I am still pretty confused on this issue. Do you have any experience with this problem or is null checking in an update probably not an issue do you think? Thanks for all the great content too by the way! By far my favorite game dev channel.
@CamoflaugeDinosaue4 жыл бұрын
I could be wrong, but I'm pretty sure a null check is one byte for ref 1, 2 and the check so 3 bytes total. I don't think you ever realistically have any chance of null checks causing performance issues.
@JasonStorey4 жыл бұрын
Null checks are not really a problem by themselves, but like anything can be if abused. In general though there are ways to avoid needing them, usually this is by performing some "defensive programming" e.g if a type is required by a script to run, you can check if it exists, set a boolean flag of "canRun" or similar to false and "fail early" in the start of the awake function and avoid doing any null checks all together. the flag only gets set true when the set function is called and the value is not null. Second, if it is a service and not an object, you can often avoid null checks by using something like a "null object pattern" where you simply provide behaviour.. that does nothing! you heard me right, make a version of the service, e.g a scoreboard, and instead of throwing null with no scoreboard call "saveScore" on a "NoScoreboard" object that does... nothing. it removes any need for null checks around the object, and can be at any time replaced with a functioning implementation and the rest of your code is none-the-wiser. Finally in extreme cases, you can simply have a script disable itself if the pre-requisite requirements are not met, fun fact, unity will do this for you automatically if the awake function throws an exception. In short they are not the end of the world, but they also don't _need_ to be there in most cases. it is less about null being an issue and more about avoiding doing "unnecessary work". If you can take work out of update and have it only happen when it needs to (aka when the object actually changes value) the more performance saving you will make.
@JacobNax4 жыл бұрын
If you are not destroying the actual object and you are using references, the fastest way is to do ReferenceEquals(obj, null) as it will not be overriden to the native call. However, if you are indeed destroying objects or the objects get destroyed after you change the scene due to dependency injection methods, ReferenceEquals might return false because internally, the object reference is still alive in managed code but is destroyed in native code. It's all about how you structure your framework ;p
@ZaCkOX9004 жыл бұрын
Looping with .count I also cache.
@LeoDaRasta4 жыл бұрын
Thank you big homie
@Qbikk4 жыл бұрын
How do u look younger with each video, what sorcery is this o.o
@johnw31944 жыл бұрын
i was about to say the same
@arsenbabaev10224 жыл бұрын
I used camera.main in update accidentally tnx for showing it as an issue
@comikawn51474 жыл бұрын
Hey Can you make serie to make Game look like HOTLINE MIAMI
@StigDesign4 жыл бұрын
15:38 DAMN XD Reminds me of Windows 95 with slow Mouse pointer and Tracer`s activated hehe :)
@beri41384 жыл бұрын
I had no idea that a simple debug.log is this expensive. Wow.
@patrevizani4 жыл бұрын
nice!
@MrRedpearl4 жыл бұрын
Before coding, map out your coding logic based on the needs of the game to help you decide what techniques you need to focus on learning.
The best way to make your code faster is, not writing that code in the first place. Think twice before writing quick but slow code. Even if we would have god's heaven server farm, we would still need to care about speed due to rising fidelity and expectation constraints.
@Dragoncro0wn4 жыл бұрын
make every single function a different script so when you open the proffiler you'll see which functions are slow
@Voidsway4 жыл бұрын
@@Dragoncro0wn I pray this was a joke.... Lol
@rickster52244 жыл бұрын
But where do you define the line between getting a working prototype quickly for proof of concept and scripting everything the most efficient way? Ive found I focus on "just making it work" and then get screwed when it comes time to optimize But then other times I try to avoid the headache of fixing alot of bad code by writing it properly from the start, but then end up loosing interest in the project because it feels as if im barely making progress toward getting something playable.
@Voidsway4 жыл бұрын
@@rickster5224 that's why you write proper code the first time and save the script so you could reuse it some other time. Exactly the same way a "design patterns" are meant to be used. If you're just cranking out code for every little problem you run into, you'll never run out of bugs to fix. If you get ahead of it by creating structure in your workflow, you'll know what bugs youll run into before they happen. Doesn't always work as pretty as that but man did it help me go from never finishing, to finishing what I started.
@GGFTV4 жыл бұрын
@@Voidsway I write a functional version of a prototype feature in a day or two, see if it is good, then if I want to keep it or iterate it, I will spend a week updating the code to be more clean, efficient, and fleshed out. With how many features I end up throwing away, I never write super great code on the first iteration. You should still avoid some obvious issues though.
@ilyabykov24372 жыл бұрын
Lol, the best tip for optimization with C# - disregard most features that C# offers.
@mfatihbarut3 жыл бұрын
unfortunately there is no double like button
@johnw31944 жыл бұрын
unfortunately my only bottleneck..ALWAYS is the graphics :D
@sunilsorahia40804 жыл бұрын
Hey
@pigsinspace99274 жыл бұрын
Google code Ctrl C Ctrl V 1.7 million errors
@natalius4 жыл бұрын
fast
@mohokhachai Жыл бұрын
S
@sunilsorahia40804 жыл бұрын
First
@canaldosoninho4 жыл бұрын
Congrats?
@officialnickname3 жыл бұрын
1) Use Unreal
@GarronArgentina4 жыл бұрын
6 minutes and you say nothing interesting! dislike!
@arkadiusz53874 жыл бұрын
I don't like it. Next video of basics. We have a lot of basics things on youtube.
@afton6444 Жыл бұрын
For me most of the resources are being used by Semaphore.WaitForSignal what should I do
@ToddHarrisonDavis2 жыл бұрын
Great video, awesome for a somewhat noob like myself! Here is some updated code for 2022 #if !(DEVELOPMENT_BUILD || UNITY_EDITOR) Debug.unityLogger.logEnabled = false; #endif