PlayerControllerThatLevelsUp.cs
Assets > Scripts > PlayerControllerThatLevelsUp.cs
Assets > Scripts > PlayerControllerThatLevelsUp.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEditor;
public class PlayerControllerThatLevelsUp : MonoBehaviour
{
public float moveSpeed = 1f;
public float turnSpeed = 45f;
public float currentMoveSpeed;
public float currentTurnSpeed;
public float sprintSpeedModifier = 2f;
public float activeSprintModifier = 1f;
public float jumpHeight = 2f;
public float currentJumpHeight;
public int currentLockPickSkill = 1;
public float xp = 0;
public float xpForNextLevel = 10;
public int level = 0;
private void Start()
{
SetXpForNextLevel();
SetCurrentMoveSpeed();
SetCurrentTurnSpeed();
SetCurrentJumpHeight();
SetCurrentLockPickSkill();
}
void SetXpForNextLevel()
{
xpForNextLevel = (10f + (level * level * 0.1f));
Debug.Log("xpForNextLevel " + xpForNextLevel);
}
void SetCurrentMoveSpeed()
{
currentMoveSpeed = this.moveSpeed + (this.moveSpeed * 0.1f * level);
Debug.Log("currentMoveSpeed = " + currentMoveSpeed);
}
void SetCurrentTurnSpeed()
{
currentTurnSpeed = this.turnSpeed + (this.turnSpeed * (level * 0.1f));
Debug.Log("currentTurnSpeed = " + currentTurnSpeed);
}
void SetCurrentJumpHeight()
{
currentJumpHeight = this.jumpHeight + (this.jumpHeight * 0.1f * level);
Debug.Log("currentJumpHeight = " + currentJumpHeight);
}
void SetCurrentLockPickSkill()
{
currentLockPickSkill = this.currentLockPickSkill + 1;
Debug.Log("currentLockPickSkill = " + currentLockPickSkill);
}
void LevelUp()
{
xp = 0f;
level++;
Debug.Log("level" + level);
SetXpForNextLevel();
SetCurrentMoveSpeed();
SetCurrentTurnSpeed();
SetCurrentJumpHeight();
SetCurrentLockPickSkill();
}
public void GainXP(int xpToGain)
{
xp += xpToGain;
Debug.Log("Gained " + xpToGain + " XP, Current Xp = " + xp + ", XP needed to reach next Level = " + xpForNextLevel);
}
void Update()
{
if (Input.GetKeyDown(KeyCode.X) == true) { GainXP(1); }
if (xp >= xpForNextLevel)
{
LevelUp();
}
if (Input.GetKeyDown(KeyCode.Escape) == true)
{
#if UNITY_EDITOR
{
EditorApplication.isPlaying = false;
}
#else
{
Application.Quit();
}
#endif
}
if (Input.GetKey(KeyCode.LeftShift) == true)
{
activeSprintModifier = sprintSpeedModifier;
}
else
{
activeSprintModifier = 1f;
}
if (Input.GetKey(KeyCode.UpArrow) == true || Input.GetKey(KeyCode.W) == true) { this.transform.position += this.transform.forward * currentMoveSpeed * activeSprintModifier * Time.deltaTime; }
if (Input.GetKey(KeyCode.DownArrow) == true || Input.GetKey(KeyCode.S) == true) { this.transform.position -= this.transform.forward * currentMoveSpeed * activeSprintModifier * Time.deltaTime; }
if (Input.GetKey(KeyCode.E) == true) { this.transform.position += this.transform.right * currentMoveSpeed * activeSprintModifier * Time.deltaTime; }
if (Input.GetKey(KeyCode.Q) == true) { this.transform.position -= this.transform.right * currentMoveSpeed * activeSprintModifier * Time.deltaTime; }
if (Input.GetKey(KeyCode.RightArrow) == true || Input.GetKey(KeyCode.D) == true) { this.transform.RotateAround(this.transform.position, Vector3.up, currentTurnSpeed * Time.deltaTime); }
if (Input.GetKey(KeyCode.LeftArrow) == true || Input.GetKey(KeyCode.A) == true) { this.transform.RotateAround(this.transform.position, Vector3.up, -currentTurnSpeed * Time.deltaTime); }
if (Input.GetKey(KeyCode.Space) == true && Mathf.Abs(this.GetComponent<Rigidbody>().velocity.y) < 0.01f)
{
this.GetComponent<Rigidbody>().velocity += Vector3.up * (this.jumpHeight * this.currentJumpHeight);
}
}
}
This code will be explained in sections, which each have a different colour to separate them from each other. Comments in the script have been removed from this excerpt, but will be included in the Google Doc containing the script, linked at the bottom of the page.
Note that in this script and in subsequent scripts, I'll be explaining what the functions are doing in the script rather than explaining what they are in general (except for functions that I haven't already explained before), which is what I did with the PlayerController.cs page. If you want to see my explanation for the functions in general, you can access that page with the button below.
SECTION 1: Setting up the script
This part of the script is dedicated to setting up all of the namespaces and variables that will be used.
using System.Collections
using System.Collections.Generic
using UnityEngine
This is the namespaces that the script will be using for each of its functions.
using UnityEditor
This was a namespace that was used in the original PlayerController.cs script, and it's present on that page, but it wasn't explained. This namespace allows you to use functions for the Unity Editor instead of only the normal Unity Engine functions designed for runtime. It will be used later in the script to quit the game while in playmode in the Unity Editor.
public float moveSpeed = 1f
public float turnSpeed = 45f
public float currentMoveSpeed
public float currentTurnSpeed
public float sprintSpeedModifier = 2f
public float activeSprintModifier = 1f
public float jumpHeight = 2f
public float currentJumpHeight
These are all the variables that the script will be using for the movement of the player controller. The first two variables are the baseline variables that even the simpler PlayerController.cs script used, which are the moveSpeed and turnSpeed variables that control the move and turn speed of the player. Next is the currentMoveSpeed and currentTurnSpeed, which are used for dealing with the buffed values given from leveling up. Next is the two sprint modifiers, which deal with the standard and buffed sprint values and work them into the normal move and turn speeds to make sure they function correctly. Lastly is the jumping variables which include jumpHeight, which deals with the base jumping height, and currentJumpHeight, which deals with the buffed jumping height from leveling up.
public int currentLockPickSkill = 1
public float xp = 0
public float xpForNextLevel = 10
public int level = 0
These variables are mainly for the XP and level system. The bottom three variables are for the system directly, such as the xp and xpForNextLevel variables for gaining and retaining XP, as well as the the level variable for the player's current level. There is also the currentLockPickSkill variable, which is here because even though it receives a buff just like the movement variables, it more so falls under the category of skills than movement, and the lock pick skill works like a level system rather than just a slight buff.
SECTION 2: Making a start and defining the buffs
This part of the script is dedicated to starting up the script and creating all the buffs and the amount they would buff each value
private void Start()
{
SetXpForNextLevel()
SetCurrentMoveSpeed()
SetCurrentTurnSpeed()
SetCurrentJumpHeight()
SetCurrentLockPickSkill()
}
In this Start method, which initializes all of the code within it upon the first frame of the game, all of the methods that are about to be covered and that are related to all of the variables that were created in section 1 are called. We'll now go into what each of these methods do.
A flow chart that shows the order of operations for each function in this section.
void SetXpForNextLevel()
{
xpForNextLevel = (10f + (level * level * 0.1f))
Debug.Log("xpForNextLevel " + xpForNextLevel)
}
The first method that's called is SetXpForNextLevel, which sets the amount of XP requires to reach the next level for each level reached by the player. The XP requirement will increase by the value that is the result of the given equation for every level that is reached. For example, if the player reaches level 3, the equation will be 10 + (3 * 3 * 0.1f), which will equal 10.9. It will then report the current XP requirement for the next level.
A flow chart that shows the order of operations for each function in this section.
void SetCurrentMoveSpeed()
{
currentMoveSpeed = this.moveSpeed + (this.moveSpeed * 0.1f * level)
Debug.Log("currentMoveSpeed = " + currentMoveSpeed)
}
This next method that is called is SetCurrentMoveSpeed, which deals with the move speed of the player per level. Every time the player levels up, the movement speed will increase by the value that is the result of the given equation. For example, if a player reaches level 3, the equation will be 1 + (1 + (3 * 0.1)), which will equal 2.3. It will then report the current move speed to the console.
void SetCurrentTurnSpeed()
{
currentTurnSpeed = this.turnSpeed + (this.turnSpeed * (level * 0.1f))
Debug.Log("currentTurnSpeed = " + currentTurnSpeed)
}
This next method that is called is SetCurrentTurnSpeed, which deals with the turn speed for the player per level. Every time the player levels up, the turn speed will increase by the value that is the result of the given equation. For example, if a player reaches level 4, the equation will be 45 + (45 * (4 * 0.1)), which would equal 63. It will then report the current turn speed to the console.
A flow chart that shows the order of operations for each function in this section.
void SetCurrentJumpHeight()
{
currentJumpHeight = this.jumpHeight + (this.jumpHeight * 0.1f * level)
Debug.Log("currentJumpHeight = " + currentJumpHeight)
}
This method is called SetCurrentJumpHeight. This method deals with the player's jump height per level. Every time the player levels up, the jump height is increased by the value of the result of the given equation. For example, if a player reaches level 4, the equation would be 2 + (2 * 0.1 * 4), which equals 2.8. It will then report the current jump height to the console.
A flow chart that shows the order of operations for each function in this section.
void SetCurrentLockPickSkill()
{
currentLockPickSkill = this.currentLockPickSkill + 1
Debug.Log("currentLockPickSkill = " + currentLockPickSkill)
}
This last method is called SetCurrentLockPickSkill. This is a skill method instead of a movement method, and levels up like a standard level—in increments of 1—rather than with a slight increase like the other methods. The equation for this method is simpler because of this. For example, if the player levels up to level 5, the equation will be 5 + 1, which equals 7.
(It actually equals 6, but I just thought I'd do a sneaky on ya.)
A flow chart that shows the order of operations for each function in this section.
SECTION 3: Making the XP system work and level up
This part of the script is dedicated to the XP and leveling system, and allows the player to level up if enough XP has been given.
void Update()
{
if (Input.GetKeyDown(KeyCode.X) == true) { GainXP(1) }
if (xp >= xpForNextLevel)
{
LevelUp()
}
In the Update method, which calls the code within it every frame that the game is running, there are two methods that are called which we will go over. The first is the GainXP method, which is called when the X key has been pressed down. In this case, the method has been called with an integer with a value of 1, which represents the amount of XP that will be given to the player.
The second method that is called is the LevelUp method, which is called when the script detects that the value of the xp variable is bigger than or equal to the xpForNextLevel variable.
A flow chart that shows the order of operations for each function in this section.
public void GainXP(int xpToGain)
{
xp += xpToGain
Debug.Log("Gained " + xpToGain + " XP, Current Xp = " + xp + ", XP needed to reach next Level = " + xpForNextLevel)
}
In this method, XP is given to the player by adding the integer for this method (which in this case is 1) to the xp variable, and then reporting to the console that the player has gained the amount of XP that xpToGain is worth, then reporting the current amount of XP the player has, and then reporting the amount needed to level up.
A flow chart that shows the order of operations for each function in this section.
void LevelUp()
{
xp = 0f
level++
Debug.Log("level" + level)
SetXpForNextLevel()
SetCurrentMoveSpeed()
SetCurrentTurnSpeed()
SetCurrentJumpHeight()
SetCurrentLockPickSkill()
}
This is the method that is called to level up the player if the condition shown in the first excerpt for this section is met. In this method, the xp variable is reset back to 0, the level variable is incremented which will affect all of the buffs created in Section 2, and then the current level that has just been reached is reported to the console.
After this, all of the methods that were defined in Section 2 are called again to apply the new values of the variables for the newly obtained level of the player.
A flow chart that shows the order of operations for each function in this section.
SECTION 4: Player movement
This part of the script is dedicated to adding movement functionality to the player.
if (Input.GetKey(KeyCode.UpArrow) == true || Input.GetKey(KeyCode.W) == true) { this.transform.position += this.transform.forward * currentMoveSpeed * activeSprintModifier * Time.deltaTime }
if (Input.GetKey(KeyCode.DownArrow) == true || Input.GetKey(KeyCode.S) == true) { this.transform.position -= this.transform.forward * currentMoveSpeed * activeSprintModifier * Time.deltaTime }
This part of the section, although not the first function that appears in order in the script, is the first step of the player's ability to move. These functions are what allow the player to move forwards and backwards. In the case of moving forward, if the W key or the Up Arrow key has been pressed, then the script will calculate the given equation (also note how currentMoveSpeed is in the equation) and add it with transform.position for the player controller, and then set that as the value of transform.position. The same is done for moving backwards, however the equation uses subtraction instead of addition, and it looks for the S key or Down Arrow key instead.
A flow chart that shows the order of operations for each function in this section.
if (Input.GetKey(KeyCode.E) == true) { this.transform.position += this.transform.right * currentMoveSpeed * activeSprintModifier * Time.deltaTime }
if (Input.GetKey(KeyCode.Q) == true) { this.transform.position -= this.transform.right * currentMoveSpeed * activeSprintModifier * Time.deltaTime }
This next part of the script works similarly to the functions for moving forwards and backwards, except it looks for the E and Q keys instead, and it also uses transform.right instead of transform.forward. This allows the player to strafe left and right.
A flow chart that shows the order of operations for each function in this section.
if (Input.GetKey(KeyCode.RightArrow) == true || Input.GetKey(KeyCode.D) == true) { this.transform.RotateAround(this.transform.position, Vector3.up, currentTurnSpeed * Time.deltaTime) }
if (Input.GetKey(KeyCode.LeftArrow) == true || Input.GetKey(KeyCode.A) == true) { this.transform.RotateAround(this.transform.position, Vector3.up, -currentTurnSpeed * Time.deltaTime) }
This part of the script is for rotating the player, allowing them to look around and navigate the game world more effectively. This part works by using transform.RotateAround to rotate the player character with the given variables if it detects that the D or A keys, or the Right or Left Arrow keys have been pressed.
A flow chart that shows the order of operations for each function in this section.
SECTION 5: User convenience
This last part of the script is for user convenience, which just makes the player's life easier in terms of things like quitting the game with a single key press.
if (Input.GetKeyDown(KeyCode.Escape) == true)
{
#if UNITY_EDITOR
{
EditorApplication.isPlaying = false;
}
#else
{
Application.Quit();
}
#endif
}
This final section of code allows the player to quit the game by simply pressing the Escape key. The script checks if the player has pressed the Escape key, and if it finds that the key has been pressed, it will then check to see if the game is being run in the Unity Editor, and if it finds that this is the case, it will exit playmode and return to the Editor, otherwise it will quit the application.
A flow chart that shows the order of operations for each function in this section.
The full script
This the full PlayerControllerThatLevelsUp.cs script, straight from the project. This version of the script includes the original colouring and also has the original comments that were removed from the code above.