Transform.position = new Vector3 is not working when I have charactercontroller.move in the script

Hi, I am experiencing an issue where I change a GameObjects transform.position and then have the command charactercontroller.move on the same GO. But the transform.position doesn’t work consistently. The issue is in a FPS movement script, in a part where I want my player to crouch. I decrease the transform.position.y when left ctrl is pressed, then reset it when the key is released.

The weird thing is that very rarely, either the decrease or increase does work. Since I suspect that other parts of the code are interfering, here is the whole movement script so far:

[Header("Movement")]
public float movementSpeed = 5f;
public float jumpHeight = 5f;
[SerializeField] private bool rawMovementAxis = false;
private float inputX = 0f;
private float inputZ = 0f;
[SerializeField] private float crouchedHeightMultiplier = 0.5f;
[SerializeField] private float crouchedSpeedMultiplier = 0.8f;
private float originalYScale = 1.6f;
  

[Header("Physics")]
public float gravityMultiplier = 1f;
public float maxFallVelocity = 100f;
private float gForce = 9.81f;
private Vector3 playerVelocity;


[Header("Ground Check")]
[SerializeField] private Transform groundCheckPosition;
public float groundCheckRadius;
[SerializeField] private float yVelocityInSphereCheck;
private bool isGrounded = false;

[Header("Headbump Check")]
[SerializeField] private Transform headbumpCheckPosition;
public float headbumpCheckRadius;
private bool isBumpingHead = false;

[SerializeField] private LayerMask groundLayer;
[SerializeField] private CharacterController characterController;

void Start()
{
    originalYScale = transform.localScale.y;
    Debug.Log(originalYScale);
}


void Update()
{
    isGrounded = Physics.CheckSphere(groundCheckPosition.position, groundCheckRadius, groundLayer);
    isBumpingHead = Physics.CheckSphere(headbumpCheckPosition.position, headbumpCheckRadius, groundLayer); // Possible fix: Add layermask for jumpableground

    float gravityAcceleration = gravityMultiplier * -gForce;

    if ((isGrounded && playerVelocity.y < 0) || isBumpingHead)
    {
        playerVelocity.y = -yVelocityInSphereCheck;
    }

    if (Input.GetButtonDown("Jump") && isGrounded)
    {
        playerVelocity.y = Mathf.Sqrt(jumpHeight * -2 * gravityAcceleration);
    }

    if (rawMovementAxis)
    {
        inputX = Input.GetAxisRaw("Horizontal");
        inputZ = Input.GetAxisRaw("Vertical");
    }
    else
    {
        inputX = Input.GetAxis("Horizontal");
        inputZ = Input.GetAxis("Vertical");
    }


    if (Input.GetKeyDown("left ctrl"))
    {
        transform.localScale = new Vector3(transform.localScale.x, originalYScale * crouchedHeightMultiplier, transform.localScale.z);
        transform.position = new Vector3(transform.position.x, transform.position.y - originalYScale * crouchedHeightMultiplier, transform.position.z);

        Debug.Log("y position decrease:" + originalYScale * crouchedHeightMultiplier);
        Debug.Log(originalYScale * crouchedHeightMultiplier);


        movementSpeed *= crouchedSpeedMultiplier;
    }
    if(Input.GetKeyUp("left ctrl"))
    {
        transform.localScale = new Vector3(transform.localScale.x, originalYScale, transform.localScale.z);
        transform.position = new Vector3(transform.position.x, transform.position.y + originalYScale * crouchedHeightMultiplier, transform.position.z);

        movementSpeed /= crouchedSpeedMultiplier;
    }
    

    Vector3 movementDirection = transform.right * inputX + transform.forward * inputZ;

    characterController.Move(movementDirection * movementSpeed * Time.deltaTime); // Removing this and other line with comment fixes crouch part

    if (playerVelocity.y > -maxFallVelocity)
    {
        playerVelocity.y += gravityAcceleration * Time.deltaTime;
    }



    characterController.Move(playerVelocity * Time.deltaTime); // Removing this and other line with comment fixes crouch part

    
    
}

The crouching part of the code does work when I remove BOTH lines I have marked with comments… Something to do with CharacterController.Move

I would recommend implementing crouch a different way. The way I usually do it is by decreasing the y axis of my characters capsule collider and then playing a crouching animation for the visual part.

Lowering the transform.position.y of your character doesn’t really make sense as this will just be pushing your character through the floor, which the physics system or character controller will respond by pushing the characters collider back out. Additionally you shouldn’t really set position of transform if you are using characterController.Move, this is basically just moving your character twice in one frame.