- 2 months ago
In this video, we will create a camera system to pan the camera when we put the mouse pointer to the screen edge.
A standard mechanism in most RTS games and Isometric RPG games. We will create the system using Unity's new input system.
Project files https://www.patreon.com/posts/138934419
Environment Asset https://assetstore.unity.com/packages/3d/environments/landscapes/mountain-stylized-fantasy-environment-307488
Do you want to support my work? The best way to support this channel is to buy my game on Steam. https://store.steampowered.com/app/2527340/Cosmic_roads/
Alternate ways to support!
https://www.patreon.com/DigvijaysinhG
https://github.com/sponsors/DigvijaysinhGohil
A standard mechanism in most RTS games and Isometric RPG games. We will create the system using Unity's new input system.
Project files https://www.patreon.com/posts/138934419
Environment Asset https://assetstore.unity.com/packages/3d/environments/landscapes/mountain-stylized-fantasy-environment-307488
Do you want to support my work? The best way to support this channel is to buy my game on Steam. https://store.steampowered.com/app/2527340/Cosmic_roads/
Alternate ways to support!
https://www.patreon.com/DigvijaysinhG
https://github.com/sponsors/DigvijaysinhGohil
Category
📚
LearningTranscript
00:00Today, I will create a simple camera system to pan the camera when we put our mouse pointer
00:05on the screen's edge.
00:11A standard mechanism present in most of the real time strategy games or an old school
00:17isometric RPG title like Geneforge.
00:20Man, I'm old.
00:25Anyway, for the tutorial, I'm using Unity 6.2, but it will work just fine on older versions
00:31as well.
00:32And I will be using Unity's new input system.
00:35Now without any further ado, let's get the video started.
00:39Okay, so I have the stylized environment scene which I've downloaded from the asset store.
00:45I will put the link in the description so you can download it, but it is just there for
00:50the aesthetics.
00:52Now the very first thing is, let's define inputs for our game.
00:56So for that, I'm going to create a new empty folder.
01:00Let's call it inputs.
01:03And in here, let's create a new input action map.
01:06So create input actions.
01:10Let's call it game input actions.
01:15And double click to open our asset.
01:18Then in here, we will define a new action map.
01:21So hit this plus button.
01:24And let's call it mouse.
01:27And for the actions, I'm going to rename this new action.
01:30So let's call it move.
01:33And for the action type, I'm going to select value.
01:37And for the control type, I'm going to select vector 2.
01:41Because our mouse position will be of type vector 2.
01:45Then in our actions, let's define a new binding.
01:48So let's select this path.
01:51And select our mouse.
01:53And select this position.
01:56And this will be all of our inputs for this project.
01:59So hit the save assets button.
02:02And let's close this window.
02:04Then select our game input actions.
02:07And select this generate C sharp class.
02:11Then hit this apply button.
02:14And it will generate this new game input action script where all of our input actions are defined.
02:21Now in my projects, I like to create a separate script to listen to the player input.
02:26So first, let's create a new empty game object in our scene.
02:31The control shift and end is the shortcut.
02:34Let's call it game inputs.
02:38And let's reset its transform.
02:40And I also like to keep it on the very top of the hierarchy.
02:45Then let's create a new script with the same name.
02:48So first, I'm going to create a new empty folder.
02:52Let's call it scripts.
02:57And let's create a new mono behavior script.
03:02Let's call it game inputs.
03:05And let's assign our script to our game inputs empty object.
03:11And double click to open our script.
03:14In the script, I'm going to get rid of everything.
03:18Then here, let's grab the reference for our game input actions.
03:22So private game input actions.
03:27And let's also call it game input actions.
03:31Then let's initialize our game input actions in the awake method.
03:34So I'll simply go awake.
03:37And here, let's go game input actions equals new game input actions like this.
03:43Now in our game input actions, I've created that mouse action map.
03:47So I have to enable it here.
03:49So I'll simply go game input actions dot mouse dot enable.
03:55So with this line, I will be able to use the actions defined in this mouse action map.
04:02Now one important thing to notice, once you enable an action map like this, and after that,
04:09if this game input's game object gets destroyed for whatever reason, for example due to scene
04:15change, then it will cause a memory leak.
04:19So it is a good idea to disable the action map in on destroy method.
04:24So let's do that.
04:27On destroy.
04:28And here, I'll simply go game input action dot mouse dot disable like this.
04:34Now let's create a public method to read the mouse position.
04:37So for that, here I'll simply go public.
04:41And it will return vector2.
04:43Let's call it getMousePosition.
04:46And here, I'll simply go return game input action dot mouse.
04:53And our action was move, so dot move.
04:56And simply go read value of type vector2.
05:01And this will be all for our game inputs class.
05:04And now let's create a script to actually pan our camera.
05:08So for that, let's create a new MonoBehaviour script.
05:14Let's call it cameraPan.
05:17And I'll attach this script on my main camera itself.
05:24Like this.
05:25Then let's open our script.
05:27Then first, I'll get rid of everything here as well.
05:33Now here, first thing we need is the reference to our game inputs.
05:37So for that, I'm going to create a field.
05:39So private game inputs.
05:44Let's call it game inputs as well.
05:47First, I will assign it from the inspector.
05:49So let's add a serialized field attribute here.
05:53Like this.
05:54Save.
05:55In unity, select the main camera.
05:58And in the inspector, you will see this game input slot.
06:01Simply drag and drop our game inputs.
06:05Like this.
06:06Then in our camera pan script, let's first simply print our mouse position.
06:11So in the update, I will go vector2 mouse position equals game input dot get mouse position.
06:23Then I'll simply go debug dot log mouse position.
06:30Like this.
06:31Okay, so let's test.
06:33And here I will be in a way.
06:36So let me drag this console window here.
06:39So you can see that we are printing the mouse position.
06:44So at the bottom left of the screen, we will have 00 and it will go up to the screen resolution
06:54at the top right.
06:57So currently this mouse position is going from 00 up to my screen's resolution.
07:02But what I want is, I want 00 in the middle of the screen and I want it to go from minus
07:080.5.5 to positive 0.5.5.
07:12So first let's make our mouse position to go from 0 to 1.
07:17So to make this mouse position go from 00 to 11, I'll simply divide my mouse position
07:23with the screen's resolution.
07:26So I'll simply go vector2.
07:29Let's call it screen uv new vector2.
07:35And I'll simply go mouse position.x and I'll divide it with screen's width.
07:41So simply go screen.width and mouse y divide it with screen.height.
07:53Alright now instead of mouse position, let's print screen uv.
07:57Okay, so at the center of the screen, it's printing 0.5.5.
08:03And if I put it bottom left, yep it's printing 00.
08:09And if I put it to top right, it's printing 11.
08:14So our logic is working.
08:16Alright now I want my screen uv to go from minus 0.5 to 0.5 instead of 0 to 1.
08:23So for that I can simply subtract 0.5 from both our x and y components.
08:28So I'll simply go minus 0.5 minus 0.5.
08:38And by the way I wrote it like this to avoid a new vector2 call here.
08:43Like this, minus new vector2, 0.5, 0.5.
08:48So that the garbage collector will have to work a little bit less.
08:54Anyway let's test again.
08:57So you can see that in the middle of the screen we are printing 00.
09:01And at the bottom left it's going minus 0.5 minus 0.5.
09:06And at the top right it will be printing 0.5, 0.5.
09:11And now I will simply check if my mouse position is less than some threshold.
09:17And based on that I will move my camera.
09:20So we no longer need to print this screen uv.
09:25And I'll create a new constant float so private constant float.
09:33Let's call it edge threshold and let's set it to 0.45f.
09:42Then in the update I'm going to create a move vector so vector3.
09:47Vector3 because our camera is in 3d space and we will move it on x and z axis and not
09:54up down.
09:55So simply vector3 move and let's set it to 0 initially so vector3.0.
10:04Then here I'll simply check if green uv.x is less than negative edge threshold.
10:13If so I will simply go move.x equals minus 1f.
10:20By the way for a single statement if I like to write it like this.
10:24Then again let's check if green uv's x is greater than positive edge threshold then
10:32simply go move.x equals 1 like this.
10:36And we will do the same thing for the vertical axis so again if screen uv.y is less than negative
10:45edge threshold.
10:46Then this time go move.x equals minus 1f.
10:53Then again if screen uv's y is greater than edge threshold then move.x equals 1.
11:03And now we have our move vector based on that let's simply move over camera.
11:08And this camera pan is sitting on our camera so I can simply go transform.translate and
11:17pass in our move vector.
11:20And let's also make our movement frame independent so simply multiply it with time.deltaTime.
11:27And to control the pan sensitivity let's create a new serialize field so here simply go serialize
11:34field private float move sensitivity or move speed and let's default it to 10.
11:45And let's multiply it here.
11:47So move speed.
11:51Now one instructive thing this move is a vector 3 and these two values are float.
11:57So when we write it like this it will go over vector 3 multiply float.
12:04So this time.deltaTime will multiply with all three components of our move vector.
12:10So that's 3 multiplication and the result of that will be vector 3.
12:16And it will again multiply with this move speed.
12:19So total 6 float multiplication.
12:22So if I write it like this.
12:31Now it will go float multiply float.
12:34So that's one multiplication.
12:36And then multiply vector 3.
12:38So that's 3 more.
12:39So we just saved 2 float multiplications.
12:42So a nice optimization tip.
12:45Although it doesn't matter in the long run.
12:48But hey.
12:49Alright.
12:50Let's test.
12:51So if I put my mouse pointer to the right side of the screen.
12:54Yep.
12:55It's moving correctly.
12:57But if I go left.
12:59Yep.
13:00But if I go up.
13:02So now the camera is zooming in and zooming out.
13:07So what is happening is my main camera has some rotation.
13:13So on the X axis it's going perfectly like this.
13:19But on the Z axis it's moving like this.
13:23So we don't want that.
13:27So when we move the main camera on the Z axis.
13:30I want it to move parallel to the XZ plane.
13:34So our logic would work just fine if there was no rotation on the X axis.
13:40So our camera would work just fine in the Z axis as well.
13:45Now there's million ways to fix this.
13:48But I'm going to rotate the move vector based on the Y rotation of our camera.
13:55So in our script here I'll go move equals.
13:59And then I'm going to create a quaternion based on our camera's Y rotation.
14:04So I'll simply go quaternion.euler.
14:08Then on the X pass in 0.
14:11Then for the Y I'll go transform.eulerangles.y so our camera's rotation.
14:19And for the Z I'm again going to pass in 0.
14:23And now I can rotate my move vector by simply multiplying it with the quaternion like this.
14:29And it's good idea to normalize the move vector as well.
14:33So that when we move diagonally the speed will be consistent.
14:38And then in this translate method I'm going to pass in new parameter called space.
14:43So space.world.
14:46So this simply means move our camera relative to the world space.
14:52Alright let's check.
14:53So to the right.
14:54Yep.
14:55Left.
14:56Up.
14:57Down.
14:58To the diagonal.
15:00So yes.
15:03Our logic is working.
15:05Pretty cool.
15:06And there we have a nice camera pan system.
15:10Hope this was useful.
15:12And now as usual.
15:13Like the video.
15:14Share.
15:15Comment.
15:16Subscribe.
15:17Check out my patreon.
15:19That's it from me.
15:21And I'll see you in the next one.
15:23Bye.
15:24Bye.
15:25Bye.
15:26Bye.
15:27Bye.
15:28Bye.
15:29Bye.
15:30Bye.
15:31Bye.
15:32Bye.
15:33Bye.
15:34Bye.
15:35Bye.
15:36Bye.
15:37Bye.
15:38Bye.
15:39Bye.
15:40Bye.
15:41Bye.
15:42Bye.
15:43Bye.
15:44Bye.
15:45Bye.
15:46Bye.
15:47Bye.
15:48Bye.
15:49Bye.
15:50Bye.
15:51Bye.
Recommended
5:06
|
Up next
11:33
19:47
17:26
17:50
11:14
11:28
17:51
19:23
5:43
18:21
5:57
16:43
13:05
Be the first to comment