Player movement line based

Hi,

I need player movement like this game:

I’ve got my character staying on the x,y lines, but the lane changes are not smooth.

My code:

      void FixedUpdate()
          {
              pos = transform.position;
              if (Input.GetKey(KeyCode.UpArrow))
              {
                  
                  pos += (Vector2.up * speed * Time.deltaTime);
                  pos.x = Mathf.RoundToInt(pos.x);
                  transform.position = pos;
      
              }
              else if (Input.GetKey(KeyCode.DownArrow))
              {
                          pos += (Vector2.down * speed * Time.deltaTime);
                  pos.x = Mathf.RoundToInt(pos.x);
                  transform.position = pos;
      
              }
              else if (Input.GetKey(KeyCode.LeftArrow))
              {
                          pos += (Vector2.left * speed * Time.deltaTime);
                           pos.y = Mathf.RoundToInt(pos.y);
                  transform.position = pos;
      
              }
              else if (Input.GetKey(KeyCode.RightArrow))
              {
                  
                  pos += (Vector2.right * speed * Time.deltaTime);
                  pos.y = Mathf.RoundToInt(pos.y);
                  transform.position = pos;
      
              }

This question is the same as mine , but i’ve not been able to understand it. Advanced grid movement vs free movement question - Questions & Answers - Unity Discussions

“Then add a threshold such that when the character is at an intersection, it doen’t need to be perfectly aligned with the centerlines, but instead will snap to align with them automatically when close enough.”

So, I see a few issues with your code.

  • Your character gets up to full speed in a single frame.
  • You are rounding the change in position to the nearest integer value.
  • You are limited to the arrow-keys.
  • A few other things that don’t affect the final movement of your character.

Now, we can fix the first point by using the Horizontal and Vertical input axes. We can fix this with something like:

var inputX = Input.getAxis("Horizontal");
var inputY = -Input.getAxis("Vertical");
var deltaPos = Vector2.zero;

if (Mathf.Abs(inputY) > Mathf.Abs(inputX)) {
    deltaPos.Y = speed * inputY * Time.deltaTime;
}
else {
    deltaPos.X = speed * inputX * Time.deltaTime;
}

transform.position += deltaPos;

By doing this, you can adjust the axis sensitivity values within the project settings, to increase (or decrease) the amount of time it takes a button press to go from zero to one (or negative one). Or, if what you want is a bit of a ramp/ease curve to control this, then you can add an AnimationCurve to your object’s settings, and pass in the unsigned axis’ value into the AnimationCurve’s Evaluate(…) method. This will allow to remap the input values without having to change the code.


Edit:

So, I took a closer look at what the game is doing, and based on that, the answer I game you is completely useless. While we can manually create the next Player Position in code, that’s a lot of code and that code would also be very dependent on how you’re representing the walkable and not-walkable areas in the game.

If this were a 3D game, I would use a nav-mesh for the player movement, and I would use the Player’s input to set the desired location you want the Player’s character to move to. More specifically, I would place the nav-agent’s desired location as one block away in the direction that the Player wants to move while the Player is providing directional input. And, when the Player is not providing directional input, I would set the Player’s current location as the desired location. The way the game works, is if the Player tries to move down and moving down is blocked, then one of two things can happen.

  • If the player is close to the center of the blocking cube, they stay in place.
  • If the player is off center from the blocking cube, and the path in the next is clear, then the character will move horizontally (despite trying to move downward). Once they move far enough horizontally to move down-ward, then it will move downward.

In the case of the nav-mash, when you set a target position that you can’t reach, the nav-mesh agent will move to the walkable location that’s nearest to the target position that you set. By playing with the settings and using nav mesh obstacles for destructible obstacles, I can recreate the the previous behavior while writing a lot less code.

Obstacles are 1 for everything i believe. All origin points are centered.
“Now, I’m guessing that this is a grid based game where you can check an 2D bool (or int) array for the presence of obstacles by entering a column-row index-pair. Yet, I don’t actually know that, that’s an assumption I’ve made.”
It will be, but i haven’t done all that yet, just working on the movement at the moment.