I made a script that lets the player jump only if they are grounded. If I set the layer to default in unity, I can jump but I can jump in air aswell. Here is my code:
using System.Collections;
using System.Collections.Generic;
using UnityEditor.UIElements;
using UnityEngine;
public class PlayerController : MonoBehaviour
{
private PlayerControls playerControls;
[SerializeField] private float PlayerSpeed = 30f;
[SerializeField] private float jumpHeight = 5f;
[SerializeField] private LayerMask groundLayer;
Rigidbody2D rb;
private Collider2D col;
private void Awake()
{
playerControls = new PlayerControls();
rb = GetComponent<Rigidbody2D>();
col = GetComponent<Collider2D>();
}
private void OnEnable()
{
playerControls.Enable();
}
private void OnDisable()
{
playerControls.Disable();
}
private void Start()
{
if (gameObject.tag == "Player1") // Player1: Use WASD
{
playerControls.Player1.Jump.performed += _ => Jump();
}
else if (gameObject.tag == "Player2") // Player2: Use Arrows
{
playerControls.Player2.Jump.performed += _ => Jump();
}
}
private void Jump()
{
if (isGrounded())
{
rb.AddForce(new Vector2(0, jumpHeight), ForceMode2D.Impulse);
}
}
private bool isGrounded()
{
Vector2 topLeftPoint = transform.position;
topLeftPoint.x -= col.bounds.extents.x;
topLeftPoint.y += col.bounds.extents.y;
Vector2 bottomRightPoint = transform.position;
bottomRightPoint.x += col.bounds.extents.x;
bottomRightPoint.y -= col.bounds.extents.y;
return Physics2D.OverlapArea(topLeftPoint, bottomRightPoint, groundLayer);
}
// Update is called once per frame
void Update()
{
float playerInput;
// Read the movement value
if (gameObject.tag == "Player1") // Player1: Use WASD
{
playerInput = playerControls.Player1.Move.ReadValue<float>();
}
else if (gameObject.tag == "Player2") // Player2: Use Arrows
{
playerInput = playerControls.Player2.Move.ReadValue<float>();
}
else
{
playerInput = 0;
}
// Move the player
rb.AddForce(new Vector2(playerInput , 0) * Time.deltaTime * PlayerSpeed, ForceMode2D.Impulse);
}
}