Search Unity

  1. Megacity Metro Demo now available. Download now.
    Dismiss Notice
  2. Unity support for visionOS is now available. Learn more in our blog post.
    Dismiss Notice

Cycling through FixedUpdate() twice, before exiting the first collision.

Discussion in 'Scripting' started by Brandon-Keeler, Oct 31, 2014.

  1. Brandon-Keeler

    Brandon-Keeler

    Joined:
    Oct 27, 2014
    Posts:
    75
    If I wait a few seconds after my game starts, everything works fine, but If I try to jump immediately at the start of my program, I jump twice as high than I am supposed to. (Only one time.)

    Code (CSharp):
    1. using UnityEngine;
    2. using System.Collections;
    3. public class PlayerController : MonoBehaviour
    4. {
    5.     public GameObject player;
    6.     public float speed;
    7.     public float value = 0;
    8.     bool isGrounded = false;
    9.  
    10.     void OnCollisionEnter (Collision col)
    11.     {
    12.         if(col.gameObject.name == "Ground 1")
    13.         {
    14.             isGrounded = true;
    15.             //Debug.Log ("Collision Enter");
    16.         }
    17.     }
    18.  
    19.     void OnCollisionExit (Collision col)
    20.     {
    21.         if(col.gameObject.name == "Ground 1")
    22.         {
    23.             isGrounded = false;
    24.             //Debug.Log ("Collision Exit");
    25.         }
    26.     }
    27.  
    28.     void FixedUpdate ()
    29.     {
    30.         float moveHorizontal = Input.GetAxis ("Horizontal");
    31.         float moveVertical = Input.GetAxis ("Vertical");
    32.         //Debug.Log ("Fixed Update");
    33.         if(isGrounded == true)
    34.         {
    35.             if (Input.GetKeyDown (KeyCode.Space))
    36.             {value = 9.8f * 3.0f;}
    37.             else {value = 0;}
    38.         }
    39.         else
    40.         {
    41.             value = 0;
    42.         }
    43.         //Debug.Log (value);
    44.  
    45.         Vector3 movement = new Vector3 (moveHorizontal, value , moveVertical);
    46.         rigidbody.AddForce(movement * speed * Time.deltaTime);
    47.     }
    48. }
    When I debugged it, this was the process it showed.
    Code (CSharp):
    1. "Fixed Update"; value = 0;
    2.  
    3. "Collision Enter"
    4. "Fixed Update"; value = 29.4; //Attempted to jump
    5. "Fixed Update"; value = 29.4; //This is where I jump twice as high.
    6. "Collision Exit"
    7.  
    8. "Fixed Update"; value = 0; //In the air
    9.  
    10. "Collision Enter"
    11. "Fixed Update"; value = 0; //Haven’t tried to jump yet.
    12. "Fixed Update"; value = 29.4; //Jumped Normally
    13. "Collision Exit"
     
    Last edited: Oct 31, 2014
  2. Brandon-Keeler

    Brandon-Keeler

    Joined:
    Oct 27, 2014
    Posts:
    75
    Can someone tell my why my code isn't exiting the first collision immediately, and what process I can go about to resolve this bug?
     
  3. Baste

    Baste

    Joined:
    Jan 24, 2013
    Posts:
    6,294
    So, the issue is that FixedUpdate can run a bunch of times for every Update .

    The Input.GetKeyDown method clears after every Update cycle. This means that you shouldn't use it outside of Update. If you use it in FixedUpdate as you do here, your game reads several jump inputs for every keypress.

    Simply change your FixedUpdate into Update, that'll fix the bug.
     
  4. Brandon-Keeler

    Brandon-Keeler

    Joined:
    Oct 27, 2014
    Posts:
    75
    I tried your advice and it didn't work (same bug)... again its only on the first jump.
    Code (CSharp):
    1. using UnityEngine;
    2. using System.Collections;
    3. public class PlayerController : MonoBehaviour
    4. {
    5.     public GameObject player;
    6.     public float speed;
    7.     public float value = 0;
    8.     bool isGrounded = false;
    9.  
    10.  
    11.     void OnCollisionEnter (Collision col)
    12.     {
    13.         if(col.gameObject.name == "Ground 1")
    14.         {
    15.             isGrounded = true;
    16.             //Debug.Log ("Collision Enter");
    17.         }
    18.     }
    19.    
    20.     void OnCollisionExit (Collision col)
    21.     {
    22.         if(col.gameObject.name == "Ground 1")
    23.         {
    24.             isGrounded = false;
    25.             //Debug.Log ("Collision Exit");
    26.         }
    27.     }
    28.  
    29.     void Update()
    30.     {
    31.         if(isGrounded == true)
    32.         {
    33.             if (Input.GetKeyDown (KeyCode.Space))
    34.             {value = 9.8f * 3.0f;}
    35.             else {value = 0;}
    36.         }
    37.         else
    38.         {
    39.             value = 0;
    40.         }
    41.     }
    42.  
    43.     void FixedUpdate ()
    44.     {
    45.         float moveHorizontal = Input.GetAxis ("Horizontal");
    46.         float moveVertical = Input.GetAxis ("Vertical");
    47.         //Debug.Log ("Fixed Update");
    48.         //Debug.Log (value);
    49.  
    50.         Vector3 movement = new Vector3 (moveHorizontal, value , moveVertical);
    51.         rigidbody.AddForce(movement * speed * Time.deltaTime);
    52.     }
    53. }
    54.  
     
  5. Dantus

    Dantus

    Joined:
    Oct 21, 2009
    Posts:
    5,667
    After you have applied the force in fixed update, you need to set value to 0!
     
  6. GarthSmith

    GarthSmith

    Joined:
    Apr 26, 2012
    Posts:
    1,240
    The FixedUpdate() cycle and the Update() cycle are not tied together. This means that you can have FixedUpdate() run multiple times per Update(), or even not at all.

    So you set your value in Update(), and then two FixedUpdate()s run before value is updated in the next Update(). So you end up AddForce()ing twice.

    For things like a one time AddForce() you can do that in Update() as well. FixedUpdate() is really meant for times when you will be AddForce()ing over numerous frames.

    Short Version: Update() and FixedUpdate() cycles are not synced together at all.
     
  7. Brandon-Keeler

    Brandon-Keeler

    Joined:
    Oct 27, 2014
    Posts:
    75
    Ok, so i tried using only update, and it really bugged out my program. When I try to jump in the air at the start of the game I go super high. Also my character no longer rests along the surface of my plane and ends up going 0.02 into it...

    Code (CSharp):
    1. using UnityEngine;
    2. using System.Collections;
    3. public class PlayerController : MonoBehaviour
    4. {
    5.     public GameObject player;
    6.     public float speed;
    7.     public float value = 0;
    8.     bool isGrounded = false;
    9.  
    10.  
    11.     void OnCollisionEnter (Collision col)
    12.     {
    13.         if(col.gameObject.name == "Ground 1")
    14.         {
    15.             isGrounded = true;
    16.             //Debug.Log ("Collision Enter");
    17.         }
    18.     }
    19.  
    20.     void OnCollisionExit (Collision col)
    21.     {
    22.         if(col.gameObject.name == "Ground 1")
    23.         {
    24.             isGrounded = false;
    25.             //Debug.Log ("Collision Exit");
    26.         }
    27.     }
    28.  
    29.     void Update()
    30.     {
    31.         float moveHorizontal = Input.GetAxis ("Horizontal");
    32.         float moveVertical = Input.GetAxis ("Vertical");
    33.         if(isGrounded == true)
    34.         {
    35.             if (Input.GetKeyDown (KeyCode.Space))
    36.             {value = 9.8f * 3.0f;}
    37.             else {value = 0;}
    38.         }
    39.         else
    40.         {
    41.             value = 0;
    42.         }
    43.         //Debug.Log ("Update");
    44.         //Debug.Log (value);
    45.         Vector3 movement = new Vector3 (moveHorizontal, value , moveVertical);
    46.         rigidbody.AddForce(movement * speed * Time.deltaTime);
    47.     }
    48. }
     
    Last edited: Nov 1, 2014
  8. Brandon-Keeler

    Brandon-Keeler

    Joined:
    Oct 27, 2014
    Posts:
    75
    FixedUpdate function seems to work better. I think the problem is that its stalling too much when I start the program, and not properly exiting the collision. Is there anything else I can try?