Isometric movement may seem easy at first, until you realize your character does not move according to your input... I show you how to skew your navigation input to allocate for the rotation of the camera.
DISCLAIMER: I missed a few things in the video which are corrected in the script below.
Isometric camera setup: https://www.youtube.com/watch?v=optfGhipg-w
🔔 SUBSCRIBE: https://bit.ly/3eqG1Z6
🗨️ DISCORD: https://discord.gg/GqeHHnhHpz
✅ MORE TUTORIALS: https://www.youtube.com/tarodev
0:20 Gathering Player Input
1:05 Moving a Character
3:00 Rotating a Character
7:10 Fixing Isometric Navigation
in the last video i quickly showed you how to set up an isometric camera in this one i'll be creating an isometric character controller a common problem devs often face using an isometric camera is that standard input moves the character across the isometric plane which feels awkward the player expects the character to move up the screen when they press up so we'll address that also so let's get stuck in the first thing we'll do is create a new script here called a player controller and then let's open that up okay so i'm going to do this in a few steps the first step is to gather the player's input so gather input and in here we're going to assign a value to a vector3 so let's create a vector3 here just call it input so then here we'll say input equals new vector3 for the x it will be input dot get axis raw horizontal for the y it's going to be zero because we're not moving on the y plane and for the z will be uh input get axis raw uh vertical and that's all we need there and then we need to actually move so let's create a new function here called move and now also let's actually call this so in our update function let's call gather input whoops gather input and then uh in our move we're well i am going to be using a rigid body just so that we can take advantage of colliders and collisions and physics and all that good stuff so i'm going to create a serialized field here private rigid body just call it rb and in here just to demonstrate let's just use rb move position and we'll take in our current transform position plus let's say our transform forward position and then let's serialize another field here so that we can uh adjust our speed at run time float this would be called speed let's default it to five so then we'll times this by speed times time dot delta time and as we're uh affecting our rigid body here and using physics let's put this in fixed updates so we'll just call move right there cool so uh right now this is being ignored but let's just test that this in fact does work so on our player here and as you can see i've got some glasses here just to indicate that that's the front of our player i'm going to attach my player controller i'll add a rigid body i'll add a box collider and we'll never be moving on the wire so i'm just going to freeze that position chuck in my rigid body and this should work yeah cool and it should collide excellent so for our movement i figured what would be best instead of just pressing the wasd or like a key a joystick and just strafing all over the place i thought it would be more fun to only allow the player to move forwards and backwards and if they want to change direction they've actually got a turn to face that direction to me that feels like a better controller than just being able to strafe so i am going to create a new function here called look so this will be changing our look direction and just before i forget i'm going to put that straight under uh gather inputs in our update function so the first thing we want to do here is find the relative difference between us where we are now and where we want to be so let's uh find the relative i'm just going to call it relative and i'm going to put this in brackets transform position plus and we can now put in our input here so this will be our current transform position plus whichever way we're pressing on the uh keypad uh minus our current transform position and that will find the relative uh dista angle between us and then we can actually turn that into a rotation so quaternion look rotation and just send in relative uh actually we'll also need to send in up so basically we're saying that's our up direction and we want to we're wanting unity to rotate us around that axis okay and now as now that we've got our rotation we can say transform rotation equals rot cool so now uh of course we're just going to be moving forward non-stop but we'll at least be able to change our direction now so let's see how that works and yes we can indeed but one problem is when i let go of my joystick you can see that it flips back and that's because down here it's as soon as we take off our input this is going to be input is going to be zero so it's going to just flick back to that so that's not desired so what we can do is we can say if input uh does not equals zero that is the only time we want to uh actually do that and just to make sure that works let's see yep so now we can keep our direction and it all works just fine excellent okay so in our movement we obviously don't want to be just moving forward forever so what we can do here is we can take this and i'm going to put that in brackets transform forward times input.magnitude so when that's 0 no input it's just going to be 0 and we're not going to go anywhere and uh depending on it doesn't we we don't actually care which way we're actually uh pointing our joystick we just care that uh a number is being displayed okay so it's just giving us the length of the vector whatever that may be let's try that yeah beautiful so now it is uh stopping and starting when we want but as you can see sometimes when i'm letting go on my stick it's like flicking to another direction and that's because my joystick is snapping over to the other side for one second and our rotation is being set immediately so that's not really the best so instead of just setting it directly to this let's add a little bit of lerp to it so quaternion rotate towards and we're going to send in our current rotation and then the goal rotation is the rot and now we need max degrees delta so how fast we would actually like to spin private float and this will be our turn speed and let's say we want one full rotation a second so then here we'll go 10 speed times time dot delta time all right let's try that out and there you go now you can see it's like much smoother now when i let go of my stick i'm not getting any snappy movement it's just exactly what we want now the main problem uh in an ico game when i'm pressing up i'm actually going this way and when i'm pressing left or right i'm going up that way right and we really when we want to press up we kind of want to go up this way don't we okay so it's a little bit tricky to fix this but it's actually not too much code so basically when you're looking at your normal uh coordinate system right you've got like uh upwards will be y plus one and then down will be y y minus one and then left will be x minus one right um and then you've got all the in between so that's we can refer to that as a matrix okay it's a matrix of values uh what we can do now is we can make our own little matrix just to hold these values equals matrix 4x4 rotate now this is a little function that they give us nice and handy and say we put in quaternion identity right so no rotation this will give us our stock standard coordinate system completely normal not changed and if we actually use this it would give us the exact same results that we've got now because when we press up we're going y up right and that is actually the correct direction up that way but because we're skewed 45 degrees we also need to rotate our angle 40 by 45 degrees so instead of quaternion identity let's put in quaternion euler 0 45 0. and i swear i say this word different every single time but bear with me so now that we've got our matrix we can now create our new uh rotation to use instead of input here we can we can grab our skewed input and in fact that's a good way to that's a good um variable name so skewed input equals matrix multiply point three by four so we're multiplying our matrix by our vector okay and our vector is in fact our input okay so now that we've got our skewed input we can use that in place of our normal input and we don't actually need to use it down here because we're just using the magnitude of our input here it will be the exact same with our skewed input or otherwise so with just that if we just press play now we should see that we now have proper iso movement by the way staring at a sliding cube makes it look a little bit lackluster so here's a little video of this controller in action with a model attached to it very nice works works beautifully and if if i just hold my joystick a little bit we'll see that because we're using the magnitude we can control just how fast our player goes so it's actually i mean it's it's not many lines of code but it's a very it's a very simple nice feeling controller you could potentially add a little bit of acceleration here now one thing uh this is being called every single frame yet it never ever changes okay we don't need to perform this every single frame not only that we might want to use this calculation across heaps of objects on our scene we never know right so let's uh move this to somewhere more reusable and whenever i make extension methods i always put them in a script called helpers depending how many i'm going to have if i've got like a whole bunch that's going to be really specific to something i'll call that script something specific but uh for now i'm just going to call it helpers so open it up uh let's remove this it's going to be a static class and we won't need our mono behavior so then here let's uh cache this value so let's plonk that in there this will be a private static type of matrix 4x4 and let's actually call this our iso matrix like that and then to actually get the value let's do public static this will return a vector3 the skewed 3 2 iso and this is an extension method so i'm going to use this k word and it's going to be on a vector3 and that's our input there actually let's call it input because we don't know that it's going to be a dir a direction um and then we will return uh iso matrix multiply and then send in our inputs and there we go so there's our reusable extension method so then we don't need this and we can just say input to iso and let's try it out should work just the same and do exactly what this little message that i'm running around says and uh in the next episode i will be creating a simple camera script to follow our play around perfect for an isometric game if you've got any other ideas that you want me to cover in this isometric series let me know otherwise i'll see you in the next video bye [Music] you