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.)
using UnityEngine;
using System.Collections;
public class PlayerController : MonoBehaviour
{
public GameObject player;
public float speed;
public float value = 0;
bool isGrounded = false;
void OnCollisionEnter (Collision col)
{
if(col.gameObject.name == "Ground 1")
{
isGrounded = true;
//Debug.Log ("Collision Enter");
}
}
void OnCollisionExit (Collision col)
{
if(col.gameObject.name == "Ground 1")
{
isGrounded = false;
//Debug.Log ("Collision Exit");
}
}
void FixedUpdate ()
{
float moveHorizontal = Input.GetAxis ("Horizontal");
float moveVertical = Input.GetAxis ("Vertical");
//Debug.Log ("Fixed Update");
if(isGrounded == true)
{
if (Input.GetKeyDown (KeyCode.Space))
{value = 9.8f * 3.0f;}
else {value = 0;}
}
else
{
value = 0;
}
//Debug.Log (value);
Vector3 movement = new Vector3 (moveHorizontal, value , moveVertical);
rigidbody.AddForce(movement * speed * Time.deltaTime);
}
}
When I debugged it, this was the process it showed.
"Fixed Update"; value = 0;
"Collision Enter"
"Fixed Update"; value = 29.4; //Attempted to jump
"Fixed Update"; value = 29.4; //This is where I jump twice as high.
"Collision Exit"
"Fixed Update"; value = 0; //In the air
"Collision Enter"
"Fixed Update"; value = 0; //Haven’t tried to jump yet.
"Fixed Update"; value = 29.4; //Jumped Normally
"Collision Exit"
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.
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.
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…
using UnityEngine;
using System.Collections;
public class PlayerController : MonoBehaviour
{
public GameObject player;
public float speed;
public float value = 0;
bool isGrounded = false;
void OnCollisionEnter (Collision col)
{
if(col.gameObject.name == "Ground 1")
{
isGrounded = true;
//Debug.Log ("Collision Enter");
}
}
void OnCollisionExit (Collision col)
{
if(col.gameObject.name == "Ground 1")
{
isGrounded = false;
//Debug.Log ("Collision Exit");
}
}
void Update()
{
float moveHorizontal = Input.GetAxis ("Horizontal");
float moveVertical = Input.GetAxis ("Vertical");
if(isGrounded == true)
{
if (Input.GetKeyDown (KeyCode.Space))
{value = 9.8f * 3.0f;}
else {value = 0;}
}
else
{
value = 0;
}
//Debug.Log ("Update");
//Debug.Log (value);
Vector3 movement = new Vector3 (moveHorizontal, value , moveVertical);
rigidbody.AddForce(movement * speed * Time.deltaTime);
}
}
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?