Search Unity

[SOLVED]Unity Move() with FixedUpdate more efficient ?

Discussion in 'Scripting' started by Craze74, Feb 19, 2016.

  1. Craze74

    Craze74

    Joined:
    Nov 19, 2012
    Posts:
    83
    Hello guys,

    I have been playing with characterController which is something new to me, and I noticed that as long as I am keeping my code into the void update(), sometimes my actions ( like jumping ) will just be missing, like if no buttons were pressed at all.

    I tried to use the fixedUpdate() instead, and it all seems to work fine.
    So here is what I don't understand : I searched online and saw that fixedUpdate() is actually used when dealing with rigidBody and physics, but at the same times, it seems there are people who are making everything working ( with characterController and Move() ) inside the update() without problems. The posts seemed from 4 years ago so maybe it changed, but I would like to understand what's going on and what is clearly specified to use fixedUpdate or Update depending on the situation ?

    Here is my code just in case :

    Code (CSharp):
    1. using UnityEngine;
    2. using System.Collections;
    3.  
    4. public class player : MonoBehaviour {
    5.  
    6.     // player speed
    7.     public float fPlayerSpeed = 14.0f;
    8.     public float moveSpeedSmooth = 0.3f;
    9.     public float jumpSpeed = 11;
    10.     public float gravity = 18.0f;
    11.  
    12.     float currentForwardSpeedX;
    13.     float currentForwardSpeedZ;
    14.     float forwardSpeedV;
    15.     float forwardSpeedV2;
    16.  
    17.  
    18.     CharacterController controller;
    19.     Vector3 currentMovement;
    20.  
    21.  
    22.     // Use this for initialization
    23.     void Start () {
    24.  
    25.         //Player Spawn Point
    26.         //This is where our player will start when the game is played
    27.         //player == game object, game object == transform
    28.         this.transform.position = new Vector3(0, 3, -1);
    29.  
    30.         controller = GetComponent<CharacterController>();
    31.     }
    32.  
    33.     // Update is called once per frame
    34.     void Update () {
    35.         //player to move up right and down
    36.         //player transform to move when arrow key pressed
    37.         //OLD
    38.         //this.transform.Translate(Vector3.right * Input.GetAxis("Horizontal")* fPlayerSpeed*Time.deltaTime);
    39.         //this.transform.Translate(Vector3.forward * Input.GetAxis("Vertical")* fPlayerSpeed*Time.deltaTime);
    40.         //OLD
    41.  
    42.  
    43.  
    44.         currentForwardSpeedZ = Mathf.SmoothDamp(currentForwardSpeedZ, Input.GetAxisRaw("Vertical") * fPlayerSpeed, ref forwardSpeedV, moveSpeedSmooth );
    45.         currentForwardSpeedX = Mathf.SmoothDamp(currentForwardSpeedX, Input.GetAxisRaw("Horizontal") * fPlayerSpeed, ref forwardSpeedV2, moveSpeedSmooth );
    46.  
    47.         currentMovement = new Vector3(currentForwardSpeedX, currentMovement.y, currentForwardSpeedZ);
    48.  
    49.  
    50.  
    51.  
    52.  
    53.         if (!controller.isGrounded)
    54.             currentMovement -= new Vector3(0, gravity * Time.deltaTime, 0);
    55.         else
    56.             currentMovement.y = 0;
    57.  
    58.         if (controller.isGrounded && Input.GetButtonDown("Jump"))
    59.             currentMovement.y = jumpSpeed;
    60.         controller.Move(currentMovement * Time.deltaTime);
    61.  
    62.     }
    63.  
    64.  
    65.  
    66. }
    67.  

    Cheers and have an awesome day !
     
  2. LeftyRighty

    LeftyRighty

    Joined:
    Nov 2, 2012
    Posts:
    5,148
    the whole point of the characterController provided in unity is that it is a way of constraining a moving object with collisions without using a rigidbody, you shouldn't need to be using FixedUpdate. In fact, assuming your attempt to use fixedupdate is the above code with just the function name changed, using FixedUpdate and Input can result in missed Input calls because of FixedUpdate not being called every frame so brief inputs can be missed.
     
  3. Laperen

    Laperen

    Joined:
    Feb 1, 2016
    Posts:
    1,065
    FixedUpdate runs at fixed time intervals, referred to as fixed-time-step found in edit>project settings>time. This is useful for physics since physics updates using the same fixed-time-step as well.

    Update runs every frame. This is useful for player input for its immediacy.

    Not sure how to give a concise list on when to use what since it depends on the situation, but in general you weigh between immediacy and consistency.
     
  4. Craze74

    Craze74

    Joined:
    Nov 19, 2012
    Posts:
    83
    Alright I see, Thanks for the explanation !

    So because Update() is called every frame no exception, is there anything that can cause the input missed calls here ?
    I assume this is something dealing with the isGrounded method, and not the update() then !
     
  5. Laperen

    Laperen

    Joined:
    Feb 1, 2016
    Posts:
    1,065
    Missed input calls happen i n this situation when you place input in Fixed update, since the time of a frame is not necessarily the time of the fixed-time-step. So if your jump input is in FixedUpdate, and you press the jump key while the fixed-time-step is somewhere in the middle, FixedUpdate is not called while you pressed the key and your input will be missed.

    And after looking at your script again, this is a different issue. For a CharacterController's OnGround to work properly, applying your gravity all the time is a must. It's some weird quirk of the CharacterController's .onGround.

    And also while the above change will solve this problem, i will still mention it. You are resetting your y position to 0 as long as the CharacterController is grounded. This is a bad idea. With your current script, just raise your floor 1 unit up and you will fall through the floor the moment you land on the floor.
     
    Last edited: Feb 19, 2016
    Craze74 likes this.
  6. BluHornet

    BluHornet

    Joined:
    Feb 23, 2015
    Posts:
    40
    I use update to capture input and fixed update to apply them. Using fixed can reduce the tasking each frame and increase frame rate. Though this is only significant in big games
     
  7. Craze74

    Craze74

    Joined:
    Nov 19, 2012
    Posts:
    83

    I Will try that thanks ! Applying gravity all the time isnt going to take unecessary ressources ? Whereas Applying it only when we need it Will save some memory ?

    Cheers guys
     
  8. Laperen

    Laperen

    Joined:
    Feb 1, 2016
    Posts:
    1,065
    Far more resources will be used on .Move, so the applied gravity before that is negligible. And even assuming not applying gravity while you were on the ground saves you a ton of memory, it makes the game unplayable anyway, so the resource usage on gravity is not a choice but a necessity.
     
  9. Craze74

    Craze74

    Joined:
    Nov 19, 2012
    Posts:
    83
    Alright !

    Thanks for the answers guys, looks more clear now :)

    Cheers
     
  10. hippocoder

    hippocoder

    Digital Ape

    Joined:
    Apr 11, 2010
    Posts:
    29,723
    Character controller operates independently of FixedUpdate - you don't need to do it there *unless* you have colliders which move, because CC is based on raycasts, and raycasts return a result the moment they're called.

    By contrast though, the geometry the raycasts test against, are only refreshed after FixedUpdate has run, so if you have a moving block with a collider, the raycast may be slightly inaccurate in this situation.
     
  11. MrG

    MrG

    Joined:
    Oct 6, 2012
    Posts:
    368
    Can you provide a source for this? I've read that CC is a wrapper for PhysX engine's C++ controller under the hood, which might lead one to think FixedUpdate would be appropriate for .Move even if the inputs were recorded in Update().

    Yeah, this is a bit of thread necromancy, but it's one of the more recent posts on this subject.
     
    Last edited: Oct 20, 2018
    AlejMC likes this.
  12. hippocoder

    hippocoder

    Digital Ape

    Joined:
    Apr 11, 2010
    Posts:
    29,723
    I don't have time to look for particular posts for you but I've done it for years, spoken to staff about it, It's raycast based, therefore there is no requirement at all to be in fixed update. Rays hit colliders. Colliders *only* update their positions when simulate is called at the rate of fixed update.

    So the same applies to Physx as well, in C++ land. Since raycasts have nothing at all to do with simulations and are just querying the same state.

    If you move a collider your raycasts will act on where the collider was, until the simulate step updates. This still has nothing to with character controller (unless you're moving colliders themselves, and my previous post did mention this clearly).

    You can test this in 5 mins with your own code.

    Even the Unity docs state it's not physics driven.
     
    mikeohc and MrG like this.
  13. hippocoder

    hippocoder

    Digital Ape

    Joined:
    Apr 11, 2010
    Posts:
    29,723
    DSivtsov and MrG like this.
  14. Slater7

    Slater7

    Joined:
    Oct 10, 2018
    Posts:
    11
    I know this thread is old, but I ask anyway.
    As far as I understand it, I can freely use a character controller and put all my movement logic in update() with time.deltaTime without caring about performance issues?
     
  15. PraetorBlue

    PraetorBlue

    Joined:
    Dec 13, 2012
    Posts:
    7,914
    That's the intended way to use CharacterController, yes.
     
    AlejMC likes this.
  16. Slater7

    Slater7

    Joined:
    Oct 10, 2018
    Posts:
    11
    Ah thanks, always thought I have to seperate the input logic in Update() and the movement logic in fixedUpdate()
     
  17. Yoreki

    Yoreki

    Joined:
    Apr 10, 2019
    Posts:
    2,605
    This is somewhat true - but only if you move using physics. As a rule of thumb, physics go into FixedUpdate, do your best to keep everything else out of it due to performance reasons.
    Oftentimes people in these cases put their input checks into FixedUpdate as well, and get told to separate it such that the input checks are in Update. You probably got confused by that :)
     
    Slater7 likes this.
  18. Slater7

    Slater7

    Joined:
    Oct 10, 2018
    Posts:
    11
    Thanks for the clarification :)