Movement

The movement in this project will be the core of the movement mechanics in this game, these movements will determine how well the grappling, double jump and overall movement feels in the game. To begin with the movement I firstly created a camera point on the player and created some basic code to attach the camera to the point. I would made the camera a child object of the player but I found out the hard way that if the player runs into an object, the physics of child objects become slightly distorted and begin jittering and shaking which is undesirable.

The code is only a few lines long and does exactly as expected. The camera successfully stays attached to the player without any jittering issues.

Next I created the camera movement script which allows the player to look around and uses sensitivity variables which the player should be able to adjust in the settings.

This code works by taking the mouse x and y inputs and converting them to  float values. Then rotation Y and rotation X are set to these mouse values and are plus equals or minus equals depending on the axis. Then the rotation x rotation is clamped to -90 and 90 which stops the camera from going beyond vertical on both up and down. This is so the player cannot loop the camera around themselves. Finally the rotation of the camera is set to the rotation floats. This script works almost perfectly and I have encountered no issues with camera movement. The sensitivity doesn't work yet but I will be coming back to this script later.

Next, I got started on some actual movement. Using a YouTube tutorial I found by "bananadev2", I was able to create this movement script which worked rather well.

This script works by taking the horizontal and vertical inputs of the player which is WASD and normalizes them so they have values of 0, -1 and 1 for both axis. This script calculates movement first and then calls the function in FixedUpdate to provide a smoother movement feel. It calculates the movement by taking the input values and transforms them into a direction using Transform.Direction. Target velocity takes that information and then multiplies itself by move speed or sprint speed depending if left shift is held. The next part of the script was an attempt to reduce jittery movement as I thought it wasn't the camera but I fixed this issue before by removing the camera from the player parent object and made it separate, I found that this was caused by walking into objects while the camera is a child object.


I also tweaked the air movement to create a more realistic feel when the player is airborne. I created a separate function called AirMovement which turns the drag on the rigidbody component up greatly. This slows the player down in the air which restricts how quickly they can move in the air. Not only does this create a more realistic feeling but indicates that the greater way to move around should be the grappling mechanic as it will be much faster than jumping and sprinting. I also feel that restricting movement in the air would create a overall better balance for the players as continuously trying to aim at a fast moving player in the air would be quite difficult.


The jumping is rather simple, if the player presses space and is on the ground, upwards force is added and the value is determined by the jumpForce variable which is adjustable in the inspector. To check if the player is on the ground, it uses a bool called _grounded which is set in another script that is attached to a game object that is positioned at the players feet. When the player is touching the ground or staying on the ground, the grounded bool is set to true and when the player leaves the ground via a jump or grapple, the bool is set to false. The script that controls the grounded bool is explained below on the screenshots below:

This script is attached to this game object which is a trigger collider that detects when the player is touching the ground. if the player is touching the ground this script references the movement script and turns the grounded bool to true. This bool being true makes the player be allowed to jump. This script uses the on trigger enter, exit and stay functions which detects if the game object is touching another game object or continuously touching a game object.

Evaluation:


This movement system works exactly as intended, However during this process I ran into a few issues that resulted in huge time loss to fix. The issues I ran into involved the camera suddenly jittering when the player moved in different ways. After a lengthy amount of time trying to figure out why this was happening, I found that the issue was due to the camera being a parent object of the player. The camera jitters because it follows the same physics as the player since its a child object, this means that when the player runs into another object, the child objects seem to jitter for some reason. The fixing process for this problem also took a lengthy amount of time which was frustrating and definitely made me struggle with my stress management. I eventually fixed the issue by making the camera transform onto a empty game object that is attached to the player. This seemed to stop the jittering but I also had issues moving the camera with the script I made so I would say this is a perfect fix for this issue. The camera stays smooth and doesn't jitter anymore when running into other objects. If I didn't fix this issue, the gameplay would have been annoying as the camera would have constantly been shaking. While the issues I had moving the camera gave me some time loss, I think it was worth the loss to fix this frustrating issue. To prevent time loss like this in the future, I should allocate some more time towards bug fixing and problem solving in my planning and be careful with how much work I plan for myself as it may hinder the final results of the project. The time I spent fixing this however, had a slight impact on the rest of the production as I would now have to try to recover the time I lost by being a little quicker in producing my mechanics.

New movement system:


Below is the work towards making the new movement system after a failure i had with advanced grappling targeting.


After I realised that i could not create automatic targeting for grappling alone, I resulted to creating a different grappling system where the player can shoot at any grappleable object without the game targeting these objects for the player. Following a tutorial on YouTube by Dave / GameDevelopment which helps tremendously, I recreated movement which not only feels better to control but is more in depth. Each function works differently and more efficiently than before.

Firstly, I assigned the variables I will need to control to test this movement as I go along, hence why they are all set to public.


I set JumpKey to initially be customizable for the jump but set it to spacebar for ease.

Horizontal and Vertical Input determine which direction the player has inputted in WASD. 

The start function simply gets the rigidbody component and sets a few bool variables.

The Update function mainly changes what moveSpeed (the current speed value of the player) should be. For example if the player is swinging then the moveSpeed needs to be set to swing speed as moveSpeed is what the script uses to move the player.


When the player is frozen the script freezes the player in place by reducing the velocity value of the rigidbody to zero using Vector3.zero.


If the player is on the ground and not currently in a grapple then the drag is set to the ground drag variable which helps with smoothing the movement.


MyInput and SpeedControl functions are constantly called as MyInput determines all of the players inputs and SpeedControl limits the players velocity in both regular movement and in grappling as the player moves by adding force constantly. Without a limiter the player would be able to move at a forever increasing speed.

The FixedUpdate function contains the MovePlayer function. I placed this function in fixed update because fixed update is called more consistently than Update. This minimalizes potential jittering and lag in movement.


The MyInput function checks if the player is pressing WASD which are detected by horizontal input and vertical input through the GetAxisRaw function.


If the player presses the jumpKey which is space, and is able to jump and is on the ground, then the script calls the Jump function which is where the jump mechanics are.

Here is the MovePlayer function. MoveDirection is a vector3 variable that is essential to determine which direction the player should be moving. After it is calculated using orientation, vertical and horizontal inputs, it is involved in the rb.AddForce equation which multiplies moveDirection with moveSpeed and 10 and then ForceMode.Force is applied. When the player is in the air, the same equation is applied except air multiplier is added into the equation which could increase or decrease the players speed depending on the value.

This is the speed control function which limits the speed by setting velocity to a new Vector3 when the player is going faster than expected. This function is called constantly so the player should never be moving too quickly.

This is the Jump and reset jump functions. Jump simply adds force upwards which is determined by jump force and ForceMode.Impulse is used for this force. Reset Jump essentially resets the readyToJump variable which allows the player to jump again when wanted.

Here is the result of the following code:

Movement show.mp4

Evaluation:

Overall, this movement system feels undoubtedly smoother than the previous one I made, it works more efficiently with Unity's rigidbody physics and utilises AddForce to a superior degree. A few problems that needed fixing during the bug fixing and optimisation stages are the mass of the player as I struggled to get it to a balanced amount with the move speed and jump force. When the player moves, the script adds force to the player, if the player is heavier then the player will slowly start moving and quickly stop while a light player will start quickly and stop slowly. To fix this imbalance I tried to balance the players mass, jump force and move speed to allow for smoother stopping and starting movement and a realistic jump height. This is an important fix as it greatly affects how the movement feels and plays, it would be a little annoying if the player is too light and just slide around the level too much or if they're too heavy, they would barely move. From this, I have learnt to keep some variables the same in future projects which would make things easier for me to balance. For example, if from now I always set my players mass to 2, I will have a rough idea of how to balance other variables.

Now that the movement is finished, I can begin working on the other mechanics with movement which is grappling and double jumping.