How to get 8 direction Movement with controller sticks | Topdown 3D

Im working on an 3d rpg top down view.
Something like the zelda links awakening remake.

What im trying to achieve ist that the player rotates to the direction you press and then just goes forwards and this in only 8 directions.

I already got this working with WASD and the dpad, there it obviously works because you cant press in between two buttons if you know what i mean.

But i need a way to clamp the joystick input to only the 8 directions. How can i achieve this ?
I hope you understand what i mean.
This is the code ive already written.
Note that im using the new input system.

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

public class PlayerMovement : MonoBehaviour
{
    private PlayerInputActions playerInput;

    private Rigidbody rb;

    [SerializeField]
    private float playerSpeed;

    private float angle;

    private Quaternion targetRotation;

    private Vector2 input;

    private Transform cam;

    void Awake()
    {
        playerInput = new PlayerInputActions();
        rb = GetComponent<Rigidbody>();
    }

    void Start()
    {
        cam = Camera.main.transform;
    }

    void Update()
    {
        GetInput();

        if (input.x == 0 && input.y == 0) return;

        CalculateDirection();
        Rotate();
        Move();
    }

    void GetInput()
    {
        input.x = playerInput.Player.Move.ReadValue<Vector2>().x;
        input.y = playerInput.Player.Move.ReadValue<Vector2>().y;
    }

    void CalculateDirection()
    {
        if (input.sqrMagnitude > 1.0f)
            input = input.normalized;

        angle = Mathf.Atan2(input.x, input.y);
        angle = Mathf.Rad2Deg * angle;
        angle += cam.eulerAngles.y;
    }

    void Rotate()
    {
        targetRotation = Quaternion.Euler(0, angle, 0);
        transform.rotation = targetRotation;
    }

    void Move()
    {
        //transform.position += transform.forward * 5 * Time.deltaTime;
        rb.velocity = transform.forward * 200 * Time.fixedDeltaTime;
    }

    void OnEnable()
    {
        playerInput.Enable();
    }

    void OnDisable()
    {
        playerInput.Disable();
    }
}

I made this angle-snapping script a while back. I never found a need for angle offsets, so it’s a bit simple in how it works (still calculates a magnitude though, among other things), but this should fulfill your needs:

/// <summary>
/// Snaps the input Vector2 to the nearest angle, starting from Vector2.right and circling counterclockwise
/// </summary>
/// <param name="vector">The vector to be processed</param>
/// <param name="increments">Number of increments (recommended: power of 2, value of 4 or greater)</param>
/// <returns></returns>
public static Vector2 SnapAngle(Vector2 vector, int increments)
{
	float angle = Mathf.Atan2(vector.y, vector.x);
	float direction = ((angle / Mathf.PI) + 1) * 0.5f; // Convert to [0..1] range from [-pi..pi]
	float snappedDirection = Mathf.Round(direction * increments) / increments; // Snap to increment
	snappedDirection = ((snappedDirection * 2) - 1) * Mathf.PI; // Convert back to [-pi..pi] range
	Vector2 snappedVector = new Vector2(Mathf.Cos(snappedDirection), Mathf.Sin(snappedDirection));
	return vector.magnitude * snappedVector;
}

Also, another note:

Don’t multiply Time.fixedDeltaTime into your velocity!

rb.velocity = transform.forward * 200 * Time.fixedDeltaTime;

… is the same as…

rb.velocity = transform.forward * 200f / 50f;
rb.velocity = transform.forward * 4f;
rb.velocity = transform.forward * playerSpeed; // (playerSpeed = 4f)