How To Make Terrain Effect Direction With A Top Down 2D View

Making the terrain your character is walking on have an impact on the controls can add extra depth to your control scheme.

For a top down 2D game there is not any gravity and your player is not using collision detection to walk on surfaces so doing things like walking up a set of stairs or falling off of a platform can require a little extra thought. There are many ways you could approach a problem like this, however a quick and easy way is to check what surface the player is walking on and then calculate how the player should move based on the surface.

In the example the player can go up the stairs and fall off the cliffs if they approach them. When pressing left or right on the stairs the player needs to actually move up the stairs and not just into them in order for the control scheme to feel natural.

To achieve this quickly I have attached a static RigidBody2D and a Collider2D (set to Trigger) to the tiles that make up the scene. The colliders are tagged appropriately based on what function they should perform. I use a Raycast2D to establish the tag of what the player is standing on and if the player is on the stairs or has walked off a cliff then the control scheme is amended to compensate.

In order to get the player to ascend or descend the stairs whilst only pressing left or right, when the player is standing on the stairs and moves, the x direction of the movement is either added or subtracted to the y direction depending on the direction of the stairs.

The following script is attached to the player. I also added a small 2D Circle Collider to the player, locked the z rotation and threw up a few 2D Box Colliders that were not set to triggers to prevent the player from walking off into the clouds. You could easily generate these at runtime with a script on the tiles that checked if they were touching another tile or not but in this instance i just dragged them to where I wanted them.

See the example here.

Bonus: The basic sprite sheet I made for this:

PlayerController.cs

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

public class PlayerController : MonoBehaviour
{

	public float speed = 4;
	public GameObject rayOrigin;
	// this is for an empty gameObject at the base of your player - make sure it is offset from your player's collider.

	private Rigidbody2D rb2d;
	private string directionAmender = "normal";
	// you could alter an int, I find this easier to read.

	private Vector2 movement;

	void Start ()
	{
		rb2d = GetComponent<Rigidbody2D>();
	}

	void FixedUpdate ()
	{

		Camera.main.transform.position = new Vector3 (transform.position.x, transform.position.y, Camera.main.transform.position.z);

		// using the Raycast you can see what type of terrain you are traversing.
		RaycastHit2D hit = Physics2D.Raycast (rayOrigin.transform.position, Vector2.zero);
		if (hit && hit.collider.tag == "Floor") {
			directionAmender = "normal";
		}
		if (hit && hit.collider.tag == "SDR") {
			directionAmender = "stairsDownRight";
		}
		if (hit && hit.collider.tag == "SDL") {
			directionAmender = "stairsDownLeft";
		}
		if (hit && hit.collider.tag == "Wall") {
			directionAmender = "fall";
		}

		// this sets up a system to adjust the players movement based on the terrain.
		float moveHorizontal = Input.GetAxis ("Horizontal");
		float moveVertical = Input.GetAxis ("Vertical");

		if (directionAmender == "normal") {
			movement = new Vector2 (moveHorizontal, moveVertical);
			rb2d.velocity = (movement * speed);
		}
		if (directionAmender == "stairsDownRight") {
			movement = new Vector2 (moveHorizontal, -moveHorizontal + moveVertical); //This is the key line that makes the stairs work.
			rb2d.velocity = (movement * speed);
		}
		if (directionAmender == "stairsDownLeft") {
			movement = new Vector2 (moveHorizontal, moveHorizontal + moveVertical); //This is the key line that makes the stairs work.
			rb2d.velocity = (movement * speed);
		}
		if (directionAmender == "fall") {
			rb2d.velocity = (Vector2.down * speed * 4);
		}
	}
}

Facebook Comments

Leave a Reply

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