How to Make a Wobbling Screen Effect in Unity

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
in this video I'm going to show you how you can make a wobbling screen effect in unity I will first show you a method that works with the built-in renderer and after that I'm going to show you the necessary changes to make to also make it work with the universal render pipeline in short urp hey what's up back in 2020 I released my first mobile game called flight to the rescue and in this game there are situations where our hero can get dizzy and to make the player feel that the hero is dizzy I added two things one I inverted the already inverted controls here I know everybody's favorite and two I created a screen wobble effect by moving the screen pixels in a wave-like way using a fragment Shader but before I show you how to write such a Shader to create this effect we first have to really understand what exactly is happening here and how we can create this wave and for that we're going to need a little bit of math too hey come on I keep it simple I promise and if you're not interested in math you can just skip to the coding part of the video in the next chapter alright then let's start with how to make a wobbling screen effect in unity okay let's look closely at the still frame of my game we see that while the wobble effect is active all the pixel colors are shifted to create a waveform but they don't just stay in place or else with our game active our current wobble effect would look like this but instead the wave itself shifts vertically as seen here to create this wobbly motion okay so how can we represent this mathematically so that we can implement it in our Shader easy for the waveform we can simply take a sine function or a cosine function whichever you like but let's say we use the sine function the distance between one full up and down wave is called a period and an irregular sine function the distance of a period is 2 pi but when working for example with texture coordinates we don't use coordinate values like Pi or 2 pi but instead use values from 0 to 1. so to make it easier for us we're going to map this wave in X direction from 0 to 1. to do that we just multiply the regular period value of 2 pi to our x value and we have successfully mapped one sine wave from 0 to 1. now to increase the frequency of our wave meaning how many times we want to repeat one up and down sine wave in our interval we just multiply 2 pi x with the frequency we want so if the frequency is 2 the waves are doubled three tripled four quadrupled and so on we're nearly done only two values left to explain and we can start the code now to be able to change the height of our ways we can multiply a value called the amplitude to our sine function this value will scale our waves to the size we like for example if we only want our waves to be half as high we set our amplitude to 0.5 and so on okay so we have as many waves as we want with the size we want now to create the wobble effect we need to move our wave in one direction to do that we just add a shift value to our x value after it got multiplied by the frequency and 2 pi and to move our wave we increase our shift value over time right we are done with the math part of this video and this is the final function we are going to implement to create the wobbling screen effect okay enough math let's now open up unity and finally start implementing the wobbling screen effect okay so in unity I first set up a small scene so that we have something interesting to wobble now we create a material called wobble effect material and an unlit Shader called wobble effect Shader that we will give to our material okay let's now jump into our Shader and implement the wobble effect in our Shader we scroll to the fragment Shader because we want to manipulate the pixels seen on the screen to create this wobble effect now let's look at our function we want to implement okay frequency shift and amplitude are the variables that we want to be visible outside of our Shader so that we can set and change them in our scripts so we're going to first Define them here outside of our fragment Shader and then to make them visible outside we need to Define them as properties to do that we scroll up here to our properties and first write the name of our variable let's start with frequency and in Brackets we write the name of the property visible outside of the Shader and the type and finally we set the default value of our property now let's also do this for our shift and our amplitude if we now look at our material we can see our properties we have defined in the properties section and can later set the values of these properties in our code okay back to the fragment Shader we just need to create our PI variable I just take the first five digits after the DOT and we are done setting up all the variables we need okay before we start let's take a look at our basic fragment Shader currently it does the following it gets the UV coordinates for each pixel looks up the color value in the main texture which in our case will be the rendered scene of our main camera and Returns the color for the pixel to be rendered then on screen so basically what color comes in comes out what we want to do now is to shift the colors according to our sine function we defined before meaning that we have to calculate a new v-coordinate to get our color from and then return that color instead so our new V coordinate is our old V coordinate plus the value we get from our sine function hey everyone it's me again the me from the future what I realize now is that our wobble mirrors our sandwich with this approach what do I mean by that our current pixel gets its new color from the new calculated position according to a sine wave meaning that when the sine wave goes down we replace our old pixel color with the new color from below and when the sound wave goes up we replace the pixel color with the color from above which in the end after having processed each pixel will mirror our sine wave so to push the pixel colors in the direction of a sine wave we have to subtract our function from our old V coordinate so our new color will be chosen from the opposite direction and therefore will be pushed in the direction of our sine wave function but don't worry either way the wobble effect will look the same because by shifting our sine width over time our pixel colors will wobble up and down so it will matter if the sound width is mirrored because the only thing that is different is the starting position of our wobble and that's it okay so with that other way let's continue okay let's Implement that from our i.uv we can access our UV coordinates with X for our U coordinate and Y for our V coordinate now we first create a new y variable that is the old y variable plus our function we defined before and after that we just need to set the Y value of I dot UV to our new y value and we are done with our Shader and just so you know this Shader will create horizontal waves if you want vertical waves like in my game you can for example just swap the X and Y variable like this and also don't worry about our V coordinate reaching values slower than 0 or higher than 1 because our UV coordinates will be automatically kept to zero when lower than 0 or 1 when higher than one okay now back in the editor we create a wobble effect script for our main camera and create a public material variable called wobble effect material which we will set with our created wobble effect material in the editor in our wobble effect script we now have to implement an event function called onrender image which has two parameters source and destination source is the render texture we get after our main camera has rendered the scene and destination is the render texture we want to basically replace our source with to render on screen so to use our wobble effect Shader to change our source and save it into our destination we use a function called blit which gets the source the destination and the material containing our Shader as an input but wait before we continue I have to inform you that onrender image will only work when using the built-in renderer if you're using urp this won't work but don't worry you can follow along with all the steps in this video and in the end I will show you the changes we need to make in order for it to work with urp okay with that out of the way let's continue okay let's see what it looks like now seems like nothing is happening let's open up our material we see here that our amplitude is 0 meaning that all our waves are flat Rising it to something above zero for example 0.05 will reveal our sine wave and if we want more waves we just need to increase our frequency and finally with our shift we can move our wave nice now let's extend our wobble effect script to make our screen wobble automatically first we are going to create a wobble active pool variable to check if we should wobble or not then for float variables one for our frequency our shift in our amplitude and one for our shift speed I set the frequency to 4 shift to 0 amplitude to 0.05 and shift speed to 5. but you can set these values however you like depending on the number of waves you want the height and how fast you want them to move okay next we write three functions to change the values of our property in the wobble Shader to be able to set the value in our Shader we need to call the set float function of our wobble Shader material and then first give it a string of the property name we want to set for example here it's frequency and then the value we want to set and let's repeat that for our other properties now let's write a public start wobble and stop wobble function to set our wobble active pool to true or false okay now that we've finished all our preparations we can write a verbal core routine to make our waves move first we are going to set our three properties frequency shift and amplitude now while our wobble is active we are first going to increase our shift value by time dot Delta time multiplied by the shift speed then update our shift properties in our Shader and finally yield return nulls that we don't get stuck in our while loop when we are done wobbling we set our shift back to zero and then disable our script to disable our effect and that's it for our core routine now we just start our core routine in our start wobble function and we are done with our wobble effect script for now now to test this I'm going to write a wobble test manager script that gets a reference to our wobble effect script and waits for keyboard inputs to either turn the wobbling effect on by enabling our wobble effect script and call it start wobble function or to turn our wobble effect off by calling the stop bubble function hey future me here one last time what I've recently discovered is that it does not matter if the wobble effect script is enabled or not it is still possible to call or start wobble function even though the script is disabled and also if the wobble is active it will continue to wobble even if we manually disable the script in the editor but why is that this is because disabling our script does not really disable it but rather disable certain functions of mono Behavior like start update fix update and so on and therefore since we will not use any of these disabling our script won't have an impact on our wobble effect so what I'm saying is that you can basically ignore these two lines in our code the one in our wobble core routine where we disable our script and the one in our wobble on function where we enable it okay that's it now back to the present okay now let's test our wobble effect nice wobble on stats are wobble and wobble off instantly disables it but look what happens if I press wobble on multiple times without turning it off first the wobbling gets faster why is that it is because when we turn our wobble on we always start a new core routine that runs with all the other coroutines that were created before and each core routine we start increases the shift value in its while loop so our wobble gets faster and faster to fix that we just have to check if wobbleactive is false before we can start a new core routine and now we can press on as much as we like without breaking our wobble effect okay the base wobble effect is finished but if you like a more smoother transition between on and off like I have for example in my game we can do this by slowly increasing our amplitude from zero to the value we like when starting the wobble and slowly decreasing it to zero when we want our wobble to stop so back to the wobble effects script we are going to set our amplitude to zero and create a Max amplitude variable that holds our highest amplitude value and we are also creating an amplitude speed variable that defines how fast the transition between 0 and Max amplitude will be now in our wobble core routine we're going to squeeze ourselves between set shift and set amplitude and are going to implement our wobble warm-up phase as follows well amplitude is less than our Max amplitude we are going to increase our amplitude by Delta time multiplied by the amplitude speed to slowly get bigger waves with each frame then we are also going to increase shift by Delta time multiplied by the shift speed to move our waves and after that we update the amplitude and the shift in our Shader and enter loop with yield return null outside of the loop we then set amplitude to its max value and update our Shader one last time before we get to our main while loop and we are done with our wobble warm-up now the cooldown part is similar to the warm-up after our main wobble effect Loop while amplitude is less than zero we decrease our amplitude instead of increasing it to slowly flatten out our waves the rest stays the same as in our warm-up while loop above and outside of the loop we set amplitude and shift to 0 and update our amplitude in our Shader before disabling our script and that's it let's see how that looks like nice now we have a smooth warm-up and a smooth cooldown of our wobble effect but what happens if we try to start our wobble while the effect is in cooldown and vice versa okay so when we press wobble off while warming up we see that our amplitude will rise until its max value and then directly after start cooling down this makes sense because our stop wobble function sets our wobble active variable to false and when warming up we don't check if it is false so it will complete the warm-up phase and only then check here if wobbleactive is false before starting to cool down okay and what happens if we press wobble on while cooling down it locks our amplitude this is because when we are cooling down our wobble activist faults this means when we call the start wobble function we are allowed to create a new core routine and warm up again and because our cooldown face decreases our amplitude until it reaches zero and our warm-up phase increases our amplitude until it reaches its max value at the same speed we get stuck okay so let's fix this to be able to end our wobble while we are warming up and start our wobble again even if we are cooling down we have to actively check our wobble active variable in each of our phases so in a warm up we only continue to warm up if wobble active is true and if it is not meaning if we press wobble off in the meantime we break out of the while loop and stop the whole warm-up process and let us not forget to also check here in our last warm-up step if wobble active is true or else we would accidentally max out our amplitude okay our main wobble Loop here is fine as it is so let's move to our cooldown here we handle things similar to our warm-up we cool down our wave effect only if wobble active is set to false else we stop immediately and also here we only do all this if wobble active is false because if it is not false at this point it means that we have activated our wobble again so it would be a bad idea to change our values and disable our script one thing I realize now is that when setting our amplitude after we increase it there is a chance that amplitude is greater than Max amplitude so I just put this up here before we increase our values and that fixes it for our warm-up and the same goes for our cooldown here I also have to change the order or else there is a chance that our amplitude gets below zero and while we're at it we can remove set shift here and instead set it here at our last step before disabling the script and finally let's just move this set shift up here so the order is consistent with the other while loops okay let's take a look at how our effect looks now thanks to our changes we can now smoothly start and stop our wobble at any time nice basically that's it we finished our wobbling screen effect there's only one thing I like to mention if you're worried about the shift variable getting too big when our wobble effect is active for too long don't be we're using float so the value can get pretty big before reaching its max value but I still saw some strange behavior of our Shader when reaching a value of for example 10 million so to be extra sure we could reset our shift to zero whenever it reaches a value of 2 pi Y 2 pi you ask this is because the period of a regular sine function is 2 pi and since our shift value is not multiplied by the frequency n by 2 pi we get one full up and down wave when increasing our shift from 0 to 2 pi so back to our code at each point where we increase our shift value we can use the modular operator to limit our shift values from 0 to less than 2 pi and as you can see here our shift value gets set back to zero whenever reaching 2 pi but our wobble effect still looks like before okay great now as promised I'm going to show you a way to make this effect work in urp when looking at unity's documentation Unity suggests that for urp we need to use the scriptable render pass API because on render image is not supported this means to be able to use the blitz functionality we use in the onrender image function we need to write our own render feature I won't implement this renderer feature here but instead I'm going to use code I found in an article by Bill on gamedevbill.com who originally took the code from another article written by cyan on signgamedev.wordpress.com I will link both sides in the video description for everyone who is interested in reading more about this topic okay now in unity I've created a urp project with the default sample scene and added all the code and game objects from before now we are going to copy the blitz code go back to Unity and create a script called blit and in the script we delete everything and paste the code we copied earlier in our Universal render asset we select add renderer feature and there we see our created blit we select it and give it our wobble effect material you can see that the effect now is already applied to our scene but with some strange artifacts this is because our BLT is supplied too early to fix this we go to event and select before rendering post-processing and now everything looks fine let's now disable blit and start implementing the necessary changes in our code in our wobble effect script we can safely delete our own render image function or comment it out if you want to keep its memory alive now to be able to control our renderer feature we need to First add that we want to use the unity engine.rendering.universal namespace and then create a public scriptable renderer feature variable that we're going to set with our created Blitz render feature in the editor in the start wobble function we then activate our blit renderer feature before starting our cool routine and in our core routine we disable our Blitz renderer feature instead of the wobble effect script when we are done wobbling and because we won't disable our wobble effect script anymore we don't need to enable it in a verbal test manager script and that's it the only thing I'm going to change now is the keyboard input here because the a key is already used in this urp sample scene okay then let's test it nice now our effect also works with the universal render pipeline I hope you liked this video and if so why not give it a thumbs up do you have some questions or some tips on how to improve this method or simply just want to say hello then why not write a comment down below I'd love to hear from you and thank you so much for watching and until next time ciao [Music] yo before I forget it if you'd like to see more tutorials or tutorial like videos then check out this one where I show you how I make a retro Sheltering screen effect for a private project of mine and if you'd like to see more of my mobile game where I first implemented a swiveling screen effect then you can check out other videos related to it here or if you like why not check out the game out for yourself you can download it for free the link is in the video description okay that's it bye [Music]
Info
Channel: Roberto Cespi
Views: 755
Rating: undefined out of 5
Keywords: Unity Tutorial, Unity Devlog, Wobbling Screen Effect, screen wobble effect, Unity Shader Effect, Unity Shader, URP Screen Effect, URP shader, Built-in shader, ScriptableRenderPass API, GameDev Unity, Game development, How to make unity, Roberto Cespi, devlog, indie game devlog
Id: yG4dYBfeC0g
Channel Id: undefined
Length: 21min 19sec (1279 seconds)
Published: Sun Apr 23 2023
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.