# 'Rotating' a vector to have 1 axis = 0

I’m writing a wallrunning script. In it I have basically a projection of the velocity to the ‘wall axes’ (up, down, forward, backwards. Not sideways). The issue is that when I look a lot towards or away from the wall (so, sideways), the projection barely has any forward velocity, which turns into my wallrunning speed. Is there a way that I can sort of ‘rotate’ the velocity vector so that the X axis relative to the wall (again, sideways) is equal to zero?

The wallrunning parts of my code:

``````if(WallRunning == true) {
PlayerRB.drag = 1;

WallPointReg = CamTurn.transform.InverseTransformPoint(SlidePointReg);

if(WallRunTiltTimer == 0) {
Debug.DrawRay(transform.position, CharVel, Color.red);

if(WallPointReg.x > 0) {
if(CamTurn.transform.localEulerAngles.z < 7.5f) {
CamTurn.transform.Rotate(0, 0, 1.25f * Camera.GetComponent<CamControl>().TurnSpeed * 7.5f * Time.deltaTime, Space.Self);
}
if(CamTurn.transform.localEulerAngles.z > 7.5f) {
CamTurn.transform.localRotation = Quaternion.Euler(0, 0, 7.5f);
}
}else {
if(CamTurn.transform.localEulerAngles.z > 352.5f || CamTurn.transform.localEulerAngles.z == 0) {
CamTurn.transform.Rotate(0, 0, 1.25f * Camera.GetComponent<CamControl>().TurnSpeed * -7.5f * Time.deltaTime, Space.Self);
}
if(CamTurn.transform.localEulerAngles.z < 352.5f) {
CamTurn.transform.localRotation = Quaternion.Euler(0, 0, 352.5f);
}
}
}

PlayerRB.useGravity = false;
float VerticalWall = Input.GetAxis("Vertical") * Speed * Time.deltaTime;

//PlayerRB.constraints = RigidbodyConstraints.FreezePositionX | RigidbodyConstraints.FreezeRotationX | RigidbodyConstraints.FreezeRotationZ;

if(WallSpeedLimit > 12.5f) {
WallSpeedLimit = 12.5f;
}

if(CharVel.magnitude < WallSpeedLimit) {
WallSpeedLimit += ((WallSpeedAcc * Camera.transform.rotation.x / 90) - WallSpeedDeAcc) * Time.deltaTime;

if(WallPointReg.x > 0) {
if(transform.position.y >= WallRunOri + WallRunYLimit && Camera.transform.rotation.x < 0) {
PlayerRB.velocity += new Vector3(0, 0, (Camera.transform.TransformDirection(Vector3.forward) * VerticalWall).z);
} else {
PlayerRB.velocity += Camera.transform.TransformDirection(Vector3.forward) * VerticalWall;
Debug.Log(PlayerRB.velocity);
}
}else {
if(transform.position.y >= WallRunOri + WallRunYLimit && Camera.transform.rotation.x < 0) {
PlayerRB.velocity += new Vector3(0, 0, (Camera.transform.TransformDirection(Vector3.forward) * -VerticalWall).z);
} else {
PlayerRB.velocity += Camera.transform.TransformDirection(Vector3.forward) * -VerticalWall;
}
}
}
}

if(CharVel.magnitude < WallRunSpeedMin) {
WallRunning = false;
PlayerRB.constraints = RigidbodyConstraints.FreezeRotationX | RigidbodyConstraints.FreezeRotationZ;
}

if(WallPointReg.x > 0) {
if(WallRunning == false && CamTurn.transform.localRotation.z > 0 && Camera.GetComponent<CamControl>().LookingBack == false) {
CamTurn.transform.transform.Rotate(0, 0, 1.25f * Camera.GetComponent<CamControl>().TurnSpeed * -7.5f * Time.deltaTime, Space.Self);
}
if(WallRunning == false && CamTurn.transform.localRotation.z < 0) {
CamTurn.transform.localRotation = Quaternion.Euler(0, 0, 0);
}
}else {
if(WallRunning == false && CamTurn.transform.localRotation.z < 0 && Camera.GetComponent<CamControl>().LookingBack == false) {
CamTurn.transform.transform.Rotate(0, 0, 1.25f * Camera.GetComponent<CamControl>().TurnSpeed * 7.5f * Time.deltaTime, Space.Self);
}
if(WallRunning == false && CamTurn.transform.localRotation.z > 0) {
CamTurn.transform.localRotation = Quaternion.Euler(0, 0, 0);
}
}
``````

Something like this?

``````// Store length of the vector
float magnitude = v.magnitude;
// Project on yz-plane
v.x = 0;
// Restore previous length
v = v.normalized * magnitude;
``````