Character Controller Jump with FPS problem

I want to make in 2 builds, PC and android, the matters is when i jump, it doesn’t give same visual in different FPS, The laggy is does not the matter (What was i want is if the FPS different it can handle / give same move/arrive and etc, like was in ground, it can give same things in different FPS). the matter are these. I will give the details :


The movement I am Using Character Controller and the movement i set with CharaterController.Move(…), these the code :

    [Header("Refereance")]
    public CharacterController CC;

    [Header("Setting Game")]
    public float Gravity = 0.9f;
    public float VelocityAirMax = 8f;

    [Header("Setting Control")]
    public float JumpPower= 10;
    public float TurnSpeed = 13.33f;
    public float CharacterSpeed = 2f;
    public float CharacterAnimAcceleration = 5.5f;
    public float CharacterAnimDeceleration = 4.5f;

    [Header("Batasan control")]
    public float CharacterSpeedMAX = 3.5f;
    public float FallVeloActInUp = 0.0085f;
    public float FallVeloActInDw = 0.04f;

    private float _velocityAir = 0;

    private Vector3 _targetDirection;
    private float _turnSpeedMultiplier;

    private float _curSpeed = 0f;
    private Quaternion _freeRotation;

    private void Update()
    {
        
        ControlMovement();
        Locomotion();
    }

    private void FixedUpdate()
    {
        if (CC.isGrounded && InputHandle.Jump)
        {
            
            //SetVelocityAir(Mathf.Sqrt(JumpPower * Time.deltaTime));
            //SetVelocityAir(Mathf.Sqrt(JumpPower * Time.fixedDeltaTime));
        }
        if (!CC.isGrounded)
        {
            //SetVelocityAir(_velocityAir - Gravity * (Time.deltaTime));
            //SetVelocityAir(_velocityAir - Gravity * (Time.fixedDeltaTime));
        }

    }

    private void ControlMovement()
    {

        if (InputHandle.Move)
            { 
            if (GetCurSpeed() < CharacterSpeedMAX)
            {
                SetCurSpeed(GetCurSpeed() + Time.deltaTime * CharacterAnimAcceleration);
                if (GetCurSpeed() > CharacterSpeedMAX)
                {
                    SetCurSpeed(CharacterSpeedMAX);
                }
            }
            else if (GetCurSpeed() > CharacterSpeedMAX)
            {
                SetCurSpeed(GetCurSpeed() - Time.deltaTime * CharacterAnimDeceleration);
                if (GetCurSpeed() < CharacterSpeedMAX)
                {
                    SetCurSpeed(CharacterSpeedMAX);
                }
            }
        }
        else
        {
            if (GetCurSpeed() > 0)
            {
                SetCurSpeed(GetCurSpeed() - Time.deltaTime * CharacterAnimDeceleration);
            }
        }
    }

    private void Locomotion()
    {

        if (CC.isGrounded && InputHandle.Jump)
        {
            
            //SetVelocityAir(Mathf.Sqrt(JumpPower * Time.deltaTime));
            //SetVelocityAir(Mathf.Sqrt(JumpPower * Time.fixedDeltaTime));
        }
        if (!CC.isGrounded)
        {
            //SetVelocityAir(_velocityAir - Gravity * (Time.deltaTime));
            //SetVelocityAir(_velocityAir - Gravity * (Time.fixedDeltaTime));
        }

        //Gravitation when grounded keep it falling
        if (CC.isGrounded && _velocityAir < 0 && !InputHandle.Jump)
        {
            SetVelocityAir(0f);
        }

        //when landing need update where the player should move by arrow and camera angle
        if (CC.isGrounded)
        {
            UpdateTargetDirection();
        }

        Vector3 targetDir = Vector3.zero;
        //counting move when any input
        if (_targetDirection.magnitude > 0.1f)
        {
            // set the player's direction
            Vector3 lookDirection = _targetDirection.normalized;
            _freeRotation = Quaternion.LookRotation(lookDirection, CC.transform.up);
            var diferenceRotation = _freeRotation.eulerAngles.y - CC.transform.eulerAngles.y;
            var eulerY = CC.transform.eulerAngles.y;
            if (diferenceRotation < 0 || diferenceRotation > 0)
            {
                eulerY = _freeRotation.eulerAngles.y;
            }
            var euler = new Vector3(0, eulerY, 0);
            CC.transform.rotation = Quaternion.Slerp(CC.transform.rotation, Quaternion.Euler(euler), TurnSpeed * _turnSpeedMultiplier * Time.deltaTime);

            // set the player's Movement
            targetDir = _targetDirection * GetCurSpeed() * CharacterSpeed * Time.deltaTime;
            targetDir = new Vector3(targetDir.x, GetVelocityAir(), targetDir.z);
            CC.Move(targetDir);

        }
        // when velocity still on that area, player will fall dawn or go up

        else if (_velocityAir > FallVeloActInUp || _velocityAir < -FallVeloActInDw)

        {
            targetDir = new Vector3(0f, _velocityAir, 0f);
            CC.Move(targetDir);
        }
    }
    public virtual void UpdateTargetDirection()
    {
        
        _turnSpeedMultiplier = 1f;
        Vector3 forward = Camera.main.transform.TransformDirection(Vector3.forward);

        //get the right-facing direction of the referenceTransform
        Vector3 right = Camera.main.transform.TransformDirection(Vector3.right);

        // determine the direction the player will face based on input and the referenceTransform's right and forward directions
        _targetDirection = InputValueHandle.AxisFinalInput.x * right + InputValueHandle.AxisFinalInput.y * forward;

        if (_targetDirection.magnitude > 1f)
        {
            _targetDirection = Vector3.ClampMagnitude(_targetDirection, 1.0f);
        }
    }

    public void SetVelocityAir(float vel)
    {
        _velocityAir = vel > VelocityAirMax ? VelocityAirMax : vel;
    }

    public float GetVelocityAir()
    {
        return _velocityAir;
    }

    public float GetCurSpeed()
    {
        return _curSpeed;
    }

    public void SetCurSpeed(float curSpeed)
    {
        _curSpeed = curSpeed < 0 ? 0 : curSpeed > CharacterSpeedMAX ? CharacterSpeedMAX : curSpeed;
    }

The Lines what i was tweaks are these :

if (CC.isGrounded && InputHandle.Jump)
        {
            
            //SetVelocityAir(Mathf.Sqrt(JumpPower * Time.deltaTime));
            //SetVelocityAir(Mathf.Sqrt(JumpPower * Time.fixedDeltaTime));
        }
        if (!CC.isGrounded)
        {
            //SetVelocityAir(_velocityAir - Gravity * (Time.deltaTime));
            //SetVelocityAir(_velocityAir - Gravity * (Time.fixedDeltaTime));
        }

these in Update and FixedUpdate(i just use one of them, both not active in same time, i comment one of them when i want to try) i already tweek the Time, but still can figure it out.


After try and try the thing that make different is this :

if (!CC.isGrounded)
{
         //SetVelocityAir(_velocityAir - Gravity * (Time.deltaTime));
         //SetVelocityAir(_velocityAir - Gravity * (Time.fixedDeltaTime));
}

In these line, when i use deltaTime in update, it got wrong height(more low fps more low height can achive and vice versa) but give same floating time in different FPS, but when i use Fixed time, it give true height but give wrong floating time(more low fps more long to floating and vice versa).


When i do in fixed update, it just wrong to use that 2, when low fps, it get low height when jump. may be we i should do in here, but i clueless for it.


That it’s, thanks for for your help, i Appreciate,.

its fixed by me, can giving same pos in different fps, the height max of jump, speed and arrive pos.
it’s someone have this problem, try to use 2 curve (when up and down) and use Limit( far up use the heightMax of jump, and for down use time and gravitation), and must multiple it by Time.deltaTime.