Move relative to screen

I use top down 60 deg tilted camera and want move always visually straight directions relative to screen (up, down, left, right). When object is near screen edges it starts moving diagonally (visually) probably because of camera tilt. I tried with ScreenPointToRay but it doesnt work because even when there is no input it gives slightly offset from start position.

float delta = Time.deltaTime;

float h = Input.GetAxisRaw("Horizontal");
float v = Input.GetAxisRaw("Vertical");

Vector3 screen = MainCamera.WorldToScreenPoint(transform.position);

screen += new Vector3(h * 10, v * 10, 0);

Ray ray = MainCamera.ScreenPointToRay(screen);

RaycastHit hit;

Physics.Raycast(ray, out hit, Mathf.Infinity, 1 << 15); // 15 layer - ground plane

Vector3 world = new Vector3(hit.point.x, transform.position.y, hit.point.z);

Vector3 dir = (world - transform.position).normalized;

transform.position += dir * Speed * delta;

Better with viewport but still sometimes conversion to viewport and back to world same value gives slighltly offset. Is there more reliable solution?

if (h != 0 || v != 0)
{
Vector3 view = MainCamera.WorldToViewportPoint(transform.position);

view.x = (h > 0) ? 1 : (h < 0) ? 0 : view.x;
view.y = (v > 0) ? 1 : (v < 0) ? 0 : view.y;

Ray ray = MainCamera.ViewportPointToRay(view);

RaycastHit hit;

Physics.Raycast(ray, out hit, Mathf.Infinity, 1 << 15);

Vector3 world = new Vector3(hit.point.x, transform.position.y, hit.point.z);

Vector3 dir = (world - transform.position).normalized;

transform.position += dir * Speed * delta;
}