# Basic 2D movement

I’ve been trying to look for a working and relatively simple to understand movement script, but all I’ve found so far have been too hard to understand or simply don’t produce the kind of movement I’m looking for (if they even work that is).

The movement I’m looking for is a simple horizontal movement with no acceleration (some features added later involve deceleration, so the possibility to have that should be there) and a jumping with a variable height based on how long button is pressed up to the max height of course. I’m also working on a tile based game, so make sure that the player can’t get stuck on the tiles while walking on them (which is a common problem with some scripts that otherwise seem to work just fine).

Now normally I would do something like this, but I’m not sure how to (and if you can) translate this to Unity:

``````//Semi-pseudo code

void Update() {

//Movement Direction
hsp = (key_right_hold - key_left_hold) * walksp;
vsp += grav;

//Add jump force if jump is pressed
if(key_jump_press == 1) {
vsp += -9;
}

//Gets rid of any upward force if jump key is released
if(vsp < 0 && !key_jump_hold) {
vsp = max(vsp,0);
}

//x and y refers to object's current position
x += hsp;
y += vsp;
}
``````

EDIT:

Here is my attempt at translating the code. When I run the code the variables change, but they are not begin applied to the object:

``````	void Update () {
hsp = Input.GetAxisRaw("Horizontal") * walkspd;
vsp += grav;

if(Input.GetKeyDown("Jump") == true)
{
vsp += -9;
}

if(vsp < 0 && Input.GetKey("Jump") == false)
{
vsp = Mathf.Max(vsp, 0);
}

x = gameObject.transform.position.x + hsp;
y = gameObject.transform.position.y + vsp;

gameObject.transform.position = new Vector2(x, y);
}
``````

You would normally use a Rigidbody2D to move your character since that allows it to detect collisions and react to them in a physically accurate way. Most of your code is fine the way it is structured, but instead of moving your character by directly changing the transform, you should have a reference to your Rigidbody2D and then either add forces to it or directly set its velocity vector.
A simple movement script without acceleration but with deceleration should look a little something like this:

``````float inputX;
bool jump = false;
float movementSpeed = 2f;
float jumpForce = 2f;
Rigidbody2D rb;

void Awake()
{
rb = GetComponent<Rigidbody2D>();
}

void Update()
{
inputX = Input.GetAxis("Horizontal");
jump = Input.GetKeyDown(KeyCode.Space);
}

void FixedUpdate()
{
if (inputX != 0)
rb.velocity = new Vector2(inputX * movementSpeed * Time.deltaTime, rb.velocity.y);

if (jump)
{
rb.velocity = new Vector2(rb.velocity.x, jumpForce);
jump = false;
}
}
``````

This should work, however it is far from being optimized. I recommend watching some of the official Unity tutorials or search for simple ones on youtube.

Unity has jumping and physics and gravity and such all preprogrammed, you can use those. There are plenty of tutorials arround for that. But I take it that you want to code these things yourself?

There are some things that are not fully correct in your code: if you use vsp += grav on every frame (I take it your grav variable has a negative value?), every frame your vsp value will drop lower and lower. So even if you jump it will still be far below zero.

You never use Time.deltaTime. As Update runs every frame. You need to multiply your speeds by the time it took to load the next frame. I wrote a little script for you, I tested it and it works:

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

public class moveTest : MonoBehaviour {

float walkSp = 2;
float jumpSp = 3;
float hMove;
float yMove;
float vsp;
float x;
float y;
float grav = -9.67f;

void Start () {

}

void Update () {

// if your y pos is above 0. Apply gravity every frame:

if (transform.position.y > 0)
{
vsp += grav * Time.deltaTime;
} else
{
vsp = 0;
}

// if you press jump. Apply to the jump speed to the vertical speed:

if (Input.GetButton("Fire1"))
{
vsp += jumpSp;
}

// your yMove and hMove should be your vsp and hsp times the deltatime, to adjust for framerate.
yMove = vsp * Time.deltaTime;

hMove = Input.GetAxisRaw("Horizontal") * walkSp * Time.deltaTime;
x = transform.position.x + hMove;
// character can never get lower then 0 y:
y = Mathf.Max(transform.position.y + yMove, 0);

transform.position = new Vector3(x, y, 0);
}
``````

Now your character will be more like a rocket then a jumping character. Because as long as you keep pressing jump, your character will keep gaining vertical speed. You might wanna limit that to only apply vsp if your character is grounded for example. Or only for a limited amount of time or wathever you see fit. One last tip: if something isn’t working split it up into smaller parts. Try to code the horizontal movement first for example, and get that to work. Then do the jumping.

Good luck!