Calling normalize twice?

Hi. Why do I have to call normalize twice on this Vector? What does calling normalize twice do? If I only normalize once, the vector reaches numbers below 1.0 and thus the objects move slower when the mouse is close to them.

Thanks.

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

public class Organism_Movement : MonoBehaviour
{
    public float zTarget;
    public float radius = 2f;
    public float movespeed = 5f;
    void FixedUpdate()
    {
        var mousePos = Camera.main.ScreenToWorldPoint(Input.mousePosition);
        Vector2 dir = (mousePos - transform.position).normalized;
        Move(dir);
    }

    void Move(Vector2 direction){
        transform.position += (Vector3)direction.normalized * Time.deltaTime * movespeed;
    }

    void MoveToPosition(Vector2 pos){

    }
}

The reason you’re having this problem is that you’re doing this:

var mousePos = Camera.main.ScreenToWorldPoint(Input.mousePosition);

The var hides the type but that’s actually a Vector3, and it’s going to be somewhere on your camera plane (probably around z = -10). Meanwhile transform.position is probably around z = 0. So when you do this:
(mousePos - transform.position).normalized you’re normalizing that Vector3 which includes some z axis portion. But right after you normalize it you’re assigning it to a Vector2:Vector2 dir = (mousePos - transform.position).normalized;When you do that, you chop off the z part, and what you’re left with is a Vector2 that is not normalized at all! Hence the need for re-normalizing it inside Move()

To fix all this you can change var to Vector2, and be a little more cautious in the future about using var when the types are not that clear.

Vector2 mousePos = Camera.main.ScreenToWorldPoint(Input.mousePosition);
Vector2 dir = (mousePos - (Vector2)transform.position).normalized;
3 Likes

Thanks.

But why does removing the Z part of a normalized Vector3 make it unnormalized?

Because the Z was nonzero when it was a Vector3 and got normalized.

Thus X and Y magnitudes did not vector up to 1: it was X,Y,Z that did, then you lopped off the Z when you stuck it in a Vector2.

Try it yourself in code. Normalize a (1,1,1) vector and look at X,Y, then normalize a (1,1,0) vector and check X,Y… quite different.

PS… just to state the obvious, (1,1,1) is not a normalized vector. Neither is (1,1,0)

PPS… I have committed this exact error about a year ago in a flight mode of Jetpack Kurt and ended up with an incorrectly too-powerful reaction control jet… it only happened because I had a complicated hack to simulate reduced vehicle mass (and hence reduced inertial tensor) as fuel burned off and was playing vector games with the thrust. It’s correct now.

2 Likes

Also those are good examples to show what is happening. Normalizing means calculating the length of the vector and dividing all elements through that length. The length of a vector is just pythagoras which works in any dimension. So for the case of (1,1,1) the length of this vector is the square root of the sum of the squares of each component. So sqrt(1*1 + 1*1 + 1*1) which is just sqrt(3) which is approximately 1.732. When we divide each of our components by this length we get (0.57735, 0.57735, 0.57735)

We can check if the length is really 1 by doing the same again. The square of 0.57735 is approximately 0.333333. Since all 3 components have the same value the sum is 0.999999 so essentially “1”. Now when we remove one component our vector would look like this instead: (0.57735, 0.57735, 0) Since the last component is now 0 the total squared length is just about 0.666666. Re-normalizing would of course fix the issue and yield a vector like (0.7071, 0.7071, 0)

Just for clarification,
(1,1,1) has a length of sqrt(3) --> 1.732
while
(1,1,0) has a length of sqrt(2) --> 1.414

Nope, it isn’t :). The Euclidean distance works in all dimensions the same way. It’s always the squareroot of the sum of the squares, no matter if we have 1, 2, 3 or 10 dimensions. In dimension one we could simply use “Abs” instead, but squaring the number and taking the square root would have the same effect. The pythagorean theorem about the relationship between the sides and their corresponding squares.

In higher dimensions it gets a bit tricky to envision. However you can think about doing two dimensions first which gives you the length of a new diagonal line in those 2 dimensions. Once you have that you do it again in a new 2d space between the new diagonal line and the third axis which again is a 2d problem. So s = sqrt(x^2 + y^2) and len = sqrt(s^2 + z^2). So it can be carried out as a single sqrt(x^2 + y^2 + z^2)

1 Like