Unity Quaternion.Slerp also changes y position when it should only change x pos

I am making a Beat Saber game.

For the blue saber I used Quaternion.Slerp to rotate it. There are 5 states for the saber:
0. do nothing

  1. cut from down to up
  2. cut from up to down
  3. cut from left to right
  4. cut from right to left

When I used Quaternion.Slerp I only set it to change the x position but when I tested and cut with the saber it also changed the y position.

Here’s the code:

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

public class BlueSaberScript : MonoBehaviour
{
    public bool selected = false;
    public RedSaberScript red;
    public float status = 0; // 0=nothing, 1=down-up, 2=up-down, 3=left-right, 4=right-left
    // Start is called before the first frame update
    void Start()
    {
        
    }

    // Update is called once per frame
    void Update()
    {
        if(Input.GetMouseButtonDown(1))
        {
            selected = true;
            red.Unselect();
        }
        if(status == 0 && selected)
        {
            if(Input.GetKey(KeyCode.UpArrow))
            {
                status = 1;
            }
            else
            {
                if(Input.GetKey(KeyCode.DownArrow))
                {
                    status = 2;
                }
                else
                {
                    if(Input.GetKey(KeyCode.RightArrow))
                    {
                        status = 3;
                    }
                    else
                    {
                        if(Input.GetKey(KeyCode.LeftArrow))
                        {
                            status = 4;
                        }
                    }
                }
            }
        }

//cut animations

        if(selected)
        {
            if(status == 0)
            {
                Quaternion target = Quaternion.Euler(0f, transform.rotation.y, transform.rotation.z);
                transform.rotation = Quaternion.Slerp(transform.rotation, target, Time.deltaTime * 10.0f);
            }
            else
            {
                if(status == 1)
                {

                }
                else
                {
                    if(status == 2)
                    {
                        Quaternion target = Quaternion.Euler(-150.695f, transform.rotation.y, transform.rotation.z);
                        transform.rotation = Quaternion.Slerp(transform.rotation, target, Time.deltaTime * 5.0f);
                        status = 0;
                    }
                    else
                    {
                        if(status == 3)
                        {

                        }
                        else
                        {
                            if(status == 4)
                            {

                            }
                        }
                    }
                }
            }
        }

    }

    public void Unselect()
    {
        selected = false;
    }
}

Is there something wrong?

What I can see is wrong:
Quaternion.Euler(-150.695f, transform.rotation.y, transform.rotation.z)
Transform.rotation is a quaternion, not its euler angles. You are using transform.rotation.y and .z as if they were angles in degrees, but they are quaternion components. Use transform.rotation.eulerAngles.y instead, ideally save the eulerAngles into a local varialbe first if you want to access it twice.

I did that and it doesn’t move the y rotation any more but when I slice down the x rotation stops at around -90.342f instead of -150.695f and when I release the down arrow it slerps at the position when the saber is facing down, from there if you try to slice down again it goes again at around -90.342f then when you release it goes back to the saber facing up. Here is the new code:

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

public class BlueSaberScript : MonoBehaviour
{
    public bool selected = false;
    public RedSaberScript red;
    public float status = 0; // 0=nothing, 1=down-up, 2=up-down, 3=left-right, 4=right-left
    // Start is called before the first frame update
    void Start()
    {
        
    }

    // Update is called once per frame
    void Update()
    {
        if(Input.GetMouseButtonDown(1))
        {
            selected = true;
            red.Unselect();
        }
        if(status == 0 && selected)
        {
            if(Input.GetKey(KeyCode.UpArrow))
            {
                status = 1;
            }
            else
            {
                if(Input.GetKey(KeyCode.DownArrow))
                {
                    status = 2;
                }
                else
                {
                    if(Input.GetKey(KeyCode.RightArrow))
                    {
                        status = 3;
                    }
                    else
                    {
                        if(Input.GetKey(KeyCode.LeftArrow))
                        {
                            status = 4;
                        }
                    }
                }
            }
        }

        float rotationY = transform.rotation.eulerAngles.y;
        float rotationZ = transform.rotation.eulerAngles.z;

        if(selected)
        {
            if(status == 0)
            {
                Quaternion target = Quaternion.Euler(0f, rotationY, rotationZ);
                transform.rotation = Quaternion.Slerp(transform.rotation, target, Time.deltaTime * 10.0f);
            }
            else
            {
                if(status == 1)
                {

                }
                else
                {
                    if(status == 2)
                    {
                        Quaternion target = Quaternion.Euler(-150.695f, rotationY, rotationZ);
                        transform.rotation = Quaternion.Slerp(transform.rotation, target, Time.deltaTime * 5.0f);
                        status = 0;
                    }
                    else
                    {
                        if(status == 3)
                        {

                        }
                        else
                        {
                            if(status == 4)
                            {

                            }
                        }
                    }
                }
            }
        }

    }

    public void Unselect()
    {
        selected = false;
    }
}

The way you are using slerp is just wrong, though I see this usage all the way through different forums, so I can’t blame you. Basically, you are interpolating between two quaternions using deltaTime, which makes no sense, will never reach the target and the duration and speed of the percieved motion will be entirely dependent on the framerate. And since framerate is rarely stable, the motion will be jittery.

Since you are using Quaternion.Slerp, the quaternion finds the shortest path between two rotations, which can be different behaviour from what you expect. I suggest that you try different method instead.

You should keep and interpolate the rotation in euler angles space, individually per component, using Mathf.SmoothDampAngle. This will keep the motion smooth and framerate independent, and the interpolation space being eulers is probably more predictable and perhaps what you actually want.