Search Unity

Resolved Unity 2D Isometric Grid Based Movement Key Overlapping

Discussion in '2D' started by StiryMixy, May 5, 2021.

  1. StiryMixy

    StiryMixy

    Joined:
    May 5, 2021
    Posts:
    7
    Hello, I'm fairly new to Unity. I'm trying to code a grid based movement system in an isometric tilemap, and for the most part it works, except for a little wrinkle:

    Project Image:
    I was able to successfully code it in a way that it moves 1 tile on 1 press of a movement key (WASD), and moves continuously through multiple tiles upon a long press of any movement key (WASD) and stops on the center of any tile that it ends up on upon release of the long pressed movement key.

    Code:
    The problem with the code is movement key overlapping (as I call it);
    • if I keep pressing "W", the player will keep moving up continuously,
    • but if I then press and keep pressing "A" concurrently with the "W" key, the player will not change course and still goes up.
    Image:
    In another scenario;
    • if I keep pressing "D", the player will keep moving right continuously,
    • but if I then press and keep pressing "A" concurrently with the "D" key, the player will change course and will move left in accordance with pressing "A" despite still holding "D",
    • and if I release "A" but still hold "D", the player will then change back to its original course of moving right instead of left.
    This scenario persists with other possible combination of "D" & "the rest" keys such as;
    • "D" and "S" pair, and
    • "D" and "W" pair.
    Image:
    So therein lies the problem of inconsistency in character movement, wherein sometimes I am able to change course regardless if I'm holding 2 buttons, but sometimes I cannot.

    I want to get rid of this problem by coding it in a way that player direction will change with any possible combination of keys, regardless if it was long pressed & overlapping or not (prioritizing the last long pressed key), evoking a sense of fluidity in controlling the character.

    But so far have come up empty.

    I have tried making use of Vector3.SmoothDamp instead of LERP, removed the use of Coroutines entirely and relied solely on calling a method, arrived with a bunch of different combinations of booleans in every corner of the code and still come up dry in getting rid of this problem.

    If anyone can help me with this, I will be grateful!
     
  2. rarac

    rarac

    Joined:
    Feb 14, 2021
    Posts:
    570
    well you are setting _isMoving = true;

    so whatever input comes after that will be ignored because of this part

    if (!_isMoving)

    because of that your movement is on priority by the order of your code - 1-w 2-a 3-s 4-d
     
  3. StiryMixy

    StiryMixy

    Joined:
    May 5, 2021
    Posts:
    7
    Yes this is correct. Any chance you know a better way of detecting input without discriminating against key ordering in the code?

    My code initially made use of "else ifs" instead of all "ifs", as I was hoping to avoid the problem altogether, but "else ifs" just constrained movement further by making it so that I cannot change course after the first button since Unity's "Update" method checks every frame.
     
  4. rarac

    rarac

    Joined:
    Feb 14, 2021
    Posts:
    570
    you can add a variable to override the priority with getkeydown

    something like this

    Code (CSharp):
    1.  
    2.  
    3. public byte dirMovePriority;
    4.  
    5. void Update()
    6.     {
    7. if (Input.GetKeyDown(KeyCode.W)){ dirMovePriority = 0;}
    8. if (Input.GetKeyDown(KeyCode.A)){ dirMovePriority = 1;}
    9. if (Input.GetKeyDown(KeyCode.S)){ dirMovePriority = 2;}
    10. if (Input.GetKeyDown(KeyCode.D)){ dirMovePriority = 3;}
    11.  
    12. switch(dirMovePriority){
    13. case 0:
    14.       if (Input.GetKey(KeyCode.W))
    15.         {
    16.             if (!_isMoving)
    17.             {
    18.                 StartCoroutine(UpdateCurrentCell(Vector3Int.up));
    19.             }
    20.         }
    21. break;
    22. case 1:
    23.         if (Input.GetKey(KeyCode.A))
    24.         {
    25.             if (!_isMoving)
    26.             {
    27.                 StartCoroutine(UpdateCurrentCell(Vector3Int.left));
    28.             }
    29.         }
    30. break;
    31. case 2:
    32.         if (Input.GetKey(KeyCode.S))
    33.         {
    34.             if (!_isMoving)
    35.             {
    36.                 StartCoroutine(UpdateCurrentCell(Vector3Int.down));
    37.             }
    38.         }
    39. break;
    40. case 3:
    41.       if (Input.GetKey(KeyCode.D))
    42.         {
    43.             if (!_isMoving)
    44.             {
    45.                 StartCoroutine(UpdateCurrentCell(Vector3Int.right));
    46.             }
    47. break;
    48. }
    49.  
    50.         }
     
  5. StiryMixy

    StiryMixy

    Joined:
    May 5, 2021
    Posts:
    7
    Although with this kind of code structure, I am only able to move at 1 direction per any key press.

    I.E.
    • Pressing W will move the player forward...
    • And then pressing A together with the earlier W will do nothing and will still move the player forward...
    • If I release W while still holding A, the player will stop moving entirely instead of moving left
    I'm aiming for a code structure where I can move in one direction until I long press another key and change direction regardless if I'm still holding any other keys or not.
     
  6. rarac

    rarac

    Joined:
    Feb 14, 2021
    Posts:
    570
    this should do your point 1 and 2 correctly

    for your 3rd point if you want to release W while holding A then you should add a check for getkeyUP

    make sure you erase the old parts of your code that would override this new system
     
  7. StiryMixy

    StiryMixy

    Joined:
    May 5, 2021
    Posts:
    7
    This is resolved now, managed to fix it with the following code:

    Had to make use of stacks in the end to detect the latest key pressed, and store a stack of previously "still-pressed" keys.