Building a Camera Controller for a Strategy Game

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments

Pretty neat tutorial! You got yourself a new sub.

👍︎︎ 3 👤︎︎ u/cesena96 📅︎︎ Jun 24 2019 🗫︎ replies
Captions
game cameras are a complex beast for many players how your camera feels to use is key to giving them a positive response to your game if you know anything about me you'll know I'm a huge fan of simulation and strategy games and I found a good number of these games do weird things with the camera look at this game this game rotates around the center of the world look this one does it too doesn't that feel nice then we have this one which are you going left perhaps it's personal preference but when I enter into a simulation game and I'm looking down at the world but my camera controls act like I'm in first person it's just a little bit jarring screw you in your gut damn trains so fellow developers please stop designing of strategy game camera with the first-person controllers these engines give you out of the box 99% of the time it's not a suitable way to interact with your game it just feels weird and janky and it's infuriating to control the camera should be world relative hi there I'm Matt and welcome to game dev guide in this video we're going to take a look at building a camera system you'd expect to find in a simulation strategy game we're going to look at how we set up our camera so that it can be moved while maintaining a centered focus point on screen we're then going to look at how to extend these features to allow for smooth zooming and panning with an also going to build a focus feature that will allow us to keep the camera locked onto and follow a game object in our game before we get started though I just want to remind everyone about the game dev guide discord server it's full of all ranges of viewers and developers from the community or raising interesting questions and sharing their work with everyone I've even managed to see some of the cool stuff you've been creating based off of these videos which is always absolutely amazing to see and as a bonus if you join you'll even get to be able to influence some of the content on this channel as I'm regularly putting questions to members about what they'd like to see including the content in this video so if you want to be part of a growing community over on discord there's a link in the description below to join now let's get started building our camera system here's a scene you might see in a typical strategy game it's a city made up of assets from the low-poly city pack and will be perfect to use to build our camera system so a big thing I think a lot of these games get wrong is that they move relative to the camera itself rather than what the camera is looking and this makes sense right if you're in a first person game that's what you want we rotate the camera it simulates somebody turning their head which is fine for a game where the player is positioned directly into the world well strategy games are more omniscient and godlike the player is probably expecting to interact with the world as if it's a physical object in front of them so we want our camera to simulate the world moving rather than the camera moving this is actually quite simple to achieve all you have to do is rig the camera to a parent object and then offset the camera pointing it towards the center of this rig then instead of moving the camera we move or rotate the rig itself so let's create a new game object and call it camera rig let's then place it here at about 120 where the Z position of 60 and we'll set the height to about 10 so it's a little off the ground then let's place our camera inside the rig and bring it to the center by clearing the transform here now let's rotate the camera about 45 degrees in the x axis and then let's move the camera back to about 50 if we grab the blue forward handle here we can see that the Y position and Z position move in the opposite direction to one another this is a forward distance which acts as the zoom for our camera rig so the zoom is essentially how far away our camera is from the base of the rig all right so let's get started writing a script that will allow us to move our camera around let's select our rig and create a new script here called camera controller let's create a public float at the top here called movement speed and another cool movement type let's also create a vector3 called new position in our start method we'll set the new position to the transform position so that our transform doesn't automatically default to zero and then below let's write a new method called handle movement input in here we'll get the keyboard input from the player if inputs dot get key key code dot W or input get key key code dot up arrow just as a side note so many games vaak input to either wised or arrow keys and not both and if you do this players like me will be annoyed at you so always support both please thank you in here we'll make the new position the forward direction of the rig x the movement speed so new position plus equals transform forward x movement speed then let's simply handle this for the other directions [Music] [Music] then rather than just setting the position of the transform which I feel is kind of rough let's actually interpolate between the current position and the new position to get a smooth movement transform position equals vector $3.00 transform dot position new position time.deltatime multiplied by our movement time and then finally in our update we'll actually call this method now back in unity let's set the movement speed to 1 and let's set the time to about 5 as you can see we've now got a nice smooth movement of the camera and we can play with the values here in the inspector to adjust how it feels it's also pretty common in a game like this to add a fast-forward mode for the camera so players can move long distances quickly let's also add that into our script so we'll create a public float called normal speed and another public float called fast speed at the top here then back in our input method let's determine the speed based on if the shift key is down on so if our Shift key is down let's use the fast speed here otherwise let's use the normal speed then back in unity let's just set our normal speed to not 0.5 and our fast speed to 3 and as you can see here if I move with the shift key down it's nice and fast and if I let go is face down so we give the player much more control about how they move around our world now I would be criminal if I didn't spend a minute talking about the projection mode classic Tycoon and management games were loved for their orthographic style and that might be something you're going for so to replicate that look let's stick our camera into orthographic mode and set the size here to about 30 then let's set the Y rotation of the rig to about 45 degrees and just like that we've got our classic Tycoon management shot so I was actually designing a game camera like this myself until I started looking at a few other games and realized something I was playing to point hospital when I noticed that while I was under the impression the game was using orthographic camera it was in fact actually using a perspective camera the easiest way to tell is because with an orthographic camera all of the points of geometry are parallel so you can tell when a game is perspective or not because as you move the camera around more geometry becomes visible such as sides of walls or objects around corners you can also notice a field of view change when the camera is fully zoomed out looking over the hospital and Here I am realizing that this game has done something really clever with their camera to replicate the old-school orthographic style but still adding a small amount of depth essentially an orthographic camera is just a perspective camera with a field of view of zero so with our camera here if we switch back into perspective mode and set our field of view much closer to something like 10 and then move our camera way back like so you can see that we've got a sort of pseudo isometric style and so if I swap between the two here you can see the difference if I move the camera around a bit you can really see the difference between the two the perspective shot has that extra bit of depth that really makes a 3d environment pop a bit more I really like it okay so our camera is moving nicely but right now it's stuck at this one angle it would be really great if we could rotate it at the top of our script let's add a new quaternion called new rotation and a float called rotation amount then in the start method our new rotation will be the same as the rotation of our rig and in our input method let's add to our new rotation if the player pressed the q or e key so input get key key code q new rotation x equals quaternion dot Euler vector three up x rotation amount and then for the other direction if inputs get key key code e new rotation x equals quaternion Euler vector three up x minus rotation amount and again let's let up this so it's nice and smooth transform rotation equals quaternion Doppler transform rotation new rotation time.deltatime x the movement type and then let's set our rotation amount to one here and if we play we can see a nice smooth camera rotation finally we're probably going to want to add support for zooming the camera in our script let's add a reference to the transform of our camera called camera transform a new vector3 called zoom amount and another good news oom and in our start method we'll get the new zoom from the current local position of our camera transform we need to use the local position because we want to make sure that it stays relative to our rig then in our input method let's add our zoom so if input get key keycode our new zoom plus equals zoom amount if input get key key code F new zoom minus equals zoom amount and again let's lab that camera transform local position equals vector three camera transform local position Newseum time.deltatime x movement type and then in unity let's assign our camera and set our zoom amount to minus ten ten and now as you can see we've got a pretty functional strategy camera complete with movement rotation and zoom great now I could end this here but let's be honest keyboard controls aren't always ideal and as you know I never do things half-assed on this channel let's take a look at how to interact with the world using the mouse in our script let's create a new method called handle mouse input [Music] and we'll add that to the update method now we could simply get the mouse position when pressed down and move the camera according to the difference here however due to the potential rotation of the camera and the rig we've got I found it feels a bit janky to do it that way instead we want to simulate the player actually clicking and grabbing the world pushing or pulling it in any direction of their mouse cursor so we're going to create a plane in our world and cast a ray from our camera to get a precise point in the world that the player has clicked and then calculate the difference that way at the top here let's create two vector threes drag start position and drag current position then in our handle mouse input method let's check if the left mouse button has been clipped in here let's create a plane plane equals new plane vector three up back to 3.0 and we'll create a ray from the mouse position on the screen equals camera main screen point two ray input Mouse position then let's create a float which we'll use to get the entry point of the raycast and we'll do our ray cast on the plane [Music] then we'll set this point as our start position [Music] next we'll check if the mouse is still held down and if it is will do another ray cast so let's copy this and paste it in here and instead we'll assign the entry point to our drags current position finally we'll assign the new position by getting our cameras current position and then adding the difference between the drag positions now back in unity thanks to the mouse input and the looping we've already built into our camera movement you can see that we can easily click drag and flick our world around nice and smoothly while we're here let's add some Mouse soup at the top of our input method let's add if input mouse scroll Delta Y doesn't equal zero new zoom plus equals input mouse scroll Delta Y times zoom amounts and with just a couple of lines we've got zooming working on the mouse wheel great the last thing we want to attach to our mouse now is rotation to the top layer let's add two new vectors rotate start position and rotate current position and then in our mouse method let's add if input get mouse button down and we'll use the middle mouse button rotate start position equals input Mouse position and then if the mouse button is still held down rotate current position equals input Mouse position and then we'll calculate the difference and we reset the drag position for the next frame and then we'll create a new rotation based off of the difference so new rotation x equals quaternion Euler vector three up x negative difference X divided by five we negate the value here so that the world spins in the counter direction to drag I just think it feels much more natural this way as you can see here in unity if we now drag and pull this way the world spins in the opposite direction to the mouse as if we've spun the base of the world right so that's the gist of our camera controls the one final thing I'd like to do is allow the player to focus on an object and have it take possession of the camera something you'd likely expect to find in most management or strategy games so I've got this car here that's moving around and I want the camera to follow it when it's clicked I set that up in our camera controller at the top here let's add a transform called follow transform then in our update method let's check if the follow transform is active and if it is let's set that as our current position otherwise let's allow for the input then let's also allow the camera to be unfocused by setting the follow transform to null when Escape is pressed now finally we just have to tell our object to set itself as the follow transform on our camera when it's clicked so freeze of access let's create a singleton reference on our camera here [Music] then let's create a quick script here on our vehicle we have a Collider on the object already so let's add the onmousedown method and set it as the anchor point camera controller dot instance dot follow transform equals transform now as you can see we have a very simple follow function for our camera if we click the vehicle our camera jumps over to that and then if we hit escape the reset camera now this probably doesn't cover every use case but hopefully it gives you some ideas of things you can do and more importantly you understand the importance of world based navigation rather than the awful first-person navigation that absolutely does not belong in a strategy game I'll get off my soapbox now that's it for this guide I hope you found it useful let me know what you think in the comments and if you've enjoyed this video be sure to hit that like button if you're new to the channel and want to see more tips tricks and tutorials from me then please hit that subscribe button or check out some of the other videos already on the channel as always thank you very much for watching and I'll see you again next time [Music]
Info
Channel: Game Dev Guide
Views: 101,732
Rating: undefined out of 5
Keywords: unity, learn, games, gamedev, how to, making games in unity, tutorial, unity tutorial, learning unity, unity3d tutorial, programming, making games, camera, simulation, strategy game, management game, camera controller, unity camera, camera rig, game camera rig, game camera, orbital camera, camera system, rts camera
Id: rnqF6S7PfFA
Channel Id: undefined
Length: 17min 47sec (1067 seconds)
Published: Mon Jun 24 2019
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.