Player decides to nap facedown when Idle

Hi there. I’ve gotten the player to be able to move in the direction of the camera as well as face their direction while moving (mostly). My placeholder mixamo animations are janky but thats a whole other issue. What im most confused by is that the player will be laying face down whenever they’re idle. It only seems to happen then, as every other time they are facing the correct direction. They always snap back to the same direction whenever input has stopped. I will attach the code and a link to a video. I may be blind, but where does this issue seem to be occuring?

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


public class PlayerControls : MonoBehaviour
{
    //References   
    CharacterController controller;
    public GameObject model;
    Animator anim;


    //Vars   
    public float moveSpeed;   
    public float jumpForce;
    public float gravityScale;
    public float rotateSpeed;

    private Vector3 moveDirection;

    public Transform lookTarget;
    Transform cameraTransform;

    //Input Vars
    float horizontal;
    float vertical;
    float mouseY;
    float mouseX;

    bool runInput;
    bool jumpInput;
    bool aimInput;

    //Animation Vars
    bool movementPressed;
    bool isJogging;
    bool isRunning;   
          
    void Awake()
    {
        controller = GetComponent<CharacterController>();
        cameraTransform = Camera.main.transform;
        anim = model.GetComponent<Animator>();
        movementPressed = false;
    }
   
    void Update()
    {
        movementPressed = horizontal != 0 || vertical != 0;
        isJogging = anim.GetBool("isJogging");
        isRunning = anim.GetBool("isRunning");
        HandleMovement();
        HandleAnimation();
    }
   
    public void OnMoveInput(float vertical, float horizontal)
    {
        this.horizontal = horizontal;
        this.vertical = vertical;       
       
    }

    public void OnRunInput(bool runInput)
    {
        this.runInput = runInput;

    }

    public void OnJumpInput(bool jumpInput)
    {
        this.jumpInput = jumpInput;

    } 

    public void OnAimInput(bool aimInput)
    {
        this.aimInput = aimInput;
        

    }

    public void HandleMovement()
    {       
        //Calculate Move Direction
        var yStore = moveDirection.y;
       
        moveDirection = (Vector3.forward * vertical) + (Vector3.right * horizontal);       

        moveDirection.y = yStore;

        //Get projected camera forward to rotate movespeed to direction of movement
        Vector3 projectedCameraForward = Vector3.ProjectOnPlane(cameraTransform.forward, Vector3.up);
        Quaternion rotateToCamera = Quaternion.LookRotation(projectedCameraForward, Vector3.up);
        moveDirection = rotateToCamera * moveDirection;

        if (moveDirection != Vector3.zero && controller.isGrounded)
        {

            model.transform.rotation = Quaternion.LookRotation(moveDirection);
        }


        //HandleJump
        if (controller.isGrounded)
        {
            moveDirection.y = 0f;
            if (jumpInput)
            {
                moveDirection.y = jumpForce;
            }
        }

      
        //Gravity
        moveDirection.y = moveDirection.y + (Physics.gravity.y * gravityScale* Time.deltaTime);

        //Move in Direction of MoveDirection
        controller.Move(moveDirection * Time.deltaTime * moveSpeed);
    }

    public void HandleAnimation()
    {
        //Jogging
        if (movementPressed && !isJogging)
        {
            anim.SetBool("isJogging", true);
        }
        else if (!movementPressed && isJogging)
        {
            anim.SetBool("isJogging", false);
        }
        //Jumping
        if(jumpInput)
        {
            anim.SetTrigger("jump");
        }
        if(!jumpInput && !controller.isGrounded)
        {
            anim.SetTrigger("fall");
        }
    }

}

My first theory is this happens because lines 94 to 96 continue to operate even when moveDirection is zero, which technically results in undefined facing (how do you face in the direction of Vector3.zero?).

You should prevent this code from running unless moveDirection.magnitude is above a certain amount, such as perhaps 0.05f or something.

OK so that line series of lines now appears as

 if (moveDirection.magnitude > .05f)
        {
            //Get projected camera forward to rotate movespeed to direction of movement
            Vector3 projectedCameraForward = Vector3.ProjectOnPlane(cameraTransform.forward, Vector3.up);
            Quaternion rotateToCamera = Quaternion.LookRotation(projectedCameraForward, Vector3.up);
            moveDirection = rotateToCamera * moveDirection;
}

I have also tried to do this to be safe

  if (moveDirection.magnitude > .05f)
        {
            //Get projected camera forward to rotate movespeed to direction of movement
            Vector3 projectedCameraForward = Vector3.ProjectOnPlane(cameraTransform.forward, Vector3.up);
            Quaternion rotateToCamera = Quaternion.LookRotation(projectedCameraForward, Vector3.up);
            moveDirection = rotateToCamera * moveDirection;


            if (moveDirection != Vector3.zero && controller.isGrounded)
            {

                model.transform.rotation = Quaternion.LookRotation(moveDirection);
            }
        }

Sadly both have no affect so far on the idle position

Next thing is to study the scene: is the transform lying down? Or is the animation driving it to appear that way?

Just standard “what do I check next?” debugging… keep after it, do not stop until it works.

Also, what’s up with the feet? Are you using some sort of IK already? If the answer is yes, it easily can be your source of problem.

Ok good news! No IK btw just a really, really poorly imported animation I can fix now that this is done. I think the issue was caused due to the yStore value used to store the ydirection movement. Seems just setting moveDirection.y to 0f and waiting a little longer to restore the ystore fixed it. I also put in a check so that the player direction wont change based on no movement, stopping player from snapping back to the original direction after letting go of the button

public void HandleMovement()
    {
        if (horizontal != 0 || vertical != 0)
        {
            //transform.eulerAngles = new Vector3(transform.rotation.x, 0f, 0f);
            //Calculate Move Direction
            var yStore = moveDirection.y;

            moveDirection = (Vector3.forward * vertical) + (Vector3.right * horizontal);
            moveDirection.y = 0f;




            if (moveDirection.magnitude > .05f)
            {
                //Get projected camera forward to rotate movespeed to direction of movement
                Vector3 projectedCameraForward = Vector3.ProjectOnPlane(cameraTransform.forward, Vector3.up);
                Quaternion rotateToCamera = Quaternion.LookRotation(projectedCameraForward, Vector3.up);
                moveDirection = rotateToCamera * moveDirection;

            }

            model.transform.rotation = Quaternion.LookRotation(moveDirection, Vector3.up);


            moveDirection.y = yStore;
            //HandleJump
            if (controller.isGrounded)
            {
                moveDirection.y = 0f;
                if (jumpInput)
                {
                    moveDirection.y = jumpForce;
                }
            }


            //Gravity
            moveDirection.y = moveDirection.y + (Physics.gravity.y * gravityScale * Time.deltaTime);

            //Move in Direction of MoveDirection
            controller.Move(moveDirection * Time.deltaTime * moveSpeed);
        }
    }