- Home /
 
'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);
                 }
             }
 
 
              Answer by BastianUrbach · Jun 05, 2019 at 08:56 AM
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;
 
              Your answer
 
             Follow this Question
Related Questions
Velocity Relative to Rotation 1 Answer
relative velocity of rigidbody according to rotation... 1 Answer
Relative Rotation 1 Answer
How to set velocity to new direction after rotation? 0 Answers
Change a property based on angle? 1 Answer