[Solved] Is Invoke Repeating Frame Independent??

Hello everybody,

im have the same problem since weeks: Getting my player movement frame independent!
I cant do it in Fixed Update because it will move Jittering. Im using a Character Controller. So i create
a custom Method with Invoke Repeating. I think its frame idependend but the problem is that at 1000 fps the player has less gravity then at 60. How is that possible!!! Heres my custum method:

void Awake()
    {
        remainingHealth = Health;
        remainingEnergy = Energy;
        remainingArmor = Armor;
        canJump = true;
        InvokeRepeating("TimedUpdate", 0, 0.1f);
        InvokeRepeating("Move", 0, 0.001f); //Here it is calling my move method every 0.001 seconds.

    }

//Thats my move method wich is called every 0.001 seconds. Everything is time base how can it be that at 200 fps it can jump heigher than at 60. This problem is makeing me crazy!!!

void Move()
    {
        if (!isDrone)
        {
            if (cc.isGrounded && canControl)
            {
                move = new Vector3(Input.GetAxis("Horizontal"), 0, Input.GetAxis("Vertical"));
                move = transform.TransformDirection(move);
                remainingEnergy += energyIncrease;
                move *= walkSpeed;
                movementState = 0;
                movementInfo.text = "Movement state: Standing";
                //if the player is walking or crouching it does not cost any energy

                if (move.x != 0 && move.z != 0)
                {
                    movementState = 1;
                    step = 0.5f;
                    movementInfo.text = "Movement state: Walking";
                }



                if (Input.GetButton("Sprint") && canRun && remainingEnergy > sprintEnergyCost)
                {
                    move *= runSpeed;
                    remainingEnergy -= sprintEnergyCost;
                    movementState = 2;
                    step = 0.3f;
                    movementInfo.text = "Movement state: Sprinting";
                }


                if (Input.GetButtonDown("Jump") && canJump && remainingEnergy > jumpEnergyCost)
                {
                    move.y += jumpSpeed;
                    remainingEnergy -= jumpEnergyCost;
                    movementState = 3;
                    footstepsAudio.clip = Jump;
                    footstepsAudio.Play();
                    movementInfo.text = "Movement state: Jumping";


                }

                if (Input.GetButton("Crouch"))
                {
                    cc.height = 1f;
                    move /= crouchSpeed;
                    movementState = 4;
                    step = 0.8f;
                    canRun = false;
                    movementInfo.text = "Movement state: Crouching";

                }

                else
                {
                    cc.height = 2;
                    canRun = true;
                }

            }
        }
        move.y -= gravity;
        cc.Move(move);

    }

Thanks in advance and please help!!!

Regards,
T

Everything with phyics should be called in the FixedUpdate Function.

void FixedUpdate ()
{
    // Do not calculate anything in FixedUpdate, just execute your Physic 
        Commands
}

In general when you actually update your objects framerate independet (using FixedUpdate or invoke repeating) you will always get slight jitter. That’s because the actual visual frame rate is what you see. When you update the position framerate independent you will sometimes move further or shorter between to visual frames.

Of course the higher the fixed update rate, the less jitter you will get since the smaller the timestep the smaller the offset.

However there are other problems. This line:

move = new Vector3(Input.GetAxis("Horizontal"), 0, Input.GetAxis("Vertical"));

will cancel all the y-velocity. So your gravity will always be at max a “single step”. Gravity is an acceleration and should be accumulated over time. Though the velocity need to be set to 0 when you collide with the ground. Currently you don’t seem to check the CollisionFlags at all.

So the best visual results you get when moving inside Update ans using Time.deltaTime to compensate for different framerates.

Though there’s another problem. Time.deltaTime is a linear factor which can be used to scale linear motion / change. However gravity is an acceperation and therefore results in a quadratic motion. Just using Time.deltaTime on both, the gravity and the “move vector” / velocity won’t yield consistent motion. The error is small but it’s there. One solution is to apply half the velocity before the gravity addition and another half afterwards

If you want realistic gravity you have to perserve the y-velocity and do something like this inside Update:

// your code to setup your "move" variable here
cc.Move(Vector3.up * vVelocity * 0.5f * Time.deltaTime);
cc.Move(move * Time.deltaTime);
vVelocity -= gravity * Time.deltaTime
cc.Move(Vector3.up * vVelocity * 0.5f * Time.deltaTime);

if (cc.isGrounded)
    vVelocity = 0f;

Note that your “move” variable should not contain any “y” movement.

As i said, using FixedUpdate will always cause visual jitter but most accurate movement in relation to time… You can implement your own “fixed update” (the same way Unity has implemented it’s own). I’ve written a small helper class to do this on the wiki CustomFixedUpdate. Though using Update will yield much better results.