I have a tip too if anyone finds it useful. I recently discovered you can organize your tags by adding a slash so it makes a dropdown menu. For instance I use it to categorize footstep audio in my game. Like you make a tag called "Footsteps/Wood" or "Footsteps/Metal" and in your tag list you see a dropdown menu that you can select from. Of course you can customize your tag list to whatever you want.
Tip Timestamps: Tip 1: 0:00 - Start is IEnumerator(able) Tip 2: 0:36 - See Private Variables in Inspector Tip 3: 1:30 - Time Saver for Adding to Properties in Component without Locking Inspector Tip 4: 2:00 - Show Public Properties in the Inspector Tip 5: 2:44 - HDR Usage with Serizable Fields Tip 6: 3:13 - XML Tag (Comment) Documentation Tip 7: 4:28 - Particle System Time Saver Tip 8: 5:00 - Multiline select in Visual Studio Tip 9: 5:45 - Nullable Types Tip 10: 6:00 - Reset Transform upon Creating Empty Game Object by Default Please edit your video to have these timestamps for others! These are amazing tips that are great, but it's amazing when they're easy to grab for those who have seen your video before and are trying to reference them in the future. Thank you very much for the tips, your videos have been both motivating for me as a hobbiest game developer and very helpful mentally/emotionally.
Thanks! Here are some more / not sure how much "didn't know" category these are though. 1. You can do basic math operations in Inspector fields (+,-,*, /) 2. To remove Unity Objects from Inspector fields, click the field then press backspace. No need to browse that "None" from list. 3. Maybe quite obvious, but when in editor, you can show debug draw stuff in game view, if you press that "Gizmos" button in top right corner of the Game view window. 4. Don't like the fact that viewport selection always opens the object hierarchy? There is a lock in Hierarchy window top right corner which prevents this. 5. You can alt left mouse click to completely open deep hierarchies in Hierarchy window. 6. Using [ContextMenu] Attribute on a method is a easy way to allow calling methods to run editor code, without custom editors. Simply open you MonoBehaviour's Inspector component menu and your method will appear there.
On number 1, you can select multiple objects at once and in transform component use L(min, max) to arrange them in linearly, R(min, max) to arrange them randomly. You can also use sin, cos.. to arrange in sin and cos curves.
9. You shouldn't use null-propagation to check UnityEngine.Object descendants. Engine manages lifecycle of these objects on it's own by overloading '==' and '!=' operators. It results in MonoBehaviour someScriptsInstance; someScriptsInstance?.DoSomething(); and MonoBehaviour someScriptsInstance; if (someScriptsInstance != null) someScriptsInstance?.DoSomething(); To behave differently and can cost you unexpected null-ref exceptions during app runtime. Event in your clip three little dots appeared underneath _shake variable - it's Unity-specific warning from your IDE.
@@LeGlou you can use if (_shape) or if (_shape != null), however I recommend using (_shape != null) as it will be consistent between UnityObject stuff (MonoBehaviour, ScriptableObject, etc) and raw class instances (public class Something { /* ... */ }).
You actually CAN use ?? or ??= if you know what you're doing and understand the object life cycle and interoperation with the native engine components. I do it often in Awake/Start for initialization and assignment of default/null values and ignore the warning because I understood Unity is a native engine with a managed Mono runtime from Day 1. Call it "unfair advantage" but I was a .NET/Mono C# programmer and engine dev for a long time before I gave Unity a fair shake. I shrugged off that warning because I knew what the operators do. I have an example on Github Gists written in C and C# (native C library with managed .NET application) which shows how null-ness and life cycles work. What you're saying is not untrue, I just don't think "never use ??" is necessarily good advice. If you have no clue what I'm talking about then follow the OP's advice, lol. If this makes perfect sense then you are experienced and knowledgeable enough to take your chances 😊
@@GameDevNerd It is not a good way to work though. You might know it but what if project grows and you hire less experienced developers? Its better to have codebase without quirks. Looking at this as "uhm I'm pro and I can use it" is not a good way to build software. Actually, you want to make it as much standarized, bulletproof, newbie-friendly as you can. Otherwise your business will have to jump through hurdles you placed just for sake of placing them.
I didn't know the last one, cool Here are my tips: 1- Don't pass the entire struct as parameter to a method, only pass the individual fields of the struct you'll use. Because the structs are value types, the entire struct must be copied. This gets so slow, if the struct is 40 bytes+ Unity starts copying the struct with string.memcpy instead. If you pass the struct with ref keyword or pass a class, you don't have to worry about this size issue 2- Use namespaces for better management and assembly definitions for faster script compilation after code changes. Disabling domain and scene reloading makes it much faster 3- Seal the classes. Along with a very tiny performance boost(according to Nick Chapsas), it also makes setting Unity messages to protected unnecessary for basic classes(there is a setting in VS tools for Unity that enforces this rule that I enabled) 4- You can split any class to multiple files with the partial keyword. I use this especially for tightly related class and enum/struct/interface pairs. For example, I implement the ISaveData interface of a large class like SkillManager in SkillManager.SaveData.cs. This helps keep the SkillManager clean of any ugly and perhaps complicated interface implementation etc. PS: you can just right click a nested type and move it to its own file 5- You can use asset processors to do arbitrary things to files. For example, if your sprites are all 64 pixels per unit(ppu), instead of selecting every new sprite and setting the ppu you can do it automatically with an asset processor. You can check the assetPath for specificly changing stuff 6- You can use c# extension methods to extend classes! For example to get a random element in an array, a generic extension method works perfectly: public static T GetRandomElement(this T[] array) { return array[Random.Range(0, array.Length)]; } same goes for lists etc. too 7- For 3:55 you can just put the to the end of the line, it is more intuitive imo 8- Keeping a static WaitForEndOfFrame etc. in a static WaitForHelpers.cs class or something helps with memory and instantiation, not that important though 9- You can see a lowered version or assembly version of the code you are writing with sharplab. iirc jetbrains IDE also has an embedded tool for this 10 - Visual studio has an embedded Task List window that shows every comment that starts with TODO. I also type additional info like TODO HOTPATH to filter through them more efficiently and TODO 1 etc. to symbolize their importance/implementation order
for 8, I actually use this singleton class: using System.Threading.Tasks; using System.Collections; using System.Collections.Generic; using UnityEngine; [DisallowMultipleComponent] public class Async : MonoBehaviour { static Async instance; void Awake() { if (instance != null) { Destroy(this); return; } instance = this; } public static Task WaitOneFrame() { var tcs = new TaskCompletionSource(); instance.StartCoroutine(WaitOneFrame(tcs)); return tcs.Task; } static IEnumerator WaitOneFrame(TaskCompletionSource tcs) { yield return null; tcs.SetResult(true); } } this basically allows me to use async await instead of coroutines if I want to. I can create "Update"-like behavior for example by await Async.WaitOneFrame() inside a loop. I'm using this for a turn based game and it's allowing me to do a game loops along the lines of: - get next character - await character action - do something - await delay - repeat I found async/await to result in much cleaner code for a turn-based game than normal unity Update and Coroutines and events for coroutine notifications. Let me know what you think.
@@nourgaser6838 The Task WaitOneFrame seems to have a lot of overhead because it creates a new TaskCompletionSource + starts a coroutine. It essentially does the same "mistake" of instantiating a new WaitForEndOfFrame inside coroutines, just in a different way
Useful tip that uses debug mode in the Inspector. If you want to change the script a component uses but not lose the property values, switch the Inspector to debug mode and drag the new script into the Script field. You can use equations in numeric fields in the Inspector. For example, if you want to add 53.4 to the existing value of 67.8, add "+53.4" to the end of the existing value and press Enter. Unity will evaluate the equation and assign the result to the field.
WOOOO this SHIFT-ALT dual/triple/quadro writing is INSANE. I am using visual studio for 15 years now and i never knew this xD Thanks man, also the other stuff is exciting to me
I have two tips that newer devs may find useful: Tip #1: Add color tinting to Unity when in Play mode so you have a visual indicator whether you're in edit/play mode. Helps to avoid losing changes if you overlooked the fact you are still in play mode (changes aren't saved in runtime...for the most part). Preferences -> Colors -> "Playmode tint" and change it to something that pops (I use green) Tip #2: Instead of moving your mouse all the way to the edge of the screen to disable/enable gameobjects using the checkbox, you can bind it to something like the tilde key for quick access. Edit -> Shortcuts -> look for "Toggle Active State" and change it to whatever works best for you.
I have another tip. At first when I tried making games. I didn't understand how people make realistic graphics but then I realized that all you have to do is make an object in blender, UV Map it, then create a texture in photoshop (I personally use Aseprite for some reason), then create a normal map, and a reflection map (a black and white UV map that lays out which areas are reflective and which aren't, black is reflective and white is not) and then add all of those things to every single object you make. Normal maps are the key thing to making realistic graphics, then add reflection probes around your game, then you can add a custom skybox that's just all white, also set the camera background mode to "Solid Color" and then make the color the same color as the fog, then add a global volume and add post processing, add the following things, Bloom, Motion Blur (set the quality to high and the amount to about 25%, then I forgot what this part is called but there should be a post processing effect called something like Tone Filtering or something and it should have none, AES, and Natural, set it to AES and what that does is makes darker areas darker, you can also add the one called Shadows, Midtones, and Highlights, then change the shadows color to a darker black color, also add a lot of lights around your areas to interact with the normal maps, then go to the lighting settings and change the shadow color from a grayish blue to a regular gray. And last but not least, a personal favorite of mine is to go back to post processing and add Depth of Field to your game and make it so everything is clear but if something gets to close to the camera, it will become blurry, this hides that ugly thing that happens when you get to close to an object and you can see the individual polygons, it breaks the immersion and also it makes your game look more realistic because in real life, if you look past something close to you, the close thing becomes blurry
It's so nice to see other people using the same tricks, some were new and some were known. I was especially surprised how you made it look that it was common knowledge to lock inspector and mass select objects to add in array, I learned it wayyy late Edit : Yooo that ? thing to check for not null is craaazyy. Quality content
I already mentioned this in a comment myself but be cautious with the ? operator since this is not checking for object destruction. The == operator on unity gameobjects is overloaded to account for this but ? will not return on destroyed gameobjects and therefore throw a null ref exception.
I come into almost every single "Unity tips" video extremely skeptical because rarely is there something useful and not already common knowledge. This video though was filled with stuff I didn't know! Great work!
I recommand you to keep an eye on the commentary section, people often share their tips here and I generally learn A LOT more from comments than the video itself :)
There are some extremely helpful tips I actually didn't know! BUT!!! Tip 9 might be a dangerous one since for Unity this tip is just partially true! When you use the ? operator you are checking if the value is actually null. But Unity is handling object destruction differently. The references to the object will not get null. Therefore the ? operator will let the function be called. The == operator on the other hand is overloaded and will check this behaviour!
I would add one more I'm always using when prototyping or testing, etc Go to Project Settings -> Editor -> Enter Play Mode Options and uncheck Reload Domain Thanks to this your scene will start in milliseconds after you press the Play button :)
#10 is so amazing ... i don't understand why not a single tutorial that covers multiple lessons (that i've seen) doesn't even mention this at the start since they all "reset transform" like 20 times through the course. also the fact this isn't set to Default by unity also baffles me.
Once again, this has to do with Unity's == null overload which returns null when the C++ side has been disposed. The new-ish syntax like .? and "is not null" is not safe to use on Unity objects (like scripts and components), but is perfectly fine on non-UnityEngine.Object C# classes (like events).
I have a tip that has to do with textures and normal maps. If your to lazy to make a Normal Map for something, you can take the texture for that object and duplicate it, then take the new texture and set the "type" to normal map, it will then change the texture into a normal map and if you add that normal map to the material with the texture that your using, the normal map will line up with the texture and it sometimes ends up looking good and working, like with dirt or scratches, you can also go to the normal map and then the inspector and check the box that says "grayscale" and what that is for is if you want to import a normal map where white is flat and black is stuff that goes in, like for bumps and screws and stuff, you can do this to any normal map and it will add extra details and stuff and often looks really cool, like it makes the object look like metal stained glass. I recommend everyone try this with your normal maps
If you're using inheritance and the class doesn't get properly serialized in the inspector (only shows fields in the parent class) you can add [SerializeReference] and the object will show the correct fields of the real object asssigned even if its declared as its parent. This works even in lists with different types of objects assigned as their common parent class.
For Tip 9 - Using the null condition operators (?.) like in _shake?.CameraShake(1f, true); and the null coalescing operators (??) Do keep in mind that Unity has custom overloaded null checks because each object has a C++ engine part and a C# scripting part. So some C# objects that are not null are considered as null since their C++ part has been freed/destroyed but the C# part has not yet been garbage collected. The null conditional (?.) and coalescing operators don't utilize that overload and will produce different results. There's a defined Unity warning in Visual Studio for these specific cases. We are advised to use obj == null and obj != null in the documentation I believe.
When i saw 6:08 , I yelled, " Thank you ! finally someone teaches me how to do that! " I never understood that why Unity doesn't settings Origin for default.
I had no idea about the property popout window, that will be a big time saver. I use the coroutine start function now and again but as another tip, you can also make those methods virtual and override them in child classes.
Be REALLY careful (read: don't use) when using null propagation with Unity objects as they overload the == and != operators, so it may result in undesired behavior.
@@FunFindsYT It means that they changed how they work. Checking a Unity object (any class that inherits from UnityEngine.Object) for null with "object == null" does return true if the object has been unloaded by calling Destroy() or by changing scene, even though it's not actually null and the C# property might still point to an object in memory. But there is no way to do the same with an operator like ??=, so when using that it might tell you that an object is not null even after it has been destroyed and will be garbage collected in the future, so you might keep a reference to an invalid object without knowing it.
this has nothing to do with the video, but the one part reminded me... I made an IDamageable script that isn't an interface... because I didn't know what that was. I thought the "I" part was like an IPod "I'm damageable". That's all. This has been your AIA dev fail of the day.
This was a fun video. Fun fact! I ONLY knew about serialising properties! All the tutorials I followed used it, so this was kind of a reverse tip haha!
Great tips Brandon. I should mention though that you be careful using null interpolation with monobeahviors. The IDE will most likely warn you that it bypasses the Unity lifetime check. For monobehaviors you should still use an if but don't compare it to null. It will evaluate to false if it's been destroyed. For example: if (audioManager) audioManager.PlayClip(clip);
For a little more background on that, anything that inherits from UnityEngine.Object may not be null even though it's destroyed, or rather the managed portion of the object may be non-null but the native equivalent may be. So Unity addressed this by overloading the equality/inequality operations and will cast it to a bool. So an object that's in the process of being destroyed would return false where comparing to null would fail.
4:20 theres a way I hide all the summary info from cluttering the codebase. Instead of putting the summaries inline with the implemented functions, I have those fucntions be part of an interface and i write the summaries in the interface files instead. so in a sense my interface files become my documentation for these methods and properties. explaining how each method is intended to be used while not getting into the implementation details. makes it useful for both sides of the interface. while any comments in the implementing files focus more on the internal details. also saves me time since I only need to write a summary for the interface and not duplicate summaries for every class implementing the exact same method signatures Another tip (which is just more general C# programming) in the implemented classes I write I group all code by the types of classes which would interact with this one in regions (so one region for all unity messages, each interface get a region, a region for all the private methods, etc.) it helps me organize my code and keeps me in the mindset of how coupled/cohesive my classes become. so if I have a region of just public fields/properties/methods thats not tied to an interface, I know this is the part of the class that could be expensive to maintain later based on how many different things try to use it. and it also helps me see how easy it would be to migrate the code (if say it doesn't have a "unity" region then I know I can move it form being a monobehaviour to a simple C# class rather painlessly).
Useful tips! Some of them are general programming/IDE tips, but useful nonetheless. One about extended ColorPicker is a really good one. I'm currently working on a turnbased game on hexgrid. I've tried following an A* tutorial (regular square grid), but it's not going great. Learned from my mistake I'd advise to: create debugging only code(meaning not for released game) that shows all the background calculations in game world. That saved me a lot of headaches.
I love the fact you can make public properties appear in the inspector, the only catch is that (at least as far as I'm aware) you can't edit the look of them in your editor scripts as FindProperty and FindPropertyRelative will just return null. This may have changed, but idk
A little warning here: The ?.MethodName() thing is called "null conditional operator" and both the "null conditional operator" and the "null coalescing operator" ( the ?? thing ) should NOT be used on classes that are derived from Unity game object. Unity overloads the null operator == with custom code to return null when the dotnet managed type is not yet null, but the underlying unmanaged type already is. The override does not work with ? and ?? operators, so using them on Unity objects can lead to calls to instances that are already disposed. The visual studio code analyzer for Unity has an extra warning for that because it is a common error.
@@sealsharp Oh I didn't understand half of your warning because I learned programming only on Unity therefore my knowledge is limited on programming terms. What I understand is that it's better to use "==" than "?" while null checking? One more thing, do these extra calls occur only for methods or both methods and variables? For example: something?.SetActive(true);
Double hit ctrl R in your code on a variable to rename it. The new variable name is applied to everwhere this variable exists. Anywhere in your project. Any script. But ignores variables that happen to have the same name but are declared in a different class.
I have another tip, unlike on PC, the default framerate for phones is 30 FPS, so if you make a game, make sure you have a script that says On Start, set Application Target Frame Rate = 120 FPS or you can do 60 FPS but newer iPhones have 120 Hz screens and all other phones have 60
Or maybe what would be useful (which is beyond my current ability) would be to have all your descriptions within their own file, and have them assigned to functions in other scripts.
Awesome tips. Very exotic ones too, nice finds and thanks for sharing. The new object at origin setting one is a god send! Why is that not the default?! Regarding no. 7. Do you know if using that method breaks batching or does it use the same material across systems given the same sprite?
4:18 - One way that i know of to (kind of) hide the summary comments is to write them in an interface. This also helps when you go to write the implementation for the method or property, you can hover on the name and see the description of what the method does. also in visual studio you can hide the summary by pressing the [ - ] button in line with the beginning of the summary and it only occupies one line on screen and only shows the description (you don't need to put a #region around it). other tips for summary comments: for new lines you don't need to start the line with only end it with also you can use tags like or to add references to other classes or keywords (like int, float, etc.). it colors them differently in the text and makes them easier to read. learn.microsoft.com/en-us/dotnet/csharp/language-reference/xmldoc/recommended-tags ^ here's the documentation for writing documentation comments ^
Will using a single material (with multiple different sprites) for multiple particles reduce draw calls? I was so excited to try this that I forget to check the stats before I started.
What about extensions for stupid things, like image.SetSprite(Sprite sprite) that will check if (image) exists before signing. Same with TMP_Text. SetText(string text). Or simplify Mathf usage by extending float with some of its methods, like Abs, so someFloatValue.Abs() is way more readable and easier to type.
the problem with [fiel: seriaized... is that if you already have a public variable you've used a whole bunch and want to make it private get; while keeping it in the inspector you are going to have to fill all the values again in all the prefabs and objects you had. hope you got source control, otherwise you are going to have to balance the game again. that being said, its great. Anyone know a solution for this?
5:50 this is again a C# feature that Unity does not support. It is strongly advised by Unity to use default null checks because comparison operator is overloaded by Unity. If you use a question mark there are cases when it works and not, basically Unity doesn't support nullable types and you should avoid it To sum up, it is NOT THE SAME. Notice you have != in orange color, not gray
Don't you have a separate keyboard for each hand? Saves much time. The only problem is that in winter you have to take your socks off to operate the two mouses and your feet get cold.
After coding so much and googling so much I still don't know what Return null; or return 0 means😅 For some reasons people in tutorials use it but when I think and code with my own implementation I don't need a return
Do NOT use the ?. or ?? or ??= operators with Unity objects or component references. The Unity integration with Visual Studio even warns against this. Unity overrides the ==, != operators and the Equals method to support the C++ native object being destroyed before the C# wrapper is destroyed, but the null propagation and coalescing operators are at the compiler level and therefore have no knowledge of the C++ native object being destroyed first. So you may still end up calling a method or property on a C# object that has had the C++ native part already destroyed. That is bad. If you want to save a few characters, just drop the "== null" in the if condition. Unity also overrides the bool operator to return true if the object is still valid but not necessarily null.
I have a tip too if anyone finds it useful. I recently discovered you can organize your tags by adding a slash so it makes a dropdown menu. For instance I use it to categorize footstep audio in my game. Like you make a tag called "Footsteps/Wood" or "Footsteps/Metal" and in your tag list you see a dropdown menu that you can select from. Of course you can customize your tag list to whatever you want.
It's not a good idea to have that many tags though
Tip Timestamps:
Tip 1: 0:00 - Start is IEnumerator(able)
Tip 2: 0:36 - See Private Variables in Inspector
Tip 3: 1:30 - Time Saver for Adding to Properties in Component without Locking Inspector
Tip 4: 2:00 - Show Public Properties in the Inspector
Tip 5: 2:44 - HDR Usage with Serizable Fields
Tip 6: 3:13 - XML Tag (Comment) Documentation
Tip 7: 4:28 - Particle System Time Saver
Tip 8: 5:00 - Multiline select in Visual Studio
Tip 9: 5:45 - Nullable Types
Tip 10: 6:00 - Reset Transform upon Creating Empty Game Object by Default
Please edit your video to have these timestamps for others! These are amazing tips that are great, but it's amazing when they're easy to grab for those who have seen your video before and are trying to reference them in the future. Thank you very much for the tips, your videos have been both motivating for me as a hobbiest game developer and very helpful mentally/emotionally.
Te amo persona desconocida que enumera las cosas.
Thanks! Here are some more / not sure how much "didn't know" category these are though.
1. You can do basic math operations in Inspector fields (+,-,*, /)
2. To remove Unity Objects from Inspector fields, click the field then press backspace. No need to browse that "None" from list.
3. Maybe quite obvious, but when in editor, you can show debug draw stuff in game view, if you press that "Gizmos" button in top right corner of the Game view window.
4. Don't like the fact that viewport selection always opens the object hierarchy? There is a lock in Hierarchy window top right corner which prevents this.
5. You can alt left mouse click to completely open deep hierarchies in Hierarchy window.
6. Using [ContextMenu] Attribute on a method is a easy way to allow calling methods to run editor code, without custom editors. Simply open you MonoBehaviour's Inspector component menu and your method will appear there.
I didn't know about #2 or 6 actually, thanks so much!
On number 1, you can do much more than that. ua-cam.com/video/OQ7DfUrZT94/v-deo.htmlsi=cZ4Ip4swb_KDF-a3
On number 1, you can select multiple objects at once and in transform component use L(min, max) to arrange them in linearly, R(min, max) to arrange them randomly. You can also use sin, cos.. to arrange in sin and cos curves.
You can collapse the function comment without encapsulating them in a region.
Ctrl + M, A = Collapse All
Ctrl + M, O = Collapse to Blocks
This video is actually huge, lots of actually useful tips I didn't know even after half a decade of using Unity. Great stuff!
9. You shouldn't use null-propagation to check UnityEngine.Object descendants. Engine manages lifecycle of these objects on it's own by overloading '==' and '!=' operators. It results in
MonoBehaviour someScriptsInstance;
someScriptsInstance?.DoSomething();
and
MonoBehaviour someScriptsInstance;
if (someScriptsInstance != null)
someScriptsInstance?.DoSomething();
To behave differently and can cost you unexpected null-ref exceptions during app runtime.
Event in your clip three little dots appeared underneath _shake variable - it's Unity-specific warning from your IDE.
Which one we should use?
@@LeGlou you can use if (_shape) or if (_shape != null), however I recommend using (_shape != null) as it will be consistent between UnityObject stuff (MonoBehaviour, ScriptableObject, etc) and raw class instances (public class Something { /* ... */ }).
Absolutely correct! Don't use null propagation or null coalescing.
You actually CAN use ?? or ??= if you know what you're doing and understand the object life cycle and interoperation with the native engine components. I do it often in Awake/Start for initialization and assignment of default/null values and ignore the warning because I understood Unity is a native engine with a managed Mono runtime from Day 1. Call it "unfair advantage" but I was a .NET/Mono C# programmer and engine dev for a long time before I gave Unity a fair shake. I shrugged off that warning because I knew what the operators do. I have an example on Github Gists written in C and C# (native C library with managed .NET application) which shows how null-ness and life cycles work. What you're saying is not untrue, I just don't think "never use ??" is necessarily good advice. If you have no clue what I'm talking about then follow the OP's advice, lol. If this makes perfect sense then you are experienced and knowledgeable enough to take your chances 😊
@@GameDevNerd It is not a good way to work though. You might know it but what if project grows and you hire less experienced developers? Its better to have codebase without quirks. Looking at this as "uhm I'm pro and I can use it" is not a good way to build software. Actually, you want to make it as much standarized, bulletproof, newbie-friendly as you can. Otherwise your business will have to jump through hurdles you placed just for sake of placing them.
I didn't know the last one, cool
Here are my tips:
1- Don't pass the entire struct as parameter to a method, only pass the individual fields of the struct you'll use. Because the structs are value types, the entire struct must be copied. This gets so slow, if the struct is 40 bytes+ Unity starts copying the struct with string.memcpy instead. If you pass the struct with ref keyword or pass a class, you don't have to worry about this size issue
2- Use namespaces for better management and assembly definitions for faster script compilation after code changes. Disabling domain and scene reloading makes it much faster
3- Seal the classes. Along with a very tiny performance boost(according to Nick Chapsas), it also makes setting Unity messages to protected unnecessary for basic classes(there is a setting in VS tools for Unity that enforces this rule that I enabled)
4- You can split any class to multiple files with the partial keyword. I use this especially for tightly related class and enum/struct/interface pairs. For example, I implement the ISaveData interface of a large class like SkillManager in SkillManager.SaveData.cs. This helps keep the SkillManager clean of any ugly and perhaps complicated interface implementation etc. PS: you can just right click a nested type and move it to its own file
5- You can use asset processors to do arbitrary things to files. For example, if your sprites are all 64 pixels per unit(ppu), instead of selecting every new sprite and setting the ppu you can do it automatically with an asset processor. You can check the assetPath for specificly changing stuff
6- You can use c# extension methods to extend classes! For example to get a random element in an array, a generic extension method works perfectly:
public static T GetRandomElement(this T[] array)
{
return array[Random.Range(0, array.Length)];
}
same goes for lists etc. too
7- For 3:55 you can just put the to the end of the line, it is more intuitive imo
8- Keeping a static WaitForEndOfFrame etc. in a static WaitForHelpers.cs class or something helps with memory and instantiation, not that important though
9- You can see a lowered version or assembly version of the code you are writing with sharplab. iirc jetbrains IDE also has an embedded tool for this
10 - Visual studio has an embedded Task List window that shows every comment that starts with TODO. I also type additional info like TODO HOTPATH to filter through them more efficiently and TODO 1 etc. to symbolize their importance/implementation order
Combination: a preprocessor #5 can be used to apply "sealed"🦭 #3 to newly created classes.
@@sealsharp Yeah but you are better off editing the default script template for Unity and default class template for Visual studio
for 8, I actually use this singleton class:
using System.Threading.Tasks;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
[DisallowMultipleComponent]
public class Async : MonoBehaviour
{
static Async instance;
void Awake() {
if (instance != null) {
Destroy(this);
return;
}
instance = this;
}
public static Task WaitOneFrame()
{
var tcs = new TaskCompletionSource();
instance.StartCoroutine(WaitOneFrame(tcs));
return tcs.Task;
}
static IEnumerator WaitOneFrame(TaskCompletionSource tcs)
{
yield return null;
tcs.SetResult(true);
}
}
this basically allows me to use async await instead of coroutines if I want to. I can create "Update"-like behavior for example by await Async.WaitOneFrame() inside a loop.
I'm using this for a turn based game and it's allowing me to do a game loops along the lines of:
- get next character
- await character action
- do something
- await delay
- repeat
I found async/await to result in much cleaner code for a turn-based game than normal unity Update and Coroutines and events for coroutine notifications. Let me know what you think.
@@nourgaser6838 The Task WaitOneFrame seems to have a lot of overhead because it creates a new TaskCompletionSource + starts a coroutine. It essentially does the same "mistake" of instantiating a new WaitForEndOfFrame inside coroutines, just in a different way
Useful tip that uses debug mode in the Inspector. If you want to change the script a component uses but not lose the property values, switch the Inspector to debug mode and drag the new script into the Script field.
You can use equations in numeric fields in the Inspector. For example, if you want to add 53.4 to the existing value of 67.8, add "+53.4" to the end of the existing value and press Enter. Unity will evaluate the equation and assign the result to the field.
WOOOO this SHIFT-ALT dual/triple/quadro writing is INSANE. I am using visual studio for 15 years now and i never knew this xD
Thanks man, also the other stuff is exciting to me
Ctrl+R+R is my favorite, allows you to globaly refactor a variable
I have two tips that newer devs may find useful:
Tip #1: Add color tinting to Unity when in Play mode so you have a visual indicator whether you're in edit/play mode. Helps to avoid losing changes if you overlooked the fact you are still in play mode (changes aren't saved in runtime...for the most part). Preferences -> Colors -> "Playmode tint" and change it to something that pops (I use green)
Tip #2: Instead of moving your mouse all the way to the edge of the screen to disable/enable gameobjects using the checkbox, you can bind it to something like the tilde key for quick access. Edit -> Shortcuts -> look for "Toggle Active State" and change it to whatever works best for you.
Those are grest, thank you!
I have another tip. At first when I tried making games. I didn't understand how people make realistic graphics but then I realized that all you have to do is make an object in blender, UV Map it, then create a texture in photoshop (I personally use Aseprite for some reason), then create a normal map, and a reflection map (a black and white UV map that lays out which areas are reflective and which aren't, black is reflective and white is not) and then add all of those things to every single object you make. Normal maps are the key thing to making realistic graphics, then add reflection probes around your game, then you can add a custom skybox that's just all white, also set the camera background mode to "Solid Color" and then make the color the same color as the fog, then add a global volume and add post processing, add the following things, Bloom, Motion Blur (set the quality to high and the amount to about 25%, then I forgot what this part is called but there should be a post processing effect called something like Tone Filtering or something and it should have none, AES, and Natural, set it to AES and what that does is makes darker areas darker, you can also add the one called Shadows, Midtones, and Highlights, then change the shadows color to a darker black color, also add a lot of lights around your areas to interact with the normal maps, then go to the lighting settings and change the shadow color from a grayish blue to a regular gray. And last but not least, a personal favorite of mine is to go back to post processing and add Depth of Field to your game and make it so everything is clear but if something gets to close to the camera, it will become blurry, this hides that ugly thing that happens when you get to close to an object and you can see the individual polygons, it breaks the immersion and also it makes your game look more realistic because in real life, if you look past something close to you, the close thing becomes blurry
It's so nice to see other people using the same tricks, some were new and some were known. I was especially surprised how you made it look that it was common knowledge to lock inspector and mass select objects to add in array, I learned it wayyy late
Edit : Yooo that ? thing to check for not null is craaazyy. Quality content
I already mentioned this in a comment myself but be cautious with the ? operator since this is not checking for object destruction. The == operator on unity gameobjects is overloaded to account for this but ? will not return on destroyed gameobjects and therefore throw a null ref exception.
Um... If the null-conditional and null-coalescing operators are really crazy stuff for you you better learn c# before you keep coding.
@@WurstOnAir yes it also warns you that ? should not be used on unity objects
@@mad_t I AM learning C#, this is how I learn
Yes ? Operator was good
I come into almost every single "Unity tips" video extremely skeptical because rarely is there something useful and not already common knowledge. This video though was filled with stuff I didn't know! Great work!
I recommand you to keep an eye on the commentary section, people often share their tips here and I generally learn A LOT more from comments than the video itself :)
There are some extremely helpful tips I actually didn't know!
BUT!!!
Tip 9 might be a dangerous one since for Unity this tip is just partially true!
When you use the ? operator you are checking if the value is actually null. But Unity is handling object destruction differently. The references to the object will not get null. Therefore the ? operator will let the function be called. The == operator on the other hand is overloaded and will check this behaviour!
I would add one more I'm always using when prototyping or testing, etc
Go to Project Settings -> Editor -> Enter Play Mode Options and uncheck Reload Domain
Thanks to this your scene will start in milliseconds after you press the Play button :)
Did you know that there is [-] thing on the left when you create a summary?
You can click it to simply wrap the summary.
Favorite one, surprisingly, was creating objects at the world origin. I hate empty game managers at some random 4.2434, 234.2, 123.1 position!
#10 is so amazing ... i don't understand why not a single tutorial that covers multiple lessons (that i've seen) doesn't even mention this at the start since they all "reset transform" like 20 times through the course. also the fact this isn't set to Default by unity also baffles me.
Careful with the '?' operator. That bypasses the lifetime check on monobehaviors. You should actually get a warning for that either in VS or Unity
Once again, this has to do with Unity's == null overload which returns null when the C++ side has been disposed.
The new-ish syntax like .? and "is not null" is not safe to use on Unity objects (like scripts and components), but is perfectly fine on non-UnityEngine.Object C# classes (like events).
I have a tip that has to do with textures and normal maps. If your to lazy to make a Normal Map for something, you can take the texture for that object and duplicate it, then take the new texture and set the "type" to normal map, it will then change the texture into a normal map and if you add that normal map to the material with the texture that your using, the normal map will line up with the texture and it sometimes ends up looking good and working, like with dirt or scratches, you can also go to the normal map and then the inspector and check the box that says "grayscale" and what that is for is if you want to import a normal map where white is flat and black is stuff that goes in, like for bumps and screws and stuff, you can do this to any normal map and it will add extra details and stuff and often looks really cool, like it makes the object look like metal stained glass. I recommend everyone try this with your normal maps
I never expected to learn this much about unity
Great video. I find that it's short & sweet stuff like this that is far more useful than any long tutorial
If you're using inheritance and the class doesn't get properly serialized in the inspector (only shows fields in the parent class) you can add [SerializeReference] and the object will show the correct fields of the real object asssigned even if its declared as its parent. This works even in lists with different types of objects assigned as their common parent class.
For Tip 9 - Using the null condition operators (?.) like in _shake?.CameraShake(1f, true); and the null coalescing operators (??)
Do keep in mind that Unity has custom overloaded null checks because each object has a C++ engine part and a C# scripting part. So some C# objects that are not null are considered as null since their C++ part has been freed/destroyed but the C# part has not yet been garbage collected. The null conditional (?.) and coalescing operators don't utilize that overload and will produce different results. There's a defined Unity warning in Visual Studio for these specific cases. We are advised to use obj == null and obj != null in the documentation I believe.
When i saw 6:08 , I yelled, " Thank you ! finally someone teaches me how to do that! "
I never understood that why Unity doesn't settings Origin for default.
Because sometimes you want newly created game objects to be placed at wherever you're looking at.
I’m proud to say I discovered most of these for myself, but there was still a lot of useful new information in here!
I had no idea about the property popout window, that will be a big time saver. I use the coroutine start function now and again but as another tip, you can also make those methods virtual and override them in child classes.
Mind blown after the first tip. I think I could have used this a billion times.
Another Unity tip is you can ask for a publisher and fund your game. Actually, that's not an Unity tip, is a tip for you. Good video as always, btw
Be REALLY careful (read: don't use) when using null propagation with Unity objects as they overload the == and != operators, so it may result in undesired behavior.
What does it mean that they overload the operators?😊
@@FunFindsYT It means that they changed how they work. Checking a Unity object (any class that inherits from UnityEngine.Object) for null with "object == null" does return true if the object has been unloaded by calling Destroy() or by changing scene, even though it's not actually null and the C# property might still point to an object in memory. But there is no way to do the same with an operator like ??=, so when using that it might tell you that an object is not null even after it has been destroyed and will be garbage collected in the future, so you might keep a reference to an invalid object without knowing it.
What does null propagation mean? The ‘?’ for null checks?
@@jumpkut Yes! Null propagation is the ?. null check. And the same applies to null coalescing operators, that is ?? and ??=
The question mark one I didn't know, omg, it saves quite a lot of characters
this has nothing to do with the video, but the one part reminded me...
I made an IDamageable script that isn't an interface... because I didn't know what that was. I thought the "I" part was like an IPod "I'm damageable".
That's all.
This has been your AIA dev fail of the day.
Lol!! That's amazing.
IXable is a practice in csharp I believe to devote interfaces. Other languages just use Xable for their convention.
Thanks a lot for providing these tips,
5th tip is very helpful, I was stuck in the problem that you solved
👌👌
I really liked you tip #8, it was completely new to me. Thanks.
Properties in Component without Locking Inspector really going to help me out
Super useful video for me, thanks for making it. In the future, I would like to see more content like this.
the public properties tip & Multiline select tip is useful for me :D
What i can say, We learn as long as we live. Great video,thanks for sharing
He doesnt stop !! Great vid yet again
Really great video! Best tips for unity video I have seen ❤
This was a fun video.
Fun fact! I ONLY knew about serialising properties! All the tutorials I followed used it, so this was kind of a reverse tip haha!
Wow!! the "create objects on origin" is awesome :D
Those were some solid tips, noted! thank you!
These tips are ALL very useful! Thanks a lot!
Great tips Brandon. I should mention though that you be careful using null interpolation with monobeahviors. The IDE will most likely warn you that it bypasses the Unity lifetime check. For monobehaviors you should still use an if but don't compare it to null. It will evaluate to false if it's been destroyed. For example: if (audioManager) audioManager.PlayClip(clip);
For a little more background on that, anything that inherits from UnityEngine.Object may not be null even though it's destroyed, or rather the managed portion of the object may be non-null but the native equivalent may be. So Unity addressed this by overloading the equality/inequality operations and will cast it to a bool. So an object that's in the process of being destroyed would return false where comparing to null would fail.
Favorite VS shortcut: Alt+Up/Down arrow keys to move a line of code.
4:20 theres a way I hide all the summary info from cluttering the codebase. Instead of putting the summaries inline with the implemented functions, I have those fucntions be part of an interface and i write the summaries in the interface files instead.
so in a sense my interface files become my documentation for these methods and properties. explaining how each method is intended to be used while not getting into the implementation details. makes it useful for both sides of the interface. while any comments in the implementing files focus more on the internal details. also saves me time since I only need to write a summary for the interface and not duplicate summaries for every class implementing the exact same method signatures
Another tip (which is just more general C# programming) in the implemented classes I write I group all code by the types of classes which would interact with this one in regions (so one region for all unity messages, each interface get a region, a region for all the private methods, etc.) it helps me organize my code and keeps me in the mindset of how coupled/cohesive my classes become. so if I have a region of just public fields/properties/methods thats not tied to an interface, I know this is the part of the class that could be expensive to maintain later based on how many different things try to use it. and it also helps me see how easy it would be to migrate the code (if say it doesn't have a "unity" region then I know I can move it form being a monobehaviour to a simple C# class rather painlessly).
Useful tips! Some of them are general programming/IDE tips, but useful nonetheless. One about extended ColorPicker is a really good one.
I'm currently working on a turnbased game on hexgrid. I've tried following an A* tutorial (regular square grid), but it's not going great. Learned from my mistake I'd advise to: create debugging only code(meaning not for released game) that shows all the background calculations in game world. That saved me a lot of headaches.
I love the fact you can make public properties appear in the inspector, the only catch is that (at least as far as I'm aware) you can't edit the look of them in your editor scripts as FindProperty and FindPropertyRelative will just return null. This may have changed, but idk
Loved that last tip!!!
In Visual Studio I use Ctrl+R+R to rename variables in the entire project at the same time
Thanks for them tips, you learn everyday
I used Awake and it's clutch af sometimes instead of start
OMG, number 10 is so clutch!!! so sick of the inconsistency of when it does and doesnt create at origin
Wow, I only knew two of those! This is going to save me a lot of time!
I didn't know that question mark was used for null checks. Thanks for the helpful insights.
A little warning here:
The ?.MethodName() thing is called "null conditional operator" and both the "null conditional operator" and the "null coalescing operator" ( the ?? thing ) should NOT be used on classes that are derived from Unity game object. Unity overloads the null operator == with custom code to return null when the dotnet managed type is not yet null, but the underlying unmanaged type already is. The override does not work with ? and ?? operators, so using them on Unity objects can lead to calls to instances that are already disposed.
The visual studio code analyzer for Unity has an extra warning for that because it is a common error.
@@sealsharp Oh I didn't understand half of your warning because I learned programming only on Unity therefore my knowledge is limited on programming terms. What I understand is that it's better to use "==" than "?" while null checking? One more thing, do these extra calls occur only for methods or both methods and variables? For example: something?.SetActive(true);
@@sealsharp You just solved my mystery null reference exception that would only occur every so often and drove me crazy!
@@ozgurgurbuz just use == when you're checking if a unity object is null.
@@Airelon sweet!
Thanks for the last tip, I literally said "mother******" out loud after seeing that lol
For the tip at 4:24, you can "completely" hide it if the comment is in the interface instead of the actual implementation
Very Useful, thanks for sharing!
an extra tip for the XML Tag (Comment) Documentation. Visual Studio 2022 can hide the comment section out of the box (without region or anything)
Thank you. This is a great time saver!
Double hit ctrl R in your code on a variable to rename it. The new variable name is applied to everwhere this variable exists. Anywhere in your project. Any script.
But ignores variables that happen to have the same name but are declared in a different class.
You can also implement interfaces method for some time now.
Great tips! actually very valuable and can save some time
While modifying a box collider if you click of it by accident control z will bring you back to it.
I have another tip, unlike on PC, the default framerate for phones is 30 FPS, so if you make a game, make sure you have a script that says On Start, set Application Target Frame Rate = 120 FPS or you can do 60 FPS but newer iPhones have 120 Hz screens and all other phones have 60
Or maybe what would be useful (which is beyond my current ability) would be to have all your descriptions within their own file, and have them assigned to functions in other scripts.
Awesome tips. Very exotic ones too, nice finds and thanks for sharing. The new object at origin setting one is a god send! Why is that not the default?!
Regarding no. 7. Do you know if using that method breaks batching or does it use the same material across systems given the same sprite?
Yoooooooo, I am 3+ years in unity and 2nd tip is crazy, how I didnt know that
Bro, I thought this would be another video with useless stuff, but no, it is really useful
Super useful stuff, cheers!
Nice tips, thanks!
Thanks for the tips! :)
Dame these are truly time-saving. Thanks for sharing the tips
Thanks For Sharing
4:18 - One way that i know of to (kind of) hide the summary comments is to write them in an interface. This also helps when you go to write the implementation for the method or property, you can hover on the name and see the description of what the method does.
also in visual studio you can hide the summary by pressing the [ - ] button in line with the beginning of the summary and it only occupies one line on screen and only shows the description (you don't need to put a #region around it).
other tips for summary comments:
for new lines you don't need to start the line with only end it with
also you can use tags like or to add references to other classes or keywords (like int, float, etc.). it colors them differently in the text and makes them easier to read.
learn.microsoft.com/en-us/dotnet/csharp/language-reference/xmldoc/recommended-tags
^ here's the documentation for writing documentation comments ^
0:20 you can also make it an async
Will using a single material (with multiple different sprites) for multiple particles reduce draw calls? I was so excited to try this that I forget to check the stats before I started.
Great video! I didn't know that tips, thanks!
Why do you put that empty GO with "---MANAGERS---" etc?
It’s just a way to create categories without assigning them to a parent game object. Like a sort of delimiter / region of where things go.
What about extensions for stupid things, like image.SetSprite(Sprite sprite) that will check if (image) exists before signing. Same with TMP_Text. SetText(string text). Or simplify Mathf usage by extending float with some of its methods, like Abs, so someFloatValue.Abs() is way more readable and easier to type.
3:15 these documentation comments is a C# feature not Unity, I was aware of it and it's also common in many other lanuages
all are good tips
nice video the first 2 tipps allready blew my mind and would have made my days so fucking more easy
🤦♂
1:37 Hm... I don't see how this would be any faster? I can only imagine it taking a tiny bit longer 🤔🤔🤔
I already know the debug mode
However I didn't know most of the other part off this video
amazing, thanks.
Most of these I didn't know ❤
the problem with [fiel: seriaized... is that if you already have a public variable you've used a whole bunch and want to make it private get; while keeping it in the inspector you are going to have to fill all the values again in all the prefabs and objects you had. hope you got source control, otherwise you are going to have to balance the game again. that being said, its great. Anyone know a solution for this?
5:50 this is again a C# feature that Unity does not support. It is strongly advised by Unity to use default null checks because comparison operator is overloaded by Unity. If you use a question mark there are cases when it works and not, basically Unity doesn't support nullable types and you should avoid it
To sum up, it is NOT THE SAME. Notice you have != in orange color, not gray
love it!:)
Empty at Origin and Properties for Array
Amazing!!
Flash said, slow down 😂
So usefull thx !!! xO
its a shame that I don't know everything. thanks btw
Bueno,Bonito y Barato
Nice
Its all fun and games until some unity tutorial guy does 5:18 but he types different code for each line
Don't you have a separate keyboard for each hand?
Saves much time.
The only problem is that in winter you have to take your socks off to operate the two mouses and your feet get cold.
After coding so much and googling so much I still don't know what Return null; or return 0 means😅
For some reasons people in tutorials use it but when I think and code with my own implementation I don't need a return
Do NOT use the ?. or ?? or ??= operators with Unity objects or component references. The Unity integration with Visual Studio even warns against this. Unity overrides the ==, != operators and the Equals method to support the C++ native object being destroyed before the C# wrapper is destroyed, but the null propagation and coalescing operators are at the compiler level and therefore have no knowledge of the C++ native object being destroyed first. So you may still end up calling a method or property on a C# object that has had the C++ native part already destroyed. That is bad.
If you want to save a few characters, just drop the "== null" in the if condition. Unity also overrides the bool operator to return true if the object is still valid but not necessarily null.
Why not use public for all variables when you are solo dev?