Hi guys,
i am making a small shooter with BulletML and using coroutines for player firing and stoping fire (enabling and reenabling the BulletML script)
public class Shoot : MonoBehaviour {
void Awake()
{
BulletSourceScript bulletsourcescript = GetComponent<BulletSourceScript>();
bulletsourcescript.enabled = false;
}
void FixedUpdate()
{
if (Input.GetKeyDown ("space"))
StartCoroutine (Fire ());
else if (Input.GetKeyUp ("space"))
StartCoroutine (StopFire ());
}
IEnumerator Fire ()
{
yield return new WaitForFixedUpdate();
BulletSourceScript bulletsourcescript = GetComponent<BulletSourceScript>();
bulletsourcescript.enabled = true;
}
IEnumerator StopFire ()
{
yield return new WaitForFixedUpdate();
BulletSourceScript bulletsourcescript = GetComponent<BulletSourceScript>();
bulletsourcescript.enabled = false;
}
}
It is a simple script, but i am running into a problem. Sometimes the GetKeyUp doesnât get detected, and i actually can press only two buttons at the time, is there a solution for this to work flawlessly?
Movement script is simple
using UnityEngine;
public class PlayerScript : MonoBehaviour
{
public Vector2 speed = new Vector2(50, 50);
private Vector2 movement;
void Update()
{
float inputX = Input.GetAxis("Horizontal");
float inputY = Input.GetAxis("Vertical");
movement = new Vector2(
speed.x * inputX,
speed.y * inputY);
}
void FixedUpdate()
{
rigidbody2D.velocity = movement;
}
}
FixedUpdate and Input donât play nicely.
This is because every update unity starts out with determing how much time has passed since last update. From this it determines how many ticks of the physics engine should have occurred during that time. Becuase physics calculates at a fixed rate. Usually this is 50 times per second⌠so if the amount of time that passed is 22ms, than it ticks physics (calls FixedUpdate) once (and carry over 2ms to next update). If it were 44ms, then it would call it twice (and carry over 4ms to next update). BUT if it were like 10ms, then physics isnât ticked at all, and instead thatâll carry over to the NEXT update where that 10ms will be combined with that amount of change in time, to determine the fixed number again.
Thing is if the frame that the key was released happens to ALSO be the frame that no physics ticks are called. Well then âFixedUpdateâ doesnât receive that information. Since the âKeyUpâ and âKeyDownâ last only a single frame.
Itâs suggested you donât have Input testing in FixedUpdate⌠but honestly, sometimes you canât avoid it.
So personally I handle my own âUpâ and âDownâ. Really all âUpâ is, is that GetKey (or GetButton, or whatever) was true last frame, but false this frame. And âDownâ is that GetKey was false last frame, and true this frame.
So for my inputs I just have a class (to store the state) and every frame it calls âGetKeyâ (or GetButton, etc), and it determines upness and downness.
Really basic example (mine is more robust actuallyâŚ)
public class FixedGetKey
{
public string InputID;
private bool _lastFrame;
private bool _currentFrame;
public FixedGetKey(string id)
{
InputID = id;
}
public void Update()
{
_lastFrame = _currentFrame;
_currentFrame = Input.GetKey(InputID);
}
public bool GetKey()
{
return _currentFrame;
}
public bool GetKeyDown()
{
return !_lastFrame && _currentFrame;
}
public bool GetKeyUp()
{
return _lastFrame && !_currentFrame;
}
}
public class MyScript : MonoBehaviour
{
private FixedGetKey _spaceKey = new FixedGetKey("space");
void FixedUpdate()
{
_spaceKey.Update();
if(_spaceKey.GetKeyDown())
//do stuff
}
}
Of course, this sometimes feels a little weird to the player depending how you deal with the inputs. Due to the way FixedUpdate is called, and âtimeâ holds (like say you want âif fire held 1 second, do Yâ) might feel sloppy as they arenât frame perfect. Itâs teeny tiny small, but many hardcore gamers claim they can feel it.
This is honestly why a lot of twitch games prefer constant framerates.
1 Like
Wow, this was a really thorough explanation
Thank you very much, i will try it ou and let you know how it works, i probably wonât even notice the difference except it will work
Every day is a new challenge with unity i guess