Smooth PORTALS in Unity

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments

I guess this guy https://www.youtube.com/watch?v=iHqjscifPnI should be mention at least as the code is 1:1 copy paste from his tutorial

👍︎︎ 4 👤︎︎ u/Repo_Games 📅︎︎ Jan 08 2018 🗫︎ replies

Brackeys is a god of disgestable, high quality shit

👍︎︎ 10 👤︎︎ u/Meatiecheeksboy 📅︎︎ Jan 08 2018 🗫︎ replies

First time I saw this was in the game Prey (2006) and it was pretty ground breaking. I guess they had to wait until computers were fast enough to render to 2 cameras at once.

Then in 2007 Portal came out. Attempting to create anything like this in Unity gives you some respect for what Portal was able to achieve.

👍︎︎ 3 👤︎︎ u/ZorgHCS 📅︎︎ Jan 08 2018 🗫︎ replies

At 10:00 I don't understand why he needs to get the angle between the two portals' rotations. He somehow needs it to rotate the other camera but I don't understand why. Can somebody explain this?

👍︎︎ 2 👤︎︎ u/willygamereviews 📅︎︎ Jan 09 2018 🗫︎ replies

Something I need to watch later :)

👍︎︎ 1 👤︎︎ u/brendenderp 📅︎︎ Jan 08 2018 🗫︎ replies
Captions
the reason here came across this really cool effect where the player walks through a portal and it smoothly transitions from one world to another today we'll be using rendered textures a custom shader and some math to achieve this effect also this video is sponsored by udemy udemy is a great site for learning new skills and they have a bunch of really cool courses on making gains I've previously mentioned the ultimate guide to game development with unity which is a great course made in collaboration with unity themselves if you haven't already definitely checked that out but udemy actually has a bunch more cool courses to offer one of the ones that I really enjoyed is called learn to code by making games it takes you from complete beginner to having a solid understanding of unity and C sharp programming on top of that it's made by Penn Tristram who is just really fun to learn from so to get started simply click the link in the description and get a site-wide discount as long the way and with that let's get into the video so basically the way that we are achieving this effect in the editor is by creating two worlds that we run side by side if I go here and dock my game view you can see what I'm talking about interesting we can see that we have two worlds one orange and one green in the left one we have the player and if we move him around we can see him moving in the world in the right one we have a camera this camera is going to mimic the position and rotation of our player but in the other world and we're basically just taking whatever this camera sees and cutting out a chunk the size of our portal and displaying it on a plane so that's basically what's happening then as soon as we move through the portal a player switches to the other world and you can now see another camera over here in the first world that does the exact same thing and because we're using a plane to render this when we go and move around the portal it's invisible because planes are only rendered on one side in fact if I go into the scene here go into world B and find my portal you can see that I have a render plane here which just set up with an ordinary material and this material just shows whatever the camera is seeing over here in our first world this is what we call a render texture and that's basically how we're going to set up this effect so now that we understand how it works let's try and do it ourselves so basically this is what I started with I've created two worlds which are basically just a bunch of cubes and I've put all these cubes in the world as you can see inside two master objects one called world underscore a another one called world underscore B and I've taken world underscore P and moved it over in relation to world a by 32 units but you can move this as far away as you want to it really doesn't matter we just want to make sure that the player only can see one world at a time so right now if I go ahead and play the game you can see that I have my FPS controller and I'm able to move around but of course I see nothing in the portal and if I move through it nothing really happens so let's change that before we start actually moving the player let's make our portal actually look cool and let's start by doing this in world 8 so in here I've created a portal this is just an empty game object as well as another empty game object which just stores all of our graphics which are just three cubes stacked on top of each other so that's really nothing here I have however made sure that the pivot of my portal is pretty much in the center now we can go and right click on a portal and let's create a 3d object and you will select plane and we get this big fat white plane let's start by rotating this negative 90 degrees on the X let's use the scale tool to fit this to our polo you don't have to get it exactly right I'm gonna do point to 1 by 0.3 5.3 and I think that fits nicely then let's rename this plane to render plane and this is where we'll be displaying the other world it also means that we don't need a mesh Collider so we'll remove that and we actually want to move this plane back a bit into the far side of the portal let's change the position on the z to point 5 next we want to set up a material for this render plane so let's go to the project right click go create material and it's called this camera matte because it's going to be displaying what our camera sees and let's do underscore B because we're going to be displaying what the camera sees in world B let's then go to a render plane and drag that in there but in order to display something from will be we need another camera let's go to our player object and take the player camera from here I'm just gonna use this because we want the same skybox and post-processing settings let's duplicate it move it out and I'm gonna rename this to camera on the score fee let's then Center it in our wallet I'm just gonna put it at the same position as the portal so that's 0 by 2 by 0 and let's move it over to world beats that means in my case I'm going to offset it by 32 on the X so this is going to be camera B I don't want this to be tagged as main camera so I'm gonna untag it so down here we can see what the camera is seen but how do we put that onto a material well you guessed it that's of course using a rendered texture so let's go to our project right click go create let's select render texture let's call it camera texture on the score B and now we can select our camera B and under the target texture field we'll drag in our new rendered texture so now you should see that if we select our camera check stupi the texture looks like what our camera sees and if we now go to our camera mat b and drag in our render texture on the albedo channel this now gets displayed on our plane of course it's currently distorted it has lighting applied onto it and it's very low resolution but hey at least it kind of works let's go ahead and fix these different issues the first one is that the shader we're using is completely wrong we can't really use the standard shader for this the reason why is we don't actually want to preview the entire texture we don't want to have everything that this second camera sees be displayed on this portal now we actually only want a cut out of this what I mean by this is if we imagine we take camera B here and we pull it out to a position of the player maybe the player is looking up a bit and a bit to the left here now we don't want to take this entire camera preview this entire image and put it in here instead what we want to do is we want to take only the part that we see through the portal so only this tiny part here and put that onto this texture in other words we want a cut out of the image now this might sound really difficult but it's actually really simple and I've gone ahead and created a shader that does exactly this of course have a link where you can download this in the description so let's take this into unity I'm now going into detail about shader writing basically we're dis courting the UVs of the object and instead we're using our screen coordinates if you want to know more about shader definitely let me know in the comments down below and I might do a separate video on the topic but for now we'll just use it as is so on our camera Matt B will change the shader to our new unlit screen cut out shader and you can already see this acting much much differently now what gets displayed on the cube depends on where it is on the screen and that's exactly what we want let's go ahead and undo all the changes to camera B here and let's now make a script that will take camera B and have it follow the position of a player in relation to its own portal to do that we'll hit add component and we'll create a script called portal camera well of course choose C sharp to create an ad let's open this up in Visual Studio now here we first need to set up a few references so I go public transform and first we need a reference to the player camera because that's what we're going to be following around so player camera will also need a reference to the portal that this camera belongs to so public transform portal as well as a reference to the other portal which the player is currently close to because we need to know the players position relative to his portal in order to calculate this cameras position relative to this portal so create a public transform other portal that's what no no update method we first want to get the players offset from his portal so we go vector3 player offset from portal and set it equal to the player cameras position so play a camera position - the other portals position so other portal top position and this should be the offset we can then set our current position so this portal canvas position equal to our portals position so portal dot position plus the offset so plus player offset from portal and it's actually that easy if we go and save now go into unity first drag in our player camera then our portal so that's portal B which is in here then the other portal so that's for a which is in here and I should actually go ahead and name these so it's clear when we drag them in I'll just quickly do that so now we can see that our portal is portal of B and the other portal is portal a and now when we play we might get a few warning saying that there are multiple audio listeners in this scene that's just because we need to go ahead and remove the audio listener from this camera and if I now dock these two side-by-side we should see that the camera moves around with the player and indeed it does so when we look through the portal we are actually already getting a really cool looking through the portal effect it's still very distorted and it definitely has some mistakes but we have definitely introduced perspective through the portal however if I go ahead and rotate my camera the illusion kind of breaks that's because our players camera is rotating but as you can see right here camera B is not so we need to also offset the rotation to that we go back in our script we'll make a few lines at first we need to get the angular difference between the two pole rotations and we'll store this as a float so we'll get the angular difference between portal rotations I will set this equal to quantonium dot angle and the first rotation is going to be the portals rotation so portal dot rotation and then the other portals rotation so our the portal dot rotation so that's the angular difference in rotation we then get the portal rotational difference as a quaternion so we'll go Kryptonian portal rotational difference equals quaternion angle axis and as you can see angle axis creates a rotation which rotates X amount of degrees around a certain axis in our case we have the amount of degrees right here and we just need to specify an axis so the amount of degrees is going to be the angular difference between the two rotations and the axis is going to be vector 3 dot up now if you aren't confused enough already we now need to get the direction that we need to face in so we'll create a vector 3 with the new camera direction and this is going to be the portal rotational difference that we just calculated multiply it with the player cameras forward vector so this should now give us a vector which is the direction that we need to point this camera and so finally we just need to turn that into rotation so to transform the rotation we'll set our rotation to quaternion look rotation to a rotation that looks towards our new camera direction and we want the vector three dot up to beat the up Vector and that is definitely a lot of rotational calculation and I completely understand if you don't get this right away quaternions and rotations can definitely be really hard to grasp but it should work so if we now save this and hit play inside of unity we can see that camera P rotates accordingly and that it now works much nicer when we rotate and look through the portal we're still getting a few weird issues we can see some of the portal sides that doesn't look too good and the fields that the two views aren't totally synced the reason for this is that our camera texture B is not set up to be the same size as our screen because we can't really know beforehand how big our game view is going to be therefore when we start the game we want to set this up through code to do that let's go and create a new empty object let's move this to the top let's reset it and let's call it something like game manager here we can do all of our setup let's add a new component to this and let's call it portal texture setup let's say create an ad let's open it up now here we're not going to be using our update method but we do want to use the start method but first we need a few references we need a public camera which is going to access our camera B as well as a public material which is going to be the material for camera B so camera mad B then when the game starts we want to check if camera B already has a target texture so if it already has a render texture assigned which means it is not equal to null well then we want to remove that texture we do that by going camera B target texture dot release now that we assured the camera is cleared we can go camera P dot target texture and set it equal to a new render texture so we're basically just creating a rendered texture through code and here we can set the dimensions so we of course want the width of the render texture to be screened start with the height to be screened dot height and then we can set the depth of the texture which we'll just set to 24 so now that we've created a rented texture and set our camera to render to that texture we can take this texture and feed it into our material so we'll set camera matte B dot main texture equal to camera B target texture and there we go if we now save this going to unity and reference first camera B then camera mat B and hit play we can see that as soon as we play the game the texture on the plane becomes really really crisp and we now no longer get this weird offsetting that's because unity has recognized the size of our game view and it's gone ahead and automatically created a render texture for camera mat B and C if we go ahead and click on it here with the appropriate size and this rendered texture is not visible anywhere because it's created at runtime behind the scenes but it is definitely there this also means that we can just go ahead and take our camera texture B and remove it because we're creating this automatically when we play awesome so that's actually it for the first part of this tutorial being able to look through the portal and if I go behind the portal you can see that because we're using the plane it disappears but now we need a method of safety transporting the player to the other world to do that we need a separate plane let's go under world a go to our portal and select the render plane now this is all set up correctly but we need a Collider that will trigger whenever a player walks in turn to do that that's duplicate the render plane let's remove the mesh renderer the mesh filter let's rename it to Collider plane and let's add a new component which is going to be a box Collider now we can reset this scale here and start changing the size so first let's bump this up on the X bump it up on the Z as well to make it fit I'm just gonna make it two by three and I'm gonna set the wide to zero we don't want this box to have any width I am however going to move it forward so it's in front of the render plane because I don't want an instance where our player will actually walk through the render plane before we get teleported and see what's behind our portal here that's just not gonna look good so I'm gonna set the Z here to zero so it's half a unit in front of the printer plane I found that works pretty well I'm then gonna mark our box Collider as a trigger and now we're ready to create a nother script this is going to be the portal teleporter script let's say create an ad and open it up we can remove the start method and instead we need a reference to the player so public transform player as well as a reference to the receiving portal because we need to know where we should send our player so we'll create a public transform and the receiver and before we send our player anywhere we need to know whether or not the player is colliding with the portal to do that we use void on trigger enter this method is of course called whenever something enters the trigger and we can gather some information about the object that enters by writing Collider and let's call it author so other of course refers to the other object we are colliding with and we need to make sure that this other object is actually a player so we need to check if other tag is equal to player and if it is well then the portal and the player is overlapping so let's go ahead and create a private boolean called player is overlapping and set it equal to false by default however if this is true we'll set player is overlapping to true we also need to determine when the player is not overlapping anymore in which case we'll go void on trigger exit again we'll take in a Collider farther if other tag is equal to player well then the player has left the portal so player is overlapping is false and now inside of our update method we know whenever the players overlapping so we say if the player is overlapping well then we want to use the dot product and let me show you why so we have a portal as well as a player that wants to enter it but we need to make sure that the player is entering the portal from the right side because from behind we're not drawing the portal and so we don't want to teleport the player if he walks into it from behind to check if the players coming from the right side we use the dot product that means that we get a vector that points upwards from the portal so we'll call this portal up and we also create a vector that's pointing towards the player so we call that player between these two vectors there is an angle and since the dot product is calculated using the cosine of this angle between these two vectors we can use it to determine where our player is in relation to the portal we can do this because the cosine to a angle less than 90 is positive whereas the cosine to an angle greater than 90 is negative and if we have a look at an instance where our player has gone through the portal and has passed to the other side the angle between these two vectors is definitely going to be created 90 and so the cosine to that angle is going to be less than zero and so is the dot product now what does this mean for us in code well it means that we can take the dot product so we can write float dot product which is going to be equal to vector three dot dot between the up vector of our portals so transformed a table and a vector pointing from the portal to the player to do that we get a vector three which we'll call portal to player and set equal to player position minus the portal's position so transformed up position and we'll then just put that in here so we get a dot product between transformed up and a portal to player and we can then check if the dot product is less than zero if this is true the player has moved across the portal and so we want to teleport him and of course here we need to do a bit of offsetting of the position and rotation as well first off we need to get the difference in rotation so we'll create a float rotation difference and set it equal to quaternion dot angle we want to use the rotation of our portal as well as the rotation of the receiving portal so this is the difference in rotation between the two portals and we want to make sure to reverse that will then add 180 degrees on top of that so we'll go rotation difference plus equals 180 and that's because if we have a look at our two portals we want them to be flipped so here we want to be able to enter from this side and here we want him to go out from this side and so we also want him to enter from this side so you can see that's flipped by exactly 180 degrees if we do it properly cool so finally we can take our player and rotate him around the other axis so Victor three job by our rotation difference and it's teleport there so now we're rotating him properly now we can also actually move him to do that we create a vector three which is going to be the position offset and this is the current offset between the player and the portal so player top position minus the portals position and as you can see we've actually calculated this once before right up here so we don't need to do that again however we do want to make sure that when we apply our position offset it also gets rotated so we'll calculate quaternion Euler so here we create a rotation that rotates zero degrees around the X rotation difference around the Y and zero degrees on the z and we'll multiply this with our portal to player vector so now finally we can set all players position equal to receiver dub position plus opposition offset and of course once we've teleported him we are no longer overlapping so player is overlapping is again false all right if you go through that you're amazing congratulations now we should be able to select our Collider plane and under here we have two empty slots one for the player we can drag him in there and one for the receiver and this should actually be a separate Collider plane on the other portal but instead of creating that from scratch I'm actually just gonna take the render plane and Collider plane right here and duplicate them by hitting ctrl D and then I'm gonna move them to the second portal be here and I'm just gonna take all their positions on the X here and zero those out so that should actually snap them right over to the other portal here all we want to do is make sure to kind of flip everything so we'll take a render plane and we'll move that by negative 0.5 as well as rotated around the Z by 180 there we go so now it's pointing out here and it's at the back of the portal I will also take our collider plane and rotate that by 180 as well and we don't want these to be named something with one we can just go ahead and do that so now we can take our collider plane for portal a and drag as the receiver the collider plane for portal B as well as take the coil plane for portal B and drag as the receiver the collider plane for portal a and now ladies and gentlemen if we press play we should be able to rock right through the portal and here over here it looks kind of weird I know that that's because we haven't set up the rendering for this portal but we are actually able to walk through it so there we go so now we simply need to also set up rendering for the other portal here and we've actually done this before so it's simply a matter of duplicating everything we can go ahead and duplicate camera B here and call this one of course camera a and this one we want to see row on the X and not be moved by 32 so it's right over in the center of the other portal for this portal camera the player camera is going to be the same but the portal is going to be now portal a so we'll drag in portal a and the other portal is going to be portal B so we'll drag in portal B we're just prover seing the two finally we can go to our game manager and here we need to make our portal texture setup also set up the textures for camera a so I'll just duplicate this I'm a quickly copy some code so we're creating another camera here for camera a and other material for camera matte a as well as all this code down here but instead of camera B we are now referring camera a so Catherine ate a target texture there we go and camera a main texture is equal to camera at target texture there we go make sure to replace everything or else it's going to look really weird let's say that hit into unity and we get two empty fields let's drag in camera a as well as camera Matt a which we still need to create so let's duplicate camera Matt B and rename it to camera Matt underscore a and remember we don't need to set anything up here because the texture is inserted procedurally so we'll just select our game-manager and drag it in as is and now I think it's actually going to fully work this time so if we switch into game you alright that's not quite working and that is because we need to take the depth of both camera a and B and decrease it to make sure that our standard camera always renders on top this won't be a problem when you play the game but it's just annoying when you're in the editor oops I actually forgot one thing and that is we also need to go into weld beam under the render plane here and change the camera mat to a that needs to be swapped out as well to make sure that it's not displaying what camera B is showing but what camera a is showing and now if we maximize our game view and press play we can see that we can look through the portal we can walk around it nothing happens and we can try and go through the portal and now we're involved B and we can look back into world a and we can actually go right back into that so that's it yay so that's pretty much it for this video again definitely check out the many awesome courses over at udemy simply click the link in the description to get a discount on that thanks for watching and I will see you in the next video thanks to of the awesome patreon supporters who donated in December and a special thanks to Judy Minh Vecchio infinity PPR euro Omer and soft tune sighs mommy Derek Eames Kirk Murr free Samara fine Peter died double tap 45 James Pete and Evans thomas morley Superman the great John Burkhart kookaburra Jason Lotito Alex for kid ski suniye Hobson James Rogers Robert Boone Rob fan and Erasmus
Info
Channel: Brackeys
Views: 349,139
Rating: undefined out of 5
Keywords: brackeys, unity, unity3d, asset, assets, model, texture, models, textures, material, materials, how, to, learn, tutorial, tutorials, game, development, develop, games, programming, coding, basic, basics, C#, portal, portals, transition, smooth, teleport, teleportation, shader, effect, world, advanced
Id: cuQao3hEKfs
Channel Id: undefined
Length: 24min 52sec (1492 seconds)
Published: Sun Jan 07 2018
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.