My Turn Around method doesn't work in full screen mode

I’m trying to replicate Silent Hill movement, and I have a functional “TurnAround” Coroutine that I’m calling if the player isGrounded.

Here’s my movement:

private void CalculateMovement()
    {
         vertical = Input.GetAxis("Vertical");
         horizontal = Input.GetAxis("Horizontal");

        Vector3 direction = new Vector3(0f, 0f, vertical);

        Vector3 movement = transform.TransformDirection(direction) * _moveSpeed;

        transform.Rotate(0f, horizontal * _turnSpeed * Time.deltaTime, 0f);
        isGrounded = _characterController.SimpleMove(movement);
    }

and here’s were I’m calling it:

private void Update()
    {
        CalculateMovement();

        if (Input.GetKey(KeyCode.LeftShift) && vertical > 0)
        {
            if (_rotation != null)
            {
                StopCoroutine(_rotation);
                _rotation = null;
            }
            Sprint();
        }

        else if (Input.GetKeyDown(KeyCode.Tab) && isGrounded)
        {
            _targetRotation = Quaternion.Euler(0, 180, 0) * transform.rotation;

            if(_rotation == null)
            {
                _rotation = StartCoroutine(RotateToTargetOvertTime());
            }      
        }
    }

I’m noticing when in the Inspector that my public bool isGrounded keeps flickering. It doesn’t keep me from rotating in small screen mode, but when I enter full screen mode I can’t hardly rotate at all except randomly.

What is it I’m missing?

I’m guessing that the issue has to do with calling something physics-based (moving a controller, checking for a collision with the ground) while in Update() * - if the game frames and physics frames don’t line up exactly right you can get inconsistent behavior. If that guess is accurate then the reason you’re seeing different behavior between fullscreen and windowed is because there’ll be different framerates.

*I know the documentation has that in the example, I suspect the documentation is wrong. It doesn’t make any sense for anything that collides to run in Update, and to check for being grounded, it has to do that.

You may be able to compensate by giving yourself some leeway, and setting a “timer”:

private float lastGroundedAt = -1f;

void Update() {
....
    if (_characterController.SimpleMove(movement) ) {
        lastGroundedAt = Time.time;
    }
    isGrounded = lastGroundedAt < Time.time + 0.05f;
}

This will make isgrounded true for a solid 0.05 seconds after it has been grounded, so it will at least be more consistent.

I thought you didn’t need to use FixedUpdate unless using RigidBody physics, or is that wrong? Would it be more efficient to just check if I’m touching Ground through OnTriggerEnter and change the bool that way?

Checking the CharacterController for isGrounded is a long time issue. Here’s a nearly decade spanning thread on the topic.

https://discussions.unity.com/t/446468

There’s several people throwing out solutions of likely varying quality… but this one seems rather interesting:

So what would be an efficient way to check if the player is grounded so I can prevent midair turning and other things?

In case anybody is reading this in the future, I might have solved my issue by replacing:

else if (Input.GetKeyDown(KeyCode.Tab) && isGrounded) .

with:

 raycastGrounded = Physics.Raycast(transform.position, Vector3.down, 1f);

else if (Input.GetKeyDown(KeyCode.Tab) && raycastGrounded) etc.

and it seems to be working so far. Not sure if this is efficient or not but it’s what I came up with.