How to make a silky smooth camera for pixelart games in Godot

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
hello and welcome to a new godot tutorial this time about making a very smooth camera in a pixel art game before we start i want to talk about this tutorial and its use so basically you will learn two things one is to separate your game rendering from the viewport and we will also talk about what viewport modes are that you can set in your project settings a lot of people don't really know what they do in detail and the main focus of this tutorial will be how to make a very smooth camera so let's jump right in why would you use this technique if you're making a pixel art game and if you want to be pixel perfect but still have a smooth camera motion this technique is for you especially if the bass resolution is pretty low let's say 640 by 360 or even less like 80 by 45 in this example project to have a pixel perfect game including effects like particles or shaders you want to use viewport mode you can find the stretch mode in display window right here mode viewport this will mean that everything will be rendered at the set resolution of the project so if i start the game it will be rendered at 80 by 45 you can see the particles dropping down here are pixel perfect compared to the view here in the editor where you can clearly see that the particles are rotated while falling down but the stretch mode will affect your whole game so everything will be rendered at this resolution even text which will make it very hard to read the technique that i'm about to show will solve this problem so before we continue i just quickly want to tell you the difference between the different stretch modes that you can set up here in window stretch mode so let's set it to 2d and see what happens when starting the game at first everything looks pretty much the same as before but you can see that the particles falling down are not pixel perfect anymore and if i move to play a character you can see that it's not moving pixel perfect you can observe a slight offset and i can also move the character by non-full pixel values so either i would have to round those values or live with the fact that it's not pixel perfect anymore but it also has advantages like high resolution text in 2d mode you can also rotate pixels which is something that not all people liking pixel art like a lot so how to solve this problem what's the plan we want to have the advantages of using a viewport for our pixel art game pixel perfect unrotated pixels but we also want to have the advantages that come with using godot in 2d mode clear text and a smooth camera i prepared this simple example project using kenny's pixel line platformer asset the first step that we take is to set our project to 2d mode and we also set up the project resolution that we like to work with so let's use 640 by 360 for this the new resolution the bigger resolution needs to be in the same aspect ratio as the original game resolution in this case it's 16 to 9 and the old resolution was 80 by 45 so this will be times 8. the next step will be to create a new empty scene and let's add a viewport container and inside this viewport container a viewport we set the size of this viewport to the original game resolution that is 80x45 and we also set the viewport container to a size of 80x45 you can see now that it doesn't fill up the whole screen if we add our game inside this viewport what we have to do anyway you can now see it being rendered here and if we run this scene you can see that we can play the game but it's super small so the easiest solution for that is scaling up the viewport and we already calculated the ratio of times 8 for the game resolution versus the project resolution so we just set the scale to times 8. if we run the game now takes up the whole screen and looks great now we already have the advantages of 2d mode and a pixel perfect game if we set up some text in this main game outside of the viewport and start the game you can see the game is still pixel perfect as you can see in the particle and we still have the high resolution text so that will be already enough if you want to have a pixel art game with a high resolution ui now let's get to the smooth camera what we'll do is to create two positions for the camera one rounded and one with subpixel values the subpixel value will be sent to the shader that moved the image by that amount creating the illusion of smooth motion the first thing we need to do is to add a margin to the viewport to do that we need to add two extra pixels so we increase the size to 82 and 47 and also in the viewport container 82 and 47. you can now see we have two extra game pixels in our game we need to center this viewport so we set the position to -1 and -1 but we need to take into consideration that the game was scaled by times 8 so we use -8 and -8 and you can now see especially in this corner we have one extra pixel of margin around our game we run the game this extra pixel won't be visible now we need to be able to move this around so let's add the shader to the viewport container go to material add a new shader material a new shader this will be a very simple shader just to move it around so we need a vertex shader we also need to add a uniform to control the offset of the image let's use a vector 2 for that and let's call it cam offset let's give it a default value of 0 and 0. now let's add the vertex function of the shader and in here it will be very simple vertex plus equals cam offset simple as that if you want to test if the shader works just click on the viewport container expand the shader parameters and let's play around here and you can see we can move this around and in fact if we move it by one we move it by exactly one pixel now in the next step the shader will be controlled by the game's camera we need to add the camera and we also need to make the viewport containers shader parameters accessible to the camera so to do that i will add a script to the game let's call it game.gd and i already added this singleton with the two variables viewport container and viewport so let's set that in this new script so in this script we set the variables inside the singleton viewport container and viewport to the viewport container and the viewport so let's go into our game scene in here we need to add a camera first so let's add a camera 2d let's add a script to this camera and let's call it camera script in this camera we need to set up a couple of things first we need to set up an export variable to select the player let's use this very common and well known pattern like this we can select the player model from the camera script like this we need some more variables one is called game size and this is actually the original game size that we planned the game in to be so in our case it's 80 and 45 and this is not with the margin that we added to the viewport container and the next variable we need is called windows scale and to calculate this we get os dot window size and we divide it by game's size and we only need the x value we only need one axis so we make it a float and we also need to set it to unready we get the correct window size when the game is started we need a third variable called actual camera position bar actual cam pause and we will set it to the global position of the camera now we get into the medium potatoes of this camera script let's add the process function and let's start by calculating the offset between the mouse cursor and the player model so we call it mouse position and to get that we need to know the viewport first as we set it up we will use this viewport and we will use the method get mouse position and we'll divide it by windows scale so this is basically giving us the mouse position inside the viewport and we divided by the windows scale to have basically the pixel perfect version of the mouse position so now we subtract game size divided by two and we add the player's global position like this week we'll get the offset from the mouse cursor to the player so the next thing we need is the camera position that we calculate let's call it cam pause and this is basically a linear interpolation between the value we just calculated and the player global position and we'll set the weight to 0.7 the position that this returns is a position between the mouse position and the player position let's set the actual camera position to be a linear interpolation between the actual camera position and the calculated new camera position the weight will be delta times five let's just take five it's basically the speed in which the camera moves so this line of code will smooth out the camera movement in the next line we're going to calculate the subpixel position of the camera so let's call it the pixel position and we can calculate that by taking the actual camera position around it and subtract the actual camera position in the next line of code we're going to update the viewport container shader to do that we need to access the material property of the viewport container and use the method set shader param and it needs two parameters the first one is the uniform's name that was cam offset and the second parameter is the value so we take the subpixel position that we just calculated and we send it to the shader so the shader knows how much to move the image around basically and as last step we set the global position of the camera to the actual camera position and we round it so it will be pixel perfect alright with that all done make sure you have the right player selected and make sure the camera is set as current and let's see what happens if we run the game we have a super smooth camera that we wanted and we can also add high resolution ui and we can also add shaders that use a higher resolution than the pixel perfect game thanks for watching and if you enjoyed this tutorial or if you learned something leave a thumbs up hit the bell subscribe and yeah see you next time bye
Info
Channel: picster
Views: 15,300
Rating: undefined out of 5
Keywords: Godot, Godot Engine, Game Development, Game Camera, Pixelart, Smooth, IndieDev, Indie Developer, Game Design
Id: zxVQsi9wnw8
Channel Id: undefined
Length: 10min 7sec (607 seconds)
Published: Sun Oct 31 2021
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.