H thanks for stopping by everyone I just hate these round base games that make you have to wait until the next game starts when you join into the game but at least this game has a spectate mode so I'm just going to click on this and see what's happening wait Newbert who is this random shadowman standing right behind you he looks a little creepy like are you not phased by this at all Newbert uh who am I kidding Newbert just has his airpods in he can't even hear or see what's happening Newbert I think you should turn around I don't want you getting killed wait new bird he's coming for you new bird he's got his airpods and he can't hear hear me no newd no ah whatever at least I get to play the next game now that's all that matters all right let's think about this for a minute this video is going to be about camera manipulation which is based off of the idea of our camera object now our camera is what allows us to view the 3D World in its simplest definition and there are ways that we can manipulate this camera uh through changing some properties and through scripting as well which is what I'm going to be teaching you how to do inside of this episode so from this example that you saw here when I pressed the spectate button it moved the camera to this specific position right here to be in front of Newbert and another example that I've created is we can hold left shift to Sprint and that is going to zoom our camera outward just a little bit and then if I let go then it's going to zoom the camera back in so so this is manipulating the way that we move our camera through scripting if let's say we had a system like this in place and so these are just some examples of being able to manipulate the camera and that's what we're going to be doing inside of this video so with that being said let's go ahead and go straight into the episode now that we understand it let's Implement camera manipulation inside Roblox Studio but I do want to emphasize that when we're changing the camera either through its properties or through scripting we want to do it on the local side because every single player has their own camera since what they see in the world is going to be unique from each other so we're going to get into more about that later when we start scripting it but as of right now what I want to do is introduce to you some properties that we can change with the camera and the first place to look is inside of starter player so I'm going to select this and there should be a category called camera right over here that has these properties that we can change for a starting player when they join into the game so I'm just going to scale this out so we can show the properties um two of these involve the zoom distance for the camera so basically how far away can the player zoom and how close in can they Zoom so by default the max Zoom distance is 128 so if I were to demonstrate this to you I can just reduce this to let's say 20 and I can increase the minimum Zoom distance to let's say 10 so now if I hit play then what should happen is that if I try to zoom out it's not going to work because I set the max Zoom distance to 20 studs now if I try zooming in it's only going to go in as close as 10 studs from the player so it kind of gives a constraint to how far the distances are um with the camera and so that's uh one set of properties so I'm just going to hit backspace and just so I'm just going to hit backspace really quick um next thing is camera mode so there's only two options it's either classic or lock first person I think that one's pretty self-explanatory now Dev camera occlusion mode is essentially a way for the camera to handle objects that are obstructing the character with the camera's view so if I were to create a part just like this I'm just going to create like some tall structure right here and what I'm essentially going to do is hit play so what's going to happen is when the camera tries to deal with objects that are obstructing the player like this then it's going to zoom the camera into where the player is just like this I think you kind of notice what's happening here so this is what's happening by default but there's actually a second option we can change for the occlusion mode and that's called called invisicam so when I hit play now uh once we go into the game then instead of zooming into the character what it's going to do is it's going to set the transparency of the objects that's blocking the player to semi-transparent or like 0.5 or whatever you want to describe this as so that's what invisicam does and so I think this is something you should experiment with uh depending on the kind of game that you're creating now there's two more options here which is basically what allows the developer to set uh a fixed camera movement type for the user if they joins the game I'm going to explain these camera types in a little bit um but that's essentially some of the properties that we can set for um a starting player okay but now I want to get into the camera object itself and this is located inside of workspace so if I open this up then our camera should be right over here and there's two properties that I want to look at that are going to be important one of them being camera subject and the other one being camera type which is both under the camera category so to explain what camera type is I'm just going to hit test and hit play and it's basically a property that allows us to change what kind of camera that we have going for this specific player or ideally for all players that are inside of the game so by default it's set to custom which is essentially uh whatever we pick for the camera mode that's inside of our settings which by default is classic so classic is what allows us to move around freely the this is what the classic camera type is but then we can change this to something else like let's say attach so the way this camera goes is different than what we had before and if I were to do fixed then it's just going to stay in place and then if we select something else like orbital then it's going to have this weird like top down perspective so you can see all of these different types of cameras that we can have for our game and depending on the kind of game that you're creating I think picking one of these camera types is going to be pretty beneficial I um so that's something I wanted to show so I'm just going to quickly set this back to custom and the other property is called the camera subject now by default our camera subject is the humanoid of our local player so basically the subject is essentially the reference part or instance that the camera is attached to so we can actually change this to be a reference to a different part by simply going to our camera uh clicking on camera subject and then we can select whatever reference we want for our camera subject so let's say we want it to be the part that we created so the camera has now moved to be a part to be the camera for this uh part that we created because this is now our reference point rather than our character so that's a little something I wanted to show as well and if we want to revert this back I'm just simply going to say camera subject and then I'm going to click back on our humanoid so that we now have our reference being our character so with what we know right now we can start scripting our camera and what we're going to do is create a local script in let's say starter player and starter player scripts we're going to hit the plus sign and we're going to insert a local script and we're going to delete this code right here so the first thing we have to do is make reference to our camera by saying local camera equals game.or space. camera now you might think that this is the camera that we're trying to reference here but that's actually not correct even though there is a camera inside of workspace this is not the the right kind of camera that we want to manipulate because there's a difference between a camera and a current camera camera is basically the Studio's camera but what we want to manipulate is the current camera which is basically our local players camera so instead of camera we're going to say current camera just like this and so when we're manipulating the camera inside of a local script we want to use current camera okay so now that we have that what we can do is manipulate a property that camera might have like let's say the C frame of it and when we change the C frame of the camera it's literally going to move the camera in a specific point inside of the game so what we can do is say camera. cframe equals and we can just create a new cframe we can say cframe do new open close parenthesis we could just say 100 100 and 100 so you might think that this would work but let me show you what happens if we hit play so I'm going to go to test and hit play and what we should see is the game is still running basically as expected without executing the script it seems like but the problem that lies here is this code actually did run but the thing is roblox's default camera system overrode this command that we created here and so what we need to do is not have roblox's um default camera system override our scripts when we make modifications to the camera and so what we need to do is set the camera type to scriptable so if you're remembered um for the camera there was a property here for camera type and scriptable was actually one of them so this is what we need to set the camera type to before we make any scripting changes to the camera so what we're going to do is hit stop I'm going to go to the local script and before we make the cframe change what we're going to do is say camera. camera type equals in quotations we're going to say scriptable just like this and I'm also going to add a task. weight for about 1 second so that the game loads in in time before we make this change so now if we go into the game and hit play then what we should see is that our camera's C frame is now located at uh the coordinates 100 100 and 100 with X Y and Z respectively but we haven't changed like the angle of it or like where we're looking at in specific but this is essentially how we change the position of the camera inside of the game once we change the camera type to be scriptable so let's say we wanted to have a cutscene system where we have one starting point and one ending point for the camera to essentially go from the starting point to the ending point we can do that by manipulating the CF frame of the camera using our scriptable camera type and so what we can do is essentially create two points that go from point A to point B by simply just going to model I'm just going to insert a part over here I'm going to call this start and then I'm going to duplicate this and then move this somewhere that's semi far away I'm also going to change the the rotation of this just a little bit and I'm going to rename this one to end and so what we can do is have our camera's CF frame start here and then we can have the camera move into the direction of where the end part is over here and so that way we can create this sort of cinematic experience by going from the first part to the next part so what we're going to do inside of the local script is reference these two parts by dropping two lines and we're going to say local start equals game. workpace colon wait for Child open close parenthesis start and then we're going to do the same thing for the End by saying local end equals game. workspace colon wait for Child open and close parentheses end now I realized that Roblox is triggering a keyword here so I think we should say end part and start part instead of just start and end just like that so now what we're going to do is change the cframe of this camera to be the cframe of the start part so we're going to say start part. cframe and then what we can do is put a task. we for about 2 seconds and then we can say camera. cframe equals end part. cframe so if we go into the game hit test and hit play then it's going to start at this part like the start part C frame and then it's going to go to the end parts C frame just like that but it didn't do it in a smooth fashion like we literally hardcoded the C frame to change uh after about like 2 seconds but what we can do is add a smooth transition with tween service so what we can do is drop two lines above here and say local tween service equals game colon get service tween service and then what we can do is instead of directly changing the C frame just like this I'm just going to comment this out I'm going to create a tween and then play it by saying tween service colon create open and close parenthesis and then we're going to set camera as our object and then we're going to add a tween info object so we're just going to create one here by saying tween info. new open close parenthesis we're going to make this last for 2 seconds and then uh we're going to have a table full of the goals that we're trying to accomplish with this tween which in this case is going to be the C frame so we're going to set this equal to endp part. C frame just like that and then we're going to play this tween by saying colon play open and close parentheses by the of it uh we can even get rid of these two lines as well we don't really need them and now if we go into the game and hit play then what we should see is that it did like a little smooth transition with tween service by having the starting point go to the ending point just like that I can even show it to you again by waiting for two seconds before the script fires so 2 seconds have passed and it went from the starting point to its ending point and so that is essentially how we create this sort of transition with camera manipul ation and tween service now there's two rendering properties I want to show you that you might find useful but before we do I'm going to disable our local script and I'm going to select the camera so there's two properties I want to show the first one is focus and the second one is field of view field of view is a property that essentially tells us the extent to which we can see the world through our screen and basically what I mean is if we change this field of view from 70 to let's say 100 by increasing it then it's going to compress the screen vertically so that it feels like we can see more of the world than we can actually see um and if we do the opposite by changing this to something smaller like 40 then it's going to expand the screen vertically outward so that it feels like we're zoomed in and we can actually see something that's closer so a smaller fov would be useful if let's say we wanted to zoom in on something and then uh a bigger fov would be cool for something like if the user has like a shift to Sprint system and we want the player to see that they are moving Faster by changing the fov to something where we can see more of the world so that's basically what fov is I'm going to set this back to 70 and the other property is called Focus which is essentially a point in the world where we want roblox's graphical system to prioritize anything it needs to render within this specific Focus Point versus anything that's farther away from this Focus point now by default you don't really have to worry about this property because as you can see while I'm moving my camera the focus is being updated with the cframe of the camera and usually the focus property is synonymous with the cframe camera because when we have the camera subject be set to let's say the the player's humanoid then the focus point is going to be on the character's humanoid um but if we let's say had a customized system where we have a scriptable camera type we would have to change this Focus property manually and because this is being updated every single frame we would have to use run service to update the focus every single frame when we're using our uh own scriptable camera type and that's something I wanted to introduce to you that you might want to consider using inside of the future okay so now I'm going to show you what are called raycast Methods and how they apply with the camera now I haven't made a dedicated tutorial on rayc casting yet so whatever I talk about in this episode I'm going to be emitting the technical details of the ray casting part but I still want to show some methods that are very useful with the camera that I think you'd want to use for your game and one of those methods is called get parts obscuring Target now basically what this method does is we take a specific point inside of the game and we want to detect if there's any instances that are blocking that uh position inside of the game so let's say we take this spawn location right here and we want to get the position of this so with the position of the spawn location we want to check if there's any parts that are blocking it from the camera but as of right now we can see the spawn location but if we were to hide behind this wall right here then this is going to be a part that is obscuring this spawn location's position so we can do that through our script using this camera method and so that's what I'm going to be showing you how to add right now so what we're going to do is go to our local script I'm going to drop two lines well actually first thing we're going to do is we're going to comment out everything we've had up until this point and I'm also going to comment out this task. weight statement at the beginning but we're going to keep the camera reference so here's what we're going to do um we're going to say local Parts obscuring Target equals camera colon get parts obscuring Target open close parenthesis and inside of here it takes two parameters one of them is cast points and the other one is an ignore list so I'm going to explain what both of these are so cast points is basically a table full of these Vector 3 positions that I was mentioning earlier before with the spawn location now you can have more than one position if you want but I'm going to say for the sake of this example this spawn location position right here so what we're going to do is drop a line at the beginning and we're going to say local cast points equals game. workpace colon wait for child spawn location and then we're going to wrap this with uh curly brackets to make this a table so this is our cast points and we can pass this in as the first parameter so we're going to say cast points just like this and now the second thing is an ignore list an ignore list is basically a table full of instances that we don't want to include uh for when we're detecting if there's a part that's obscuring the cast Point position that we're interested in so let's say for this part right here if we add this to the ignore list then we can still see this part's location because we added this to the ignore list so we can do that in our local script by saying local a nor list equals open and close curly braces and then we can add that inside of our second argument just like this now there is going to be a problem with this ignore list so now what I'm going to do is I want to be able to demonstrate this inside of Roblox studio and the best way we can do this is by using run service so that we can get a frame by frame uh representation inside of the output so here's what we're going to do we're going to say local run service equals game get service run serice run service just like this and what I'm going to do is say run service do hardbeat colon connect function open close parentheses enter and I'm going to take this line and paste it inside of here now what I'm going to do is check if the number of instances that we get that are obscuring the target is greater than zero so that tells us if there is at least one part that's blocking our Target so we're going to say if uh pound symbol parts of scaring Target is greater than Z then we're going to print something is blocking the Target and then what I'm going to do is print out all the parts that are blocking the target so we're going to say for I comma part in I pairs open and close parenthesis Parts obscuring Target do and then we're going to print the part itself and then to separate every single time we check this we're we're just going to separate this using uh a couple dashes Okay so here's what we have so far let's go into the game and hit play now there is going to be a problem with this so right now oh hold on the script is not working oh my bad there was a typo on my end um so we're supposed to say spawn location. position because this is a table full of vector 3 values we're not putting in the instance themselves so now if we go into the game and hit play there should be a problem here and I'm going to show you why so it says in the output that there is something that's blocking the target which is the spawn location itself that's because for the cast points we're interested in the position of the spawn location not the spawn location itself so what we need to do is add the spawn location to the ignore list so that it's not counted when we are looking for parts that are scaring it so I'm just going to copy this line here and I'm going to paste it inside of the ignore list and now what we're going to do is hit play so the spawn location should not be included with any part that's obscuring it um so now if we look at what's happening here uh what I'm going to do is block the spawn location using this part and so now it's going to say that something is blocking the target which is um this part right here uh I can even stand in front of it and there's going to be a bunch of hats and accessories from my avatar that's blocking this spawn location as well and it's being displayed in the output here every single frame and so this is essentially what this function does and you can definitely find usefulness with this function so this is something I wanted to introduce to you that you might that you might want to use for your games okay the next method I want to show you is called world two screen point now the idea behind this method is that we want to take a vector 3 position of whatever part that's inside of the game and we want to convert that to a 2d position or a vector 2 value that's going to be displayed on our screen uh that's relative to the camera as well so let's say we had this part that's right over here and we wanted to take that Vector 3 position of this part and convert it to a screen position that's going to be displayed on our screen so that's essentially what this function is going to do now instead of coding this up I'm going to show you a really practical example of this so that you get an idea of what I'm talking about okay so this video demonstrates what I'm talking about and essentially What's Happening Here is that there's all these coins that are scattered across the map and when the player picks up the coin then it's going to convert the vector 3 position of that coin and give us a 2d position of that part that's on our screen that's relative to the camera and then it's going to create this uh image label of a coin and display it at that position and then it's just going to fly off to the screen once it's done but this is essentially what I'm talking about when it comes to converting a 3D point and converting it to a 2d point on the screen and this is a really practical example of using this function which I want to give credit to my admin for creating this and also for creating the script as well so essentially it returns so essentially World 2 screen Point takes one parameter which is uh the position of the coin that was being picked up and then it returns a vector that gives us the X and Y components of the 2D screen and this is a Boolean that tells us whether this actually fits on the screen or not and then it creates the coin image label and shows it on screen so then as you can see we take a udm 2 value and we use the vectors X and Y component to change the position uh of the the image label for the 2D screen so this is a little practical example I wanted to show and I hope that this gave you insight into using this function now there is another method called World 2 viewport frame but this is literally the same exact method as World 2 screenpoint but there's only one difference and that is we're not taking into account the guy inset that is built into every single Roblox game unless the developer specifies not having this GUI inset and what I mean by this GUI inset is that Roblox reserves a specific uh amount of space on the top of the screen for their own own customized UI like these buttons over here and so with this function over here we're essentially ignoring this top part here when we're using World 2 viewport frame so that's the only difference and I think it's a pretty nice distinction uh from the two functions so depending on which one you use I hope you find practical use with these functions and I hope you found this part to be informative so for today's challenge I want you to create this spectate mode GUI system where we have a button here that says spectate and if we click on it then it's going to show this little panel here that displays what player we're currently spectating and we can click these arrows to flip to different players perspective so that we can spectate them so if I press this right button then it's going to change the camera to reflect on this player's humanoid instead of my humanoid and then if I were to uh flip it back to my character then it's going to change my camera to reflect my character's humanoid and so we can do the same thing going reverse and we can do the same thing going forward so this is what I want you to create for this Challenge and for the sake of time so once you've given this a try then we can come back and dive deeper into this spectate mode GUI so for the sake of time I'm not going to be coding this with you step by step but I will show you what I did with my code so that hopefully it can give you a better understanding of how this system works so what we have here on the right side is a spectator screen GUI so if I open this then there's going to be a local script a frame and a button so the spectate button is the button down here and then spectate frame is the the little panel that shows the player's name that we're currently spectating and the left and right button so it can flip through different players so if I open this up there's a left button a right button and a text label that tells us the player's name that we're currently spectating so I'm just going to disable this and now we're going to analyze the local script behind it so basically what we have going on here is a player list that gives us a table of all the players that can spectate and then this position is the index value of the player that we're going to be viewing inside of the spectate mode GUI and there's two functions here so the first one is update player list this one just takes our player list and updates it with all the players that are currently available and then update camera is what allows us to change the camera subject of our current camera to whatever the player that we're currently spectating is to whatever player we're currently spectating and we get their humanoid with that and then we change the the text of the player name of that as well okay so once we press the spectate button so this button down here then it's going to update the player list automatically and it's going to give a check as to whether we are currently spectating and if we are then we're going to set that equal to true we're going to make the frame visible and we're also just as a safety measure we're going to make the character not be able to move while we're spectating and we're going to set the position automatically to one and then we're going to use update camera with the player that lies in the the position of one and if we're not spectating then we're just going to let the player move we're going to disable the frame and we're going to let the player have control again since we're not spectating anyone okay so that is what happens when we press spectate button so if we press the right button so if I were to load up the frame again it's this button right over here it's going to check whether we are spectating and if we're not then it's just going to return the function we're going to update the list again and then essentially What's Happening Here is that we're going to be updating the position before we update our players camera to that uh position inside of the player list so essentially What's Happening Here is that and if this increment is greater than the size of the player list then we're going to be going out of bound and we don't want to do that so what we do is we set the position back to one so we're essentially resetting it and if we're not going out of bound then we're just going to Simply take the position and add one to it so that we're flipping through the players of the player list and so that's what we do when we update the camera and we're essentially doing the same thing with the left button where we press it except this time instead of going forward we're going backwards so we're going to take the position and we're going to subtract it by one and we're going to see if this is less than one because if we have a value of zero well there's no such thing as an index value of zero so this is not going to work so if this is the case then we're going to set the position to the size of the player list so we're going to start backwards and if that's not the case then we're just simply going to decrement the position by subtracting it by one and then once again we're going to be updating the camera and that is essentially the rundown of this spectate GUI script and I hope that this explanation has helped you with understanding how this system is created so that's pretty much going to be it for this episode if you found this video to be very helpful then I encourage you to leave a like on this video And subscribe to the channel if you haven't already uh I would also like to give a shout out to all of my patreon members for supporting the work that I do and providing me with continuous support as well um I appreciate them a lot and if you want to have access to my scripts get early access to the videos then I encourage you to become a patreon member as well um your support would be very appreciative and if there and if you're still confused about some of the concepts that we talked about like C frames then I will have a link to that video for you right here to watch so go ahead and watch that if you haven't already also you can check out the other videos that are in my Advanced scripting tutorial guide and with that being said that's going to conclude this episode I will see you in the next one take care