So, basically I have a jump function being called for a 2D character. In several places I have looked, I am told to call the function in FixedUpdate, but when I do this, my key press for jump only registers around 10% of the time… (Tested as well with a debug Log and sure enough, only registering a tenth of the time I press). but if I move the function to be called from Update, it works flawlessly. However, I am told that calling anything involving physics from the update function can lead to exploits and stability issues and that FixedUpdate is the common place to call functions like that. How can I get this to work?
Not sure of the best way to post my code here, but this is it.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Player : MonoBehaviour
{
[SerializeField]
private float moveForce = 10f;
[SerializeField]
private float jumpForce = 11f;
private float movementX;
private Rigidbody2D myBody;
private SpriteRenderer sr;
private Animator anim;
private string WALK_ANIMATION = “Walk”;
private bool isGrounded;
private string GROUND_TAG = “Ground”;
private void Awake()
{
myBody = GetComponent();
anim = GetComponent();
sr = GetComponent();
}
void Start()
{
}
void Update()
{
PlayerMoveKeyboard();
AnimatePlayer();
}
void FixedUpdate()
{
PlayerJump();
}
void PlayerMoveKeyboard()
{
movementX = Input.GetAxisRaw(“Horizontal”);
transform.position += new Vector3(movementX, 0f, 0f) * Time.deltaTime * moveForce;
}
void AnimatePlayer()
{
if (movementX > 0)
{
anim.SetBool(WALK_ANIMATION, true);
sr.flipX = false;
}
else if (movementX < 0)
{
anim.SetBool(WALK_ANIMATION, true);
sr.flipX = true;
}
else
{
anim.SetBool(WALK_ANIMATION, false);
}
}
void PlayerJump()
{
if(Input.GetButtonDown(“Jump”) && isGrounded)
{
isGrounded = false;
myBody.AddForce(new Vector2(0f, jumpForce), ForceMode2D.Impulse);
Debug.Log(“Jump Button”);
}
}
private void OnCollisionEnter2D(Collision2D collision)
{
if (collision.gameObject.CompareTag(GROUND_TAG))
{
isGrounded = true;
}
}
}
Hey and welcome!
This is worth saving, as it includes the entire Unity execution order:
https://docs.unity3d.com/Manual/ExecutionOrder.html
FixedUpdate is intended for Physics code (only). Putting unnecessary (slow) code there may even lead to exponential slowdown of the entire game, since Unity will try to make sure to call it on a fixed timestep. So the longer it takes, the less time for normal Update calls before the next FixedUpdate call.
Your movement code likely belongs in the FixedUpdate function, if you are working with a rigidbody. However, Input handling should be done in Update. Simply check the important key presses there and remember if it they were true. Then use your own bool, which you update in Update, to control behavior in FixedUpdate.
I already implied this, but FixedUpdate is not called once per frame. It may be called multiple times per frame, or on fast computers only once every couple frames. This is why, if you handle inputs there, you may miss inputs that happened in the frames inbetween.
Hope this helps ![]()
Edit:
Interrestingly according to my notification, this was posted as a reply, thus after my post… but appeared above it with an earlier timestamp. Funny.
Anyways, there are code tags to properly format code. You should directly see them in the edit / reply text window. If anything is unclear there is a sticky post for how to use code tags properly.
Wow, helped me a TON. I am actually glad you didn’t just reply with a change/fix to my code and that you actually explained WHY it was happening. I used to get frustrated at my boss when I was doing 3D CAD because he would try to get me to actually understand things instead of just fixing things for me. haha. But since then I have learned that it doesn’t help as much when you are not actually taught what is happening.
as far as the documentation that you linked, will definitely be referencing that until my brain can quit shutting me out of learning coding and let me absorb things…
Anyway, I added some functionality to be called in Update that checks whether or not the jump button has been pressed or not, and set a Bool to be true in the case that “Jump” is pressed. When true, the jump function (Which now ONLY contains the physics code, and not any input code or any other -slow- code as you called it) is called from FixedUpdate, and it is now hitting every beat!
Thanks a lot!
If you’re doing anything other than applying physics inside FixedUpdate, there is a good chance your code is wrongly placed.
Many of the input functions only return true on the specific frame where the key or button was pressed. Since FixedUpdate can either skip frames, or be called multiple times the same frame, you generally don’t want to capture input inside FixedUpdate. Instead you capture input in Update, set some bools (or otherwise record data regarding input), then do the physics stuff as a response to that input in FixedUpdate.