Jump Up Onto And Down From Platforms

How can we make a platform decide if a player can move through it or get stopped by it? An easy solution is to use the y coordinate of the player to turn the platform’s collider off and on. If the player is lower than the platform then they should be able to jump up through it and land safely on top.  You can also hop down off the platform by turning off the collider for a short amount of time.

You can play test it here (full screen is not working at the moment).

In the example I have locked the x coordinate of the player to prevent sideways motion and am using two scripts, one for the player and one for the platforms.

The player and platforms both have a RigidBody2D and a BoxCollider2D attached to them as well as their respective scripts. Make sure to link your Player to the LedgeSolidity script and set the platforms’ RigidBody2Ds to kinematic. The bottom platform has no script attached so you can’t accidentally fall off it.

If you want to practice using the same assets, I got mine from the pixabay:

Squirrel

Platform

Sky

These are the scripts I wrote to demo this effect:

 

PlayerControl.cs



public class PlayerControl : MonoBehaviour
{

	public float thrust = 75f;
	//the force the player is moved up by
	private float maxJumpTime = 0.1f;
	// stops you from being able to fly.

	private float jumpUpTimer = 0;
	private float jumpDownTimer = 0;
	// seperate timers help prevent jumping up and down from interfering with each other.

	private Vector3 initialPos;
	private bool canJumpUp = true;
	public bool canJumpDown = true;
	// also help prevent jumping up and down from interfering with each other.

	void Start ()
	{
		initialPos = transform.position;
	}

	void Update ()
	{
		// here I am locking the x and z axis.
		transform.position = new Vector3 (initialPos.x, transform.position.y, initialPos.z);

		//this line makes the camera follow the player in the y axis only.
		Camera.main.transform.position = new Vector3 (Camera.main.transform.position.x, transform.position.y, Camera.main.transform.position.z);

		// If the left mouse button is pressed, the jump has not yet completed and the player is not curretly jumping down...
		if (Input.GetMouseButton (0) && jumpUpTimer <= maxJumpTime && jumpDownTimer == 0 && canJumpUp) {
			canJumpDown = false;
			jumpUpTimer += Time.deltaTime;
			GetComponent<Rigidbody2D> ().AddForce (Vector3.up * thrust);
			// stops the player from being able to jump down and adds a positive force to the y direction.
		}
		// If the right mouse button is pressed, the jump has not yet completed and the player is not curretly jumping up...
		if (Input.GetMouseButton (1) && jumpDownTimer <= maxJumpTime && jumpUpTimer == 0 && canJumpDown) {
			canJumpUp = false;
			jumpDownTimer += Time.deltaTime;
			GetComponent<Rigidbody2D> ().AddForce (Vector3.up * thrust / 3);
			// stops the player from being able to jump up and adds a smaller positive force to the y direction to make it look like the player 'hops' down.
		}
	}

	// if the player is currently touching the ledge...
	void OnCollisionStay2D ()
	{
		// if the respective mouse buttons have been released reset everything so that the player can jump again.
		if (!Input.GetMouseButton (0)) {
			canJumpDown = true;
			jumpUpTimer = 0;
			print ("zero");
		}
		if (!Input.GetMouseButton (1)) {
			canJumpUp = true;
			jumpDownTimer = 0;
			print ("zero");
		}
	}
}








LedgeSolidity.cs


using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class LedgeSolidity : MonoBehaviour
{

	public GameObject player;
	private Collider2D col;
	private bool falling = false;
	private float fallTimer;
	private float maxFallTime = 0.8f;

	// The max fall time should be adjusted individually to your specific project. It sets the time the platform's colliders turn off for.

	void Start ()
	{
		col = GetComponent<Collider2D> ();
	}

	void Update ()
	{
		// Pressing the right mouse button turns off collisions on the platforms. GetMouseButtonDown tests if the mouse has been clicked down and only fires once per click.
		if (Input.GetMouseButtonDown (1) && player.GetComponent<PlayerControl> ().canJumpDown) {
			falling = true;
		}
		if (falling == true) {
			fallTimer += Time.deltaTime;
		}
		if (fallTimer >= maxFallTime) {
			falling = false;
			fallTimer = 0;
		}
		// I added 0.6 to the y position of the platform to account for the width of my box collider - you will have to adjust this based on your colliders.
		if (player.transform.position.y > transform.position.y + 0.6 && !falling) {
			col.enabled = true;
		} else {
			col.enabled = false;
		}
		
	}
}







Facebook Comments

Leave a Reply

Your email address will not be published. Required fields are marked *