how do I make an object move diagonally at the same speed as left to right or up and down?

I know that the title for this question isn’t specific enough. I do mean specifically with Input.GetAxis(“”).

So hear is an example line of code with just a float variable “spriteSpeed” to show what I’m talking about:

transform.Translate(spriteSpeed * Time.deltaTime * Input.GetAxis("Horizontal"), spriteSpeed * Time.deltaTime * Input.GetAxis("Vertical"), 0.0f);

Also just be sure to know that this is in a 2D game.

Now what this code does is move the object from side to side or left to right depending on what buttons you press in game. If you press a horizontal button whilst pressing a vertical button the sprite will move diagonally.

The problem is that the sprite moves faster when moving diagonally. I sort of understand this to be because the speed is being added to the equation twice so basically speed is doubled… at least I think that’s what’s happening I don’t know I might very well be wrong. But anyways the question is simple.

HOW DO I MAKE IT NOT DO THAT?

I know I used hear instead of here in the first part of this thread. Just forget about it.

Oh dang it I also said “from side to side or from left to right” I meant to say “left to right or up and down”

dude I’m tired it’s late.

Try to visualise the issue. If you hit up, you’re making a vector of (0, 1). Right is (1, 0). But both is (1, 1). If you draw a square, the distance from the center to the corner is longer than the distance to the middle of one of the sides.

So instead, you want to make a circle, which has the same distance to any point along its circumference. This is easily done by just normalising your direction (meaning it will have a length of 1, always) before using it.

Though firstly, don’t write long lines of code like that. Break it up so you can clearly see what you’re doing:

float delta = spriteSpeed * Time.deltaTime;
float xDir = Input.GetAxis("Horizontal");
float yDir = Input.GetAxis("Vertical");
Vector3 direction = new Vector3(xDir, yDir, 0);
direction = direction.normalized * delta;
transform.Translate(direction);

In this case we get the normalized direction and then apply our speed/delta time.

2 Likes

Thanks this worked really good!

1 Like

And I also do understand it better now so thanks!

1 Like

Elliptical Grid Mapping
9816291--1410558--屏幕截图 2024-05-06 104627.png

Unlike Input.GetAxisRaw, Input.GetAxis will return a float in the range of 0 to 1 and so sometimes it’s best to clamp the direction instead of normalizing it so then you get smoothed Input which can help to give the impression of inertia. This is especially useful for character controller scripts that will often just pass values from GetAxis to CharacterController.Move.

It all depends on the kind of feel you’re going for. Some people like a slightly heavy realistic feel while others like a light and fast responsive movement. I guess it comes down to whether your character is a tank or a fly…

        Vector3 direction=new Vector3(Input.GetAxis("Horizontal"),Input.GetAxis("Vertical"),0);
        direction=Vector3.ClampMagnitude(direction,1f);
        transform.Translate(direction*spriteSpeed*Time.deltaTime);

Can you elaborate further on the difference clamped vs normalized?
I understand what your saying about it giving an “inertial” feeling to movement, but why, or what is the difference and how does that affect (what I would have thought) the magnitude of the players motion?

Clamped is “keep it within this range”

Normalized is “keep its magnitude at 1.0”

You can see both of these features in my VAButton virtual touch joystick class.

https://github.com/kurtdekker/proximity_buttons/blob/master/proximity_buttons/Assets/ProximityButtons/VAButton.cs

public bool doClamp;
public bool doNormalize;