Project a vector onto a plane.

I am using the ProjectOnPlane function with the following arguments:

Vector3 project = Vector3.ProjectOnPlane(jumpspeed, Vector3.up);

As Vector3.up is short for writing new Vector3(0,1,0) , when i Debug this project vector using Debug.DrawRay(transform.position, project, Color.red);

I see the ray is towards the z axis.

Can anyone tell me a bit more about the ProjectOnPlane() function, and if the function simply projects on the perpendicular to the vector we are providing then why the projection was not done on x axis as both x and z are perpendicular to y axis.

Yes “ProjectOnPlane” simply projects the vector onto the plane that is perpendicular to the normal vector.

This line (due to simply using Vector3.up):

Vector3 project = Vector3.ProjectOnPlane(jumpspeed, Vector3.up);

would be the same as:

Vector3 project = jumpspeed;
project.y = 0;

So for trivial cases where the plane normal is one of the world axis / the target plane is identical with one of the 3 base planes it becomes quite easy to understand what actually happens. So since your normal is (0, 1, 0) the target plane is the X-Z plane.

Also keep in mind that the two vectors have to be in the same space. So either both vectors are worldspace directions or both a relative vectors of the same local space. Vector3.up doesn’t have a particular space. It depends on the interpretation. So if you have a worldspace velocity vector and Vector3.up, that would mean Vector3.up is equivalent to the worldspace up direction. The resulting vector would be a worldspace vector

However when you have a local space direction and Vector3.up, the up vector would also be a localspace vector (the blue axis of the gameobject). Of course the resulting vector will also be a local space vector in this case.

Like Hellium said in the comment if the resulting vector doesn’t have any x component your incoming vector doesn’t have one either.

edit
Just for reference:
ProjectOnPlane simply does:

public static Vector3 ProjectOnPlane(Vector3 vector, Vector3 planeNormal)
{
	return vector - Vector3.Project(vector, planeNormal);
}

and Project does:

public static Vector3 Project(Vector3 vector, Vector3 onNormal)
{
    float num = Vector3.Dot(onNormal, onNormal);
    if (num < Mathf.Epsilon)
        return Vector3.zero;
    else
        return onNormal * Vector3.Dot(vector, onNormal) / num;
}

So what actually happens is that your velocity vector gets projected onto the given normal vector. So the result of Project will be only the y-component of your velocity vector. This amount will be subtracted from your original velocity which only leaves the X and Z components. “num” is just the squared length of the normal and used to normalize the result in case the normal vector wasn’t normalized. So in your case Vector3.up is a normalized vector and num would be “1”

I have a more general question on this topic: when I rotate my direction vector 45° relative to the plane, the Vector3.ProjectOnPlane is, as expected (0, 0.71, 0). However, when I rotate my direction vector 45° relative to the plane in two dimensions, I get (0.5, 0.71, 0). So although the rotation is the same in both dimensions, the length of the projected vector is not the same in the two dimensions. To me, this is counter-intuitive.

I guess this has more to do with basic geometry understanding, but can anyone point me in the right direction?

Thanks Bunny83 for giving me your best guess answer (in spite of initially stating my question did not make much sense). It made me realize what exactly it is that I find hard to mentally visualize: “we further rotate our (0, 0.707, 0.707).vector around y (0,1,0) also be 45° This will lead to (0.5, 0.707, 0.5)”. So I guess this is not a Unity-specific problem at all but I need to instead wrap my head around some geometry textbook.

If you have a question you should ask a question and not posting an answer.

Sorry but your question doesn’t really make much sense. What do you mean by " 45° relative to the plane"? Note that “rotated vector” could mean anything. What is your starting vector and around which axis do you actually rotate? Do you apply euler angles rotation? What is even your plane normal? You can’t get (0, 0.71, 0) when you have a normal that points in the world up direction (0,1,0). That means you clearly use a different plane / plane normal.

Whatever you tried to ask here doesn’t seem to be related to the question that has been asked here since you have different vectors. Please don’'t try to hijack the question of someone else. Answers which are posted to a question have to answer the question that was asked here. If you have a similar question but this one doesn’t fully answer your specific case, ask a seperate question.

However

If you do ask a question make sure you include all necessary information to understand your case. If you have a vector tell us it’s initial state. If you apply rotations to it, tell us around which axis.

Anyways i try to give a best guess answer here. However if it doesn’t clear up your confusion, please ask a seperate question.:

Since in your second example the z component of your vector is 0 we can assume your plane normal is most likely either forward or -forward (0,0,1). So after a projection only the x and y components remains. Lets assume further that your initial vector you’re going to rotate is (0,1,0). In your first case you most likely applied a rotation around the x axis. Sin(45°) as well as Cos(45°) are both 0.707 (actually 1/Sqrt(2) or Sqrt(0.5)). So when rotating (0,1,0) around x(1,0,0) by 45° we get (0, 0.707, 0.707). Projecting down we just drop the z component and get (0, 0.707, 0).

However now before we project down we further rotate our (0, 0.707, 0.707).vector around y (0,1,0) also be 45° This will lead to (0.5, 0.707, 0.5) To check we can calculate the length of this vector and it is still 1. It’s just Sqrt(0.5² + 0.707² + 0.5²) == Sqrt(0.25 + 0.5 + 0.25) == Sqrt(1) == 1.

Of course when you project down that vector (again just dropping the z component) we get (0.5, 0.707, 0). Though i’m not quite sure what’s unintuitive about that result.

Thanks Bunny83 for giving me your best guess answer (in spite of initially stating my question did not make much sense). It made me realize what exactly it is that I find hard to mentally visualize: “we further rotate our (0, 0.707, 0.707).vector around y (0,1,0) also be 45° This will lead to (0.5, 0.707, 0.5)”. So I guess this is not a Unity-specific problem at all but I need to instead wrap my head around some geometry textbook.