March 30th 2023

Finishing the Movement System (good luck reading all this)

Intro

The previous month I had got most of the mechanics out of the way, but there were a few more things I had left to do.

These included:

As well as these final mechanics, the majority of other mechanics I had previously implemented were in desperate need of improvements and polish, so I was going to dedicate time into testing and adding a bunch of improvements to all my code.

Jira task progress March 30th

Sliding

The first thing I wanted to add was crouching and sliding. These two would go hand-in-hand as they would use very similar functionality with just slight differences in the outcome.

With this, there was a new issue I had to figure out, and that was changing the hitbox of the player to be slightly smaller. This was needed as the plan was that players should be able to crouch and slide underneath certain objects that they usually wouldn't be able to go under since they would be too tall.

With the character controller, it forces your player to have a capsule collider, meaning I was limited in my methods of changing the size. I was able to adjust the centre, radius and height.

With some experimenting, I found that halving the height and moving the centre down by 0.5 would turn the capsule shape into more of a sphere, which was perfect as it meant it would be roughly half the original size.

And that was pretty much the only hard part of crouching, I just had to make the camera move down with the top of the hitbox and make it trigger when the crouch key was pressed.

Sliding could be built off this crouch, as it would need the similar hitbox and camera changes, but would also need additional features built on.

As a result, in order to reduce duplicating code, I made it so that the crouch state could easily be switched on and off without interfering with anything else. That meant that when the player goes to slide, it can also trigger the start of the crouch at the same time. Doing this saved me from having to write any code in the slide function to change the hitbox size or camera height, and that could all be handled in the crouch functions.

This in general is just good programming practice. This is because it saves time and makes code much more maintainable, as if I wanted to alter the code that changes the hitbox size, I would only need to alter it in one area to change it.

This will run the StartCrouch function whenever the crouch key is pressed, and will also run the StartSlide function if the player is running too

Sliding needed extra functionality, however, and that was going to be a boost of forward movement. This would be easy to implement as I had already implemented movement boosts like this in loads of other parts such as the dodge or wall jumping.

There was a major issue that came up, however, and this came with getting the movement direction.

Since it was decided that the player would slide in one set direction when pressing the slide key, and they wouldn't be able to change direction mid-slide, I would have to get their current forward direction the moment they pressed to slide.

Getting this forward direction seemed to be much harder than I thought, though.

It seemed simple enough, just get the forward direction of the camera right? This, however, didn't account for if the player was looking up or down, and if the player was looking up then this would lead to some interesting situations...

I thought all I would have to do was just remove the Y (up) value from the direction vector, which would ensure that the player couldn't go up or down. 

Unfortunately, an issue would stem from this and that would be that the distance forwards would end up being significantly shorter if they were looking up or down as part of the magnitude of the vector would have been wasted on the Y value.

To counteract this, I would have to store the length (magnitude) of the vector, remove the Y value, and then set the vector back to that length. However, you can't just set the length of a vector, as the length is determined by the vector itself.

This left me a bit stuck, so I went to ask for some help and found some guidance, and it turned out the solution was way easier than I thought.

All I had to do was normalise (set the length to 1) the vector which had no Y value, and then times it by the magnitude I had stored. By multiplying it by the magnitude, it would essentially function as setting it to be the same, which was what I wanted.

Doing this resolved the issue, however, as I'm writing this issue I realised I did not need to do any of it...

For some reason, I had it in my mind that I had to get the forward direction of the camera when judging the direction that the player would slide in.

While this somewhat makes sense, it is completely unnecessary as the player themselves will be following the players' camera Y rotation already, the Y rotation being the left and right direction that the player is looking in. 

With that, the player won't be following the up rotation of the camera, meaning that I wouldn't have to do all this extra mumbo jumbo to make sure that the player can't slide up and down. This reduces the amount of code heavily.

Before

After 💀 

Now, looking back, realising this at the time would have saved me quite a few hours. However, I'm not sure if there was really a way I could avoid this other than just spending more time thinking through the method and making sure I wasn't overthinking it. I think that is just something I will pick up more over time as I learn how to do certain things and memorise certain methods. 

And on top of this, I don't necessarily regret going through this longer more painful method as it was actually way more helpful for me in learning Unity. It taught me some valuable information regarding vectors, such as how to set magnitudes. So while I could have saved time, I actually find the learning experience to be more valuable, therefore I'm not particularly regretful.

Anyway, with that done, the slide was finished.

I'm very happy with the sliding and crouching, it's really fun to just slide around for hours and that's perfect because that's exactly what players will be doing.

Looking at my code, though, there are some aspects I could improve.

For example, in order to have the slide slow down to a stop smoothly, I used some complicated maths functions on the time variable.

Now while these maths may look cool and fancy, I actually have no idea what it's doing and just took the function from somewhere online. It may work fine, but it makes it impossible to tweak in the future because I'd have no idea how to change it. It is also just bad in general to have code in which I don't understand what it's doing, as it makes it harder to track values inside of variables and know what's going on behind the code.

There would be two ways to fix this, one would be just learning the actual maths behind it which may be ideal just for the fact that the maths would actually be useful to know in general if I ever want to do something like this again in the future, however since the time I created the slide functions I have learnt about a great new way of controlling easing in and out called animation curves.

I will go into more detail about these animation curves later as I used them for the vaulting, but they are very easily adjustable and highly readable, making them a much-preferred option over confusing and finicky math code. 

So while learning the maths may be more beneficial to me as a programmer, sticking to an easier and more robust animation curve would likely be the better option for now if I were to improve this section of code.

Other than this, though, I think the code is fine and fulfils its purpose.

Rolling

Next up was rolling.

This would be added on top of the current fall damage mechanic that Kieran had made and would be a way to prevent fall damage by spreading the impact of the fall into a roll movement.

This sort of mechanic is used in Mirrors Edge, so I took a lot of inspiration from there when it came to how it would work.

As for coding it, though, it seemed to be very simple. As the fall damage system was already made, all that I had to add was the roll animation which would spin your character around if you successfully rolled, as well as a damage animation which would tint your screen red and shake it if you failed to roll.

Kieran's fall damage code

For spinning the character, I choose to do it within a coroutine as the spinning would take place over multiple frames, and it's easier in a coroutine than the update function as I don't have to have a bunch of if statements and just in general keeps the code nice and modular and easier to track.

This coroutine would just add 360 degrees to the player's X rotation, and then lerp to that rotation over time.

I choose to rotate the actual player instead of just the camera, as this felt more logical, and I worried that rotating the camera may have interfered with the system that gets the player's mouse input. 

Looking back though, this may have been a bad idea as when we start adding animations to the game, rotating the player object may interfere with the animations and cause it to roll too much.

What I should have done instead was add the camera as a child of an empty object (CameraPivot). This empty object I could then rotate around freely, with the camera object inheriting all the rotation from it due to it being a child. By having it as a separate object, it would stop it from interfering with the script I already had on the camera, allowing me to alter the rotation of the camera as I need without stopping the player from looking around.

Right now the current system works fine, but when animations are being implemented and it does become an issue, this should be an easy fix.

Current

Alternative

With that the roll animation was done, however, there was an annoyance I was noticing which I knew had to be fixed.

After finishing a roll, the player's rotation would end up facing the same direction as when they started it. Due to the fact that you are usually looking down at the floor as you are falling, this would result in most rolls ending with the player looking down at the ground, and this ended up being incredibly disorientating.

What I needed was a system to subtly alter the player's rotation mid-roll so that they would finish looking straight ahead. For this, I had the perfect idea, and it was surprisingly simple.

All I had to do was lerp (linear interpolation) the X rotation (up) of the camera from where it currently was, towards 0, which was the middle. If I did this every frame from the start of the roll to the end, it would smoothly take the rotation from where it started right to the middle. No matter what value the X rotation was currently at, it would always go towards and end at 0, so the roll would always end facing forwards.

This system of using Lerp rather than just setting their X rotation to 0 is significantly better, as while the first option would be much quicker and easier, it is also lazy and very jarring as the players would be able to immediately notice their rotation change.

This is what it would look like if I just set the X value rather than lerping it

By lerping, this transition would instead be seamless and players wouldn't even notice all the effort that had gone into fixing this issue, which is exactly how this sort of improvement should be.

Overall, I'm super happy with the rolling, it feels super smooth and the transition to looking straight is completely seamless. It feels incredibly fluid to play, and it's all-around super satisfying. It's also done with very minimal code, and looking back, there really isn't anything I would change code-wise.

The only major issue I can see that see is that the rotating of the screen could potentially cause motion sickness (due to the ingame movement being too different from the actual movement of the person playing), but I think that will need some testing to determine.

The only thing left was a system which would slow down the player, as well as some visual cues if they didn't press the roll.

The slowing down part was very easy, as I had already implemented temporary speed systems with the powerups and sprinting.

As for the visual cues, I wanted to have the screen edges tilt slightly red and have the screen shake slightly. As both of these were small visual animations, they could be easily handled with the DOTween plugin I have already used and explained for the powerups. With this, both bits of functionality could be done with just one line of code each

I did also pick out a red tint texture to use, and with that, all the rolling was done.

Vaulting

The final movement mechanic left to add to the game was vaulting. This would give players an easy way to quickly move past a short object in front of them without disrupting their movement.

Luckily for me, the basic aspects of this have already been implemented in other aspects of the code, so there was nothing I was completely unsure of.

The very first thing I had to consider was how I could check if a player was even in a valid vaulting situation.

I came up with two possible ideas for how to do this, the first was just checking the width of the object they were trying to vault and making sure it was below a certain threshold.

This method would be very easy to implement and easy to adjust but has one major flaw. If the object isn't a cuboid shape, then the length wouldn't be accurate because it would change for different parts of the object. I would need a system that would actually check the world space rather than the object itself, as the object would be too inconsistent.

So instead, I opted for a system which would first check if there was an object in front of the player, then check if that same object was still there a certain distance further ahead. If the object was no longer there, then that means the object was short enough for them to vault over, so the object was valid.

To do this second check, I could use Unity's built-in CheckSphere() function. This allows you to check if any objects collide with an invisible sphere which you can make any size, this makes it perfect for this as it means I can just run the function once to check if it's valid and a sphere shape is ideal over something like a square because it means the rotation of the player and shape of the vaulting object won't matter as much. This is better than creating my own trigger object since they can sometimes be unreliable with fast-moving objects (like the player), so I wanted a system as reliable as possible, even if it might be slightly less performant.

Overall, while this method may be less efficient than only one raycast as it requires more physics and collision checks, it makes up for it by being way more consistent and reliable.

That combined with a starting raycast to check if you are in front of an object meant that the function to check if you could start a vault was done.

The actual vaulting itself was easy enough, as I had done a movement like this 100 times at this point.

I had to get the distance that the player would vault by using the object's width, which while not completely accurate, was close enough. This distance is then added on top of the player's current position, and then the player's position is smoothly transitioned from A to B.

There was one major flaw I didn't like, however, and that was the fact that the player didn't go up at all. Currently, it looks like the player just phases through the objects, whereas what was actually meant to happen was they were jumping over them.

With the current system of going from A to B, there was no vertical movement within that, and I didn't want to change that system as anything else would be way too complicated and using Lerp was definitely ideal.

What I came up with was an idea that would lerp the Y value of the player up and down, independently, while they are vaulting. This way it wouldn't interfere with their movement from A to B, but it would still allow them to go up and down. This was also good as it meant that the Y value wouldn't affect the end position of the player at all, as that would all be separate. So there was no chance it would mess up the vault.

To do this, I got the height of the object, as this would tell me how high up the player would have to go during the animation. Then during the animation, I would lerp from 0 up to that animation height, and then back down and store that value in some variable. That variable would then be added to the current Y of the player so that they would go up from where the vault animation would set them.

The Y value would have to be added again every frame. This is because the Y value of the player would be set back down to the floor each frame as all the animation was doing was going from the start of the vault to the end, which would only be along the floor.

With that, I had a rough version of it working.

While this looked a lot better, I was still unhappy with the easing of the bobbing. I wanted to have a smarter system where it would go up quickly, hover at the top for longer, and then fall down quickly.

I didn't want to just google some complicated math I didn't understand like I did for the slide, so I needed to look for a better system which would allow me to easily adjust the easing of the animation. It was through that I stumbled across animation curves, which ended up being exactly what I needed. I watched this great YouTube Tutorial which gave me a great rundown of how they worked.

They were incredibly easy to set up. First, you would create and assign them as a variable to the player, as well as make them visible in the editor. By doing this, you could then drag and adjust the curve to be however you wanted.

The curve would be a line on a graph from 1 to 1. This meant that I could use it alongside the T variable in lerp as a way to adjust the speed at which the player goes up and down. This can be done by using the Evaluate() function on the curve.

Animation curves are amazing for loads of reasons. 

Mainly because they provide you with a GUI to edit and view them from. This makes it super easy to edit and visualise how the animation will look compared to having to write the math and then either visualise it in your head, or go through all the time compiling that code and testing it ingame just to see how it looks. This has the risk that you might have messed up the math, or that it doesn't even look right.

This benefit also allows non-programmers to edit the curve, if for example a designer wanted it to hover at the top slightly more they could change that themselves in the editor by just dragging the curve, they wouldn't need to change some complex math in the code.

Using these animation curves was better in almost every way, and if I were to go back and improve parts of my code, I would definitely swap out my sliding momentum for an animation curve because this system is far better.

Now the vault bobbing was looking much smoother.

One thing I should have considered at the time was how the vault looks with objects closer, though. Due to the environment I was testing in, the surrounding area was very desolate. This makes it much harder to visualise the bob effect of the player, since objects further away from you appear to move less compared to objects closer. I should have added more objects closer to the player to better visualise how the vault might look in an actual game environment, but nonetheless, it's fine and not a major issue.


It seemed like everything was done, however, I soon discovered a major issue with the method I used for calculating vault length.

The method I used would use the width of the object to determine how far forward they would need to travel forwards. This worked fine in most normal cases, however in the case that the player would be vaulting over a corner of an object then that object width would remain way further than they would need to travel, leading them to vault way past the intended point.

Both diagrams show in green where the player should go, however the red arrow shows there the player ends up going.

Fixing this issue would need a rework of the system I used to calculate vault length. Not only should it fix this issue, but it should also account for the future inaccuracy of having non-cuboid-shaped objects.

I couldn't come up with a good solution myself or with Google, as I wasn't sure exactly how you could google this sort of issue due to it being very specific.

Instead, I took to Discord and asked some friends who were good at programming. I assumed the issue would require some math and trigonometry of sorts, as I had the length and angles required for that sort of thing, however, I wasn't exactly sure what. As someone who is quite inexperienced with maths, I was a little out of my depth here.

One solution I was given was to use the Sin() function, on the box's length and the line's angle.

Unfortunately, it was not that easy, and this solution never seemed to give consistent results. Whether that was my fault or it was the fault of the person who gave me the idea, I will never know. Yet again, my lack of knowledge of complicated math continues to be my downfall.

Another person give me a different solution and even created a cute little Desmos Graph to help, and while appreciated the help, I had no clue what it meant, so while I appreciated the gesture it wasn't particularly helpful.

It felt like all hope was lost, that was until the next Code Studio. During the working period, I brought in my laptop and demonstrated the issue I was facing, and Avery was very quick to understand and offer a perfect solution to all my issues. 

Basically, to calculate the vault length, I would ditch the object length entirely. Instead, I would use a raycast from far in front, back towards the player, to find the exit point of the object. Then I can calculate the distance between the entrance and exit point, that distance being how far the player would need to vault.

The solution was super simple and easy to implement. Sometimes you do just need an outside perspective from a fellow game developer rather than regular programmers, since a game developer will be able to come up with more specific solutions and would also have way more experience with these sorts of issues.

The way I implemented this in code, was by first getting the direction of the player as this was essential for calculating the endpoint. Next, I needed to find a starting position to perform the second raycast to find the exit point. For this, I kept the code which calculated the object's width and added that value onto the entrance point's position in the direction the player was facing.

I thought using the object width would be the best way to do it as it would still be more reliable than some arbitrary number due to it changing according to the object size, whereas a set number might have some issues on the longer object. By continuing to use the object width for this raycast it will stay reliable and won't cause any of the issues that were happening last time.

With this raycast starting position stored, it then does a raycast in the opposite way the player is facing, which would make it go towards the player. If the raycast then hit the same object that the player is trying to vault, then it means it has hit the exit point. That exit point then becomes the end position of the vault.

I now have the entrance and exit point coordinates stored, so I could subtract them away from each other to get the exact distance of the vault!

This led to the issue being fixed, and with a 100% accurate system of checking the vault distance.

I'm glad this issue was resolved, and I'm happy that the solution that Avery came up with ended up, leading to a much better overall system. 

I wish I could have solved it independently because I don't like having to rely on other people to fix my own mistakes, but that's a bad mindset to have, especially when working on a team because it can save you a lot of time as people will likely have experience with the exact issue and can offer immediate help. This is something I will need to work on. 

I think overall there are a few parts of my implementation of the vaulting which could be improved upon.

Firstly, something I immediately notice is that I can update a lot of certain aspects now that I have the new method for checking the vault length. For example, the system I had for using CheckSphere() while cool can now be entirely removed since I can just use the vault distance to check if they are trying to vault too far...

Switching from the CheckSphere() method would sadly be ideal, as it's just running unnecessary code, which is just bad practice and can be bad for performance. So to remove that system and have the raycast system, which is already used, be used for both would be more efficient.

I think in general the whole code could do with a whole rewrite to remove redundant parts like that, maybe in the future if I can be bothered. But alas, for now, it functions fine.

I also think some of my problem-solving could have been improved upon. I may have been too quick to resort to asking for help on Discord rather than trying alternative methods or trying harder with my Google searches. Furthermore, I think one of the main reasons I struggled to Google my issue was because I didn't really understand the issue I was having. 

At first, I thought it was just caused by the line being diagonal, which would have made the distance needed to vault over b longer. It wasn't until exploring the issue further while asking for help that I realised the issue was actually just when vaulting the corners and when the vault wasn't fully across the length of the object, and then it all made sense. Perhaps if I had experimented more and fully tracked down what the issue was, I could have done a better job at solving it alone like I wanted.

Improvements

Now that all the movement mechanics were done, before I could say I was finished, I wanted to go through and polish all the code I had done so far. So I did some play tests and made a list of a bunch of things I wanted to change.

These issues were mostly caused by two things. Either a lack of hindsight and failure to see a certain situation happening, or just bad code that failed to account for all circumstances.

Ideally while writing code you should account for both things, however no one is perfect. For most people, it is just something that can be improved over time the more you do it. Perhaps one way I could have minimised the possibility of overlooking an issue would have been planning my implementation, whether that's just writing out how it should work, designing proper diagrams such as flow charts or class diagrams, or just simply prototyping them first then attempting a full implementation. That way, I would have had a better chance to fully overlook exactly how it would function and spot and fix potential mistakes early, as well as have a good idea of how something should work and all the features before dedicating lots of time to making it perfect. Maybe this is something I should consider doing in the future.

Anyway, while these issues ranged from major game-breaking glitches to just simple quality-of-life changes, I quickly got to work as it was still necessary to do.

The first thing I wanted to do was actually a further improvement to the vaulting, and it was to add a maximum angle that the player can be facing in able to be able to vault over an object. This is to stop them from going directly diagonally over an object, leading to some weird interactions.

It works by getting the direction vector of the player and then comparing it to the negative normal of the wall that the player is vaulting over. The normal is the vector pointing away from a wall, so by getting the negative value, it would be the value pointing towards the object. By comparing these two values, I can check what the difference is and see how far away the player is looking from straight ahead, and then compare it to a maximum value set in the editor.

The code works fine, and I like how it can be adjusted easily, however I think one major issue is the fact that all the checks are done using the vector values. This means that the value selected in the editor ends up being a random decimal value, which becomes hard to visualise. 

Instead, I should have used the Vector3.Angle() function to give me the difference between the values of an angle, that way it would be much easier for any other users to visualise and choose a maximum value as angles are much more familiar to the average person.

Another bug I needed to fix was in regard to wall running.

With the wall running code, I intentionally made it so that it would continue to check every frame if the player was still next to the wall and able to wall run. I did this so that players could not only detach from a wall at will, but also be able to wall run on non-straight walls. If it was checking the wall every frame, it would also recalculate the wallrunning values, allowing this to happen smoothly. This allowed for things like wallrunning on a curved surface or an attached diagonal wall possible.

One thing I failed to consider, though, was that there was no limit to how far they could turn the wall for their next wallrun...

Players were able to run around a full 90-degree corner if they angled their camera right, which was definitely not intended and was potentially abusable. It was also way too inconsistent to properly pull off, so it was bad to keep in the game, as it would just lead to player frustration.

There were a few ways I contemplated fixing the issue.

One was just removing the check completely, and having players be unable to change the angle mid-wallrun. This of course was less than ideal and a very lazy solution, as it would remove a potentially cool feature from being in the final product. I wanted to try other alternatives before going with this last solution.

Another potential solution I had was to raycast in front of the player, and then check the normal of the wall in front. This solution seemed rather finicky, as it wouldn't be able to check for walls which go away from the player rather than towards. This means the player could only wallrun inwards rather than outwards, which wasn't ideal because I kinda wanted both. Ideally, I would be able to check against a value to make sure it wasn't too far an angle difference from the last wall. It would also struggle for tight turns, as the turn might happen before it's even in front of the player, so the raycast won't be able to hit the curve.

That's when I settled on a third and final idea, which was just comparing the wall's normal to the one from the last frame. Meaning, that if a player were to switch walls, it would compare the angle of the last wall, as well as the angle of the new wall they are trying to wallrun and check the difference. If that difference was more than 45 degrees, then the wallrun would fail and the player would fall.

This system was far better as it stopped them running around 90-degree walls, it let them run outwards and inwards, and it was also easily adjustable in the future if I wanted to make it more or less forgiving. Overall, I managed to fix the issue perfectly while retaining the feature I wanted.

One last issue I want to talk about was with the fall damage detection.

This was partly Kieran's and partly my fault, as it was a result of both of our codes.

The system that Kieran had used to check if the player had landed used the OnControllerColliderHit() function, which is triggered when the object collides with another as a result of the Move() function. This worked fine for the fall damage, as the player moving downwards was a result of the Move function, so the collision with the ground would be detected. However, I soon realised that this function would detect collision with ALL objects, not just the ground...

I still to this day have no idea why, but for some reason colliding with an object instead of the floor would cause the player to be completely stuck and the camera to disassociate with the player, leading to an incredibly bizarre soft lock.

It did only happen when colliding with another object that wasn't the ground, so I knew it was related to that, and I'd have to come up with a new method of detection.

Luckily, this ended up being very easy, as all I needed was a way to check if the player was on or off the ground and check if they transitioned from off to on the ground in the last frame.

There are a bunch of ways to check if the player is on the ground.

One is a raycast down and seeing if it collides with the ground object. This works fine but can be unnecessary and runs unneeded code as there are other methods already available. This distance could potentially be a benefit, though, as it adds a check threshold, allowing you to check if the player is just about to hit the ground.

Another way could be to create an invisible trigger object, which would be a child of the player and would sit slightly below them. Then you can check when it's inside another object, as this would mean the player is on top of it. This has the same benefit as a raycast due to the object size being customisable, however, it has the same issue of potentially being unneeded code, plus it requires a whole new object with its own collider in the scene.

The final method I went with which is by far the simplest is just using the built-in CharacterController isGrounded variable which is automatically updated if the player is touching the ground after a last move. This means I don't have to run any additional code to check if they're on the ground, Unity does it for me. While this does sound perfect and exactly what I need, there is the risk of it being unreliable as I don't know exactly what code is being run to check if it's on the ground, and there is no way for me to change exactly how it is checking. However, for now, it is fine and it will do.

Overall, these changes helped do a good job of improving the overall feel and fluidity of the movement, as well as keeping the code as maintainable and reliable as possible.

It only took a few hours to get all the improvements done, too, which was surprisingly quick. 

I quite enjoy code fixes like this, because they require a unique sort of problem-solving and experimentation that I think I'm quite good at, rather than the regular coding process.

One mistake I made was making this list of improvements on Discord, this was a terrible idea and became impossible to keep track of eventually as there were just too many bugs and the only way I could order them on Discord was by manually deleting or reformatting the text. So at the end, I moved everything to a new separate Jira board just for testing and bugs, which I'll use again in the future for things like this.

Conclusion

Overall, looking back at the movement code as a whole, I'm very happy with it.

As my first proper 3D first-person project, to be able to create an entire movement system with my own custom motion, and have code that is nicely organised and well functional, is all very cool.

One part I like is that each aspect of the movement has its own start and end function. This makes it so that it can easily be started and stopped at any point of the code without needing to repeat lines. It also makes it very easy to track where certain things happen within the code if I want to make changes.

I'm also happy with my use of enumerations to store different movement states. An enum is a type of variable which stores a list of values inside of it. I then used these values as states for a movement system, where the mState variable would match the according enum value of the current movement state, depending on what the player should currently be doing. Such as running, sliding or wall running. 

Enums have many benefits over integers, for example, the code becomes way more readable as it's way easier to understand what a word means than memorise what some random number means. That makes it far easier to change in the future and reduces the chance of a potential user error.

I then check for whatever mState is active in the update function to run the correct code. This way only the necessary code is run, so none of the wall running code is run while normal running, and none of the normal running code is run while sliding. This is a great way to increase performance by reducing the number of lines being run, and just overall reducing the bugginess of the code by controlling what exactly is getting run at which point.

If there were one thing I was to improve next month, it would be my code formatting.

As someone who only had previous experience with Python and Minecraft Commands, I was only used to languages in which line switches would affect the code sequence. In those languages, each new physical line was a new command to be executed. C# however uses semicolons (;) to indicate a line change for the compiler. This way, it can be used as a nice way to organise code. 

For example. These two segments of code function the exact same, but one is far more readable.

Before

After

Avery taught me this trick right after I had implemented everything by reorganising all the code for me, and I think in the future I will definitely ensure I adopt this formatting method for all the code I write because it's so much better.

It makes all the code so much more readable and contained since it actually fits on the page. Before, for the longer lines, I would have to either zoom out or scroll left and right, which was always tedious.

In the future, I will always keep in mind that I can separate my code into multiple lines for better accessibility.

I think another big aspect I should improve is my math ability.

I feel as though there were multiple instances in the past month when I was hindered by my inability to understand some math functions. I may have been able to work around them now, but in the future, I might not be as lucky.

There is a math module next year I can use to help further improve my math ability, but I can also take my own initiative and teach myself through the countless online resources, such as a video to learn the fundamentals of trigonometry.

Overall, though, I'm proud of the work I've done so far on the project, and I'm looking forward to everything coming together for the final product.

Media