The very first script I need to make is the Player movement script this will consist of mainly giving the player the ability to move left and right and to jump considering this is a platformer that I am making. Some other mechanics I might code are attack mechanics and a crouching movement.
Left and Right Movement:-
First I have my variables which refer to the speed at which the player is moving, the axis on which he will be moving along, and the bool for checking if the player is on the ground which relates to the jumping mechanic that I will be adding later.

This piece of the script takes the input from the player as long as they are using keys that would usually make a player move left and right, for instance, the A and D keys and the left and right arrow keys on a standard keyboard. By making the input of the player equal to the movement along the X-axis the computer knows that the input of the 'Horizontal' keys correlates to that of movent left and right.

I find this next bit a little hard to understand but I know that it works. Basically, this translates the Cowboy along the X-axis when it comes to moving left and right as Unity doesn't ready the variable 'movementX' as actually referring to moving along the axis so I have to tell it to do so using this code.
Jumping:-
For this mechanic, I will be using some more variables, I need the amount of force behind a jump so that the player can actually move when they jump and I have some 'feet'- which are a game object that needs to check if the player and the ground are in contact. I need to reference the ground so that I can check if the feet and ground are in contact and then I also need to know if the player is on the ground later on this is so that the game knows to run the animation for Jumping.

I have made it so that there is only one input from the player that will make the Cowboy jump and this is the Spacebar key, this is due to it being the most common jumping button in games and to your average gamer this is like second nature to them. To be able to jump the player needs to be on the ground, this is because I don't want them to be able to double jump, plus it makes it easier when it comes to coding other things in the future.

For the actual movement behind the jumping, I have done a similar thing to the left and right movement where the movement is along the Y-axis instead, I have also told unity that the jumping force is equal to the up movement along the Y-axis and the element that brings the player back down is the gravity that comes from rigidbody that is attached to the Cowboy.

I have an isGrounded check, it takes in the feet game object and the ground layers otherwise known as the ground to check if the Cowboy is on the ground, isGrounded is also being used to play the Cowboys animation, but it will only play the Jump animation if the spacebar has been pressed and if the Cowboy is not on the ground. The script will know if the Cowboy is not on the ground because the feet will not be touching the ground. If the feet are touching the ground the bool returns true and if not, the bool returns false.

Attacking:-
For this mechanic, I need an invisible point that acts as the end of the lasso which is named the attack point, as it is the point of attack. The attack point also needs to have a radius or a space in which it will attack within; so this is what 'attackPoint' and 'attackRange' do. I also need to reference the enemy this will be being attacked by the player so that the Attack function knows what it is attacking.

I wanted to make the game as easy as possible so I've used keyboard input for attacking, as I mentioned in the concept blog that I was going to map the attack to the F key so it has been mapped to take the input of the F key as the attack. When F has pressed the function for Attack() will run.

This line of code checks if the enemy's colliders' are within range of the point of attack and stores a list of the enemies that are hit; this is so that Unity knows that the player is trying to hit the enemies.

When the enemy's collider is hit the enemy will 'Take Damage' which is an int that depletes with each hit. I will explain this in more detail later when I decode the enemy's script. I chose to leave in the Debug Log as it's a handy little bit of information that tells the player that the Enemy is hit, it takes the Enemy's name tag and tells the player that the Enemy was hit.
Animation Coding:-
For me to be able to reference the animations and tell Unity what to do with the animations I need to declare and assign the Animator in which the animations are linked and stored together in. This is the same Animator that is already attached to the Cowboy, so I will drag that into the declared 'anim' Animator field.

This code makes it so that the walking animation will play when there is movement along the X-axis only, it takes the boolean that links the animations in the Animator and sets it to true or false depending upon the movement along the axis or not. This coding also makes it so that if that Player is walking to the left the animation will completely flip and turn left as well, and if the player is facing towards the right it practically stays the same, the function for it facing towards the right still has to be declared to stop any bugs. The scale size of the animation is set to not change (stay the same) as well on both sides of the argument.

In Attack() when the F key is pressed it triggers the animation for attacking and the Cowboy will play the Attack animation.

The function that makes the Jumping animation play is the isGrounded function, here there are two isGroundeds, one contains logic and the other is a reference to the boolean that is used in the Animator for the Cowboy. The boolean in Animator will be set to true if the isGrounded logic is true and the boolean in Animator will be set to false if the isGrounded logic is false which in turn will allow the Jumping animation to play or not.

Death:-
I made a separate script for the death because the movement script should only really be for moving. Something I have made for the game is a respawn but death mechanic, so it is decently hard to not kill the enemies, there is no limit on how many times you can respawn which I could have implemented but simply decided not to. The player dies by coming into contact with the enemies, in this case, the main enemy is the Robber but I've made it so that the Cowboy can die to the Cactuses as well as an added feature; and of course, with the game being a platformer if the player falls down the gaps in the floor they will also die and respawn. I've made a game object in the scene which is a point at which the player will respawn if they die, it's a static point and doesn't move. To access the Respawn points location I have had to declare it in the Death script, it's referred to as the 'respawnPoint'.

This script makes it so that if the player comes into contact with the Enemies or falls down a gap then the Cowboy the player was playing with will be destroyed(will die) and a prefab/clone of the Cowboy will spawn in at the location of the respawn point. The 'respawnPoint' of the Cowboy Death script is derived from the Level manager script that it was originally declared in.

Level Manager takes the 'respawnPoint' and the prefab of the Cowboy that I had made prior and clones the Cowboy in the place of the Respawn Point. The Level Manager script can be accessed from anywhere.


These screenshots are to demonstrate how I linked the variables to what they needed to be linked to, this made the scripts work how they were intended to work. An extra thing I added was a Physics2D material that's purpose was to not let the Cowboy stay attached to a wall if the player jumped up them, hence why it is named 'slippery'. I also froze rotation along the Z-axis because when the Cowboy would jump if he had caught an edge of something he would rotate, so this ensures that the Cowboy would always be upright.
Movement for the Cowboy
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class PlayerMovement : MonoBehaviour
{
public float movementSpeed;
public Rigidbody2D rb; //Reference to the rigidbody attatched to the Cowboy.
public Animator anim; //Reference to the animator
public Transform attackPoint; //Reference to the end of the lasso
public float attackRange = 0.5f;
public LayerMask enemyLayers;
public float jumpingForce = 20f; //how high player jumps
public Transform feet;
public LayerMask groundLayers;
float movementX; //For movement along X-axis
bool isGrounded; //Is the player on the ground?
private void Update()
{
movementX = Input.GetAxisRaw("Horizontal"); //Left & Right movement
if (Input.GetButtonDown("Jump") && IsGrounded())
{
Jump();
}
//Plays the walking animation
if (Mathf.Abs(movementX) > 0.05f)
{
anim.SetBool("isWalking", true);
}
else
{
anim.SetBool("isWalking", false);
}
//if movement if going toward the left the sprite animation will be flipped to face the left.
if (movementX > 0f)
{
Vector3 scale = transform.localScale;
scale.Set(1f, 1f, 1f);
transform.localScale = scale;
}
else if (movementX < 0f)
{
Vector3 scale = transform.localScale;
scale.Set(-1f, 1f, 1f);
transform.localScale = scale;
}
anim.SetBool("isGrounded", IsGrounded()); //makes makes sure player is grounded.
if (Input.GetKeyDown(KeyCode.F))
{
Attack();
}
}
private void FixedUpdate()
{
Vector2 movement = new Vector2(movementX * movementSpeed, rb.velocity.y); //Left & Right movement
rb.velocity = movement;
}
//Everything below is for the links to the animations.
void Jump() //for jump movement
{
Vector2 movement = new Vector2(rb.velocity.x, jumpingForce);
rb.velocity = movement;
}
//If Player is on the ground this will return true/yes if not, false/no, does this by checking if the feet are in contact with the "Ground" layer.
public bool IsGrounded() // to check if player is grounded
{
Collider2D isOnGround = Physics2D.OverlapCircle(feet.position, 0.5f, groundLayers);
if (isOnGround != null)
{
return true;
}
return false;
}
void Attack()
{
//play attack animation
anim.SetTrigger("Attack"); //Refers to the Attack trigger in animation
//detect enemies in range of attack, store list of enemies hit
Collider2D[] hitEnemies = Physics2D.OverlapCircleAll(attackPoint.position, attackRange, enemyLayers);
//kill them
foreach (Collider2D enemy in hitEnemies)
{
Debug.Log("You hit " + enemy.name); //Says in the Debug Log which enemy we hit.
enemy.GetComponent<Enemy>().TakeDamage(20);
}
}
}
Cowboy Death
public class CowboyDeath : MonoBehaviour
{
public Transform respawnPoint;
private void OnCollisionEnter2D(Collision2D collision)
{
if(collision.gameObject.CompareTag("Enemy") || collision.gameObject.CompareTag("NotGroundBarrier"))
{
Destroy(gameObject);
LevelManager.instance.PlayerRespawn();
}
}
}
Level Manager
public class LevelManager : MonoBehaviour
{
//This whole script will be made completely accessable globally. Which means I will not have to reference the script ever time it is needed
public static LevelManager instance;
public Transform respawnPoint;
public GameObject playerPrefab;
private void Awake()
{
instance = this;
}
public void PlayerRespawn()
{
Instantiate(playerPrefab, respawnPoint.position, Quaternion.identity);
}
}
Comments