protected void HandleDynamicMovement()
        {
            if (GameState.Instance.PlayerFlags.Contains(PlayerFlags.NoPhysics)) //probably buggy
            {
                return;
            }

            float lastYVelocity = Velocity.y; //last y-velocity, ignoring gravity

            Velocity += Physics.gravity * GravityMultiplier * Time.deltaTime;

            CharController.Move(Velocity * Time.deltaTime);

            IsGrounded = CharController.isGrounded;
            IsOnSlope  = Vector3.Angle(Vector3.up, LastGroundNormal) > CharController.slopeLimit;

            if (IsGrounded && !DidJump)
            {
                //float yDamp = GroundedDamping * Time.deltaTime;
                //yDamp = Mathf.Min(yDamp, Mathf.Abs(Velocity.y));
                //yDamp = yDamp * -Mathf.Sign(Velocity.y);
                //Velocity += new Vector3(0, yDamp, 0);

                if (lastYVelocity < -FallMinDetectVelocity && TimeInAir > FallMinDetectTime)
                {
                    FallImpactSound.Ref()?.Play();

                    if (lastYVelocity < -FallMinGruntVelocity)
                    {
                        FallPainSound.Ref()?.Play();
                    }

                    if (GameParams.UseFallDamage && !MetaState.Instance.SessionFlags.Contains("GodMode") && !GameState.Instance.PlayerFlags.Contains(PlayerFlags.NoFallDamage) && !GameState.Instance.PlayerFlags.Contains(PlayerFlags.Invulnerable))
                    {
                        GameState.Instance.PlayerRpgState.Health -= RpgValues.FallDamage(GameState.Instance.PlayerRpgState, new Vector3(Velocity.x, lastYVelocity, Velocity.z));
                    }

                    //Debug.Log($"Player fell (y-velocity = {lastYVelocity:F4} m/s, time in air = {TimeInAir:F2} s)");
                }

                Velocity  = new Vector3(Velocity.x, 0, Velocity.z);
                TimeInAir = 0;
            }

            if (IsGrounded && IsOnSlope)
            {
                //Debug.Log("on slope");
                //slope slide
                Vector3 slopeDir         = new Vector3(LastGroundNormal.x, 1f - LastGroundNormal.y, LastGroundNormal.z).normalized;
                Vector3 slopeVelocityAdd = new Vector3(slopeDir.x, 0, slopeDir.z) * SlopeSlideAccleration * Time.deltaTime;
                Vector3 flatVelocity     = new Vector3(Velocity.x, 0, Velocity.z);
                slopeVelocityAdd = slopeVelocityAdd.normalized * Mathf.Min(slopeVelocityAdd.magnitude, Mathf.Max(0, SlopeSlideSpeed - flatVelocity.magnitude));
                Velocity        += slopeVelocityAdd;
            }
            else if (IsGrounded && !IsMoving)
            {
                //ground friction
                Velocity += new Vector3(-Velocity.x, 0, -Velocity.z).normalized *GroundFriction *Time.deltaTime;
            }
            else
            {
                //air resistance
                Velocity  += (-Velocity).normalized * Mathf.Min(AirResistance * Time.deltaTime, Velocity.magnitude);
                TimeInAir += Time.deltaTime;
            }
        }