2D Controller

Hey guys!

I started a small 2D project and just finished creating the controller. I decided since in past games I have always hardcoded the controls to be mapped to specific keys I would try to use the InputManager for once, since the project is so new right now.

So basically it is a 2D top down, WASD + Arrow key movement. You cannot move diagonally. I have that all working perfect with WASD or Arrow Keys.

Since I am using the GetAxisRaw for both Horizontal and Vertical I thought this would be a good opportunity to fine tune my wired XBOX 360 controller.

So I almost have it working, but I am running into some issues with the sprites animations, or facing. Which currently works fine with WASD or Arrow Keys but it doesn’t always work with joystick. I am sure I need to fine tune the values in the InputManager but I’m really not sure exactly what I should be looking for.

So here is my player’s movement code and how I currently have my InputManager. The main issue right now is the animations don’t always change.

//Player Movement
 private void FixedUpdate()
    {
        float currentMoveSpeed = speed * Time.fixedDeltaTime;

        float horizontal = Input.GetAxisRaw("Horizontal");
        bool isMovingHorizontal = Mathf.Abs(horizontal) > 0.5f;

        float vertical = Input.GetAxisRaw("Vertical");
        bool isMovingVertical = Mathf.Abs(vertical) > 0.5f;

        PlayerMoving = true;

        if (isMovingVertical && isMovingHorizontal)
        {
            //moving in both directions, prioritize later
            if (wasMovingVertical)
            {
                rb2d.velocity = new Vector2(horizontal * currentMoveSpeed, 0);
                lastMove = new Vector2(horizontal, 0f);
                AdjustLiveFacing(lastMove);
                return;
            }
            else
            {
                rb2d.velocity = new Vector2(0, vertical * currentMoveSpeed);
                lastMove = new Vector2(0f, vertical);
                AdjustLiveFacing(lastMove);
                return;
            }
        }
        else if (isMovingHorizontal)
        {
            rb2d.velocity = new Vector2(horizontal * currentMoveSpeed, 0);
            wasMovingVertical = false;
            lastMove = new Vector2(horizontal, 0f);
            AdjustLiveFacing(lastMove);
            return;
        }
        else if (isMovingVertical)
        {
            rb2d.velocity = new Vector2(0, vertical * currentMoveSpeed);
            wasMovingVertical = true;
            lastMove = new Vector2(0f, vertical);
            AdjustLiveFacing(lastMove);
            return;
        }
        else
        {
            PlayerMoving = false;
            rb2d.velocity = Vector2.zero;
            AdjustStopFacing(lastMove);
            return;
        }
    }
//Animation handling functions

 private void AdjustStopFacing(Vector2 _dir)
    {
        if (_dir == Vector2.up) { anim.Play("P_Stop_Up"); }
        if (_dir == Vector2.down) { anim.Play("P_Stop_Down"); }
        if (_dir == Vector2.right) { GetComponent<SpriteRenderer>().flipX = false; anim.Play("P_Stop_Right"); }
        if (_dir == Vector2.left) { GetComponent<SpriteRenderer>().flipX = true; anim.Play("P_Stop_Right"); }

        direction = _dir;

        playerAS.Stop();
    }

    private void AdjustLiveFacing(Vector2 _dir)
    {
        if (_dir == Vector2.up) { anim.Play("P_Walk_Up"); }
        if (_dir == Vector2.down) { anim.Play("P_Walk_Down"); }
        if (_dir == Vector2.right) { GetComponent<SpriteRenderer>().flipX = false; anim.Play("P_Walk_Right"); }
        if (_dir == Vector2.left) { GetComponent<SpriteRenderer>().flipX = true; anim.Play("P_Walk_Right"); }

        direction = _dir;

        ah.PlayAudioClip(0, .6f, true);
    }

My current InputManager

Thanks guys!

UPDATE: I got it working! So without changing anything and adding one extra line of logic to each of my sprite adjusting methods it works.

Basically I round the Vector2 direction that it uses to handle sprite facing / animations so it always gets a whole number. So -1 - 1 and PRESTO CHANGO! That SEEMS to be the fix.

Let me know if there was something easier I could have done or if this will be future proof!

//New line added to both Adjust functions
_dir = new Vector2(Mathf.Round(_dir.x), Mathf.Round(_dir.y));

makes sense as they process as 1 and -1 on vector. (Actually -1, 0, 1) and some people can confuse the vector with speed. It’s just + or - or neutral. (left, neutral, or right.) or (up, neutral, down) on position. This can be seen if you use a debug.log and wrap your code in () and run in unity checking console. What is neat about understanding this is that we can also use ‘0’ to face a player forward straight away or set a delay for a nice sonic style away from controller animation. Hope this helps someone in future.