Hi, I have this code attached to a rigidbody, pretty simple stuff … or so I thought:
using UnityEngine;
using System.Collections;
public class PlayerInput : MonoBehaviour {
// Use this for initialization
void Start () {
}
// Update is called once per frame
void FixedUpdate () {
if ( Input.GetMouseButtonDown( 0 ) )
{
Debug.Log("Added force");
rigidbody.AddRelativeForce (Vector3.right * 500);
}
}
}
The problem is that it’s not always detecting the input - it does sometimes but not others…the kind of behaviour you’d expect if the input detection wasn’t based in Update(). But I assume as the code is physics related FixedUpdate() is the place to put it…? Isn’t FixedUpdate() also called every frame?
Thanks
Fixed Update is called at a fixed time rate and completely independent from your frame time. Dependant on your frame rate, it can be called multiple times per frame (if your timestep is very small and/or your framerate very low) or only once every couple of frames (the normal case, where you have a medium to high timestep and a high framerate).
Your problem here is, that GetMouseButtonDown (unlike GetMouseButton) is only fired exactly once in the frame (not physics timestep → FixedUpdate) it occurred, so you will likely miss it during FixedUpdate.
Try catching and storing the Input during normal Update() and then act upon the cached values during your FixedUpdate.
Something like this might work:
I use a kind of Input Converter to gather Network Input and even KeyUps/downs etc. based on simple check if key is pressed or not:
//Trigger: converts weapontrigger States to keyUp/KeyDown for fixedUpdate or coroutines
private WeaponTrigger wt;
private bool triggerWasPulled = false;
private bool triggerWasReleased = true;
private bool triggerDown = false;
private bool triggerUp = false;
private int triggerIndex = 0;
private bool trigger; //trigger 1-4 assignable
public void LinkTrigger(int index){//called by Loadout
triggerIndex = index;
}
void SetWt(){ //do in start
wt = transform.parent.GetComponent();
}
void TriggerCheck(){//do in Update
switch (triggerIndex){
case 0: trigger = wt.activation1; break;
case 1: trigger = wt.activation2; break;
case 2: trigger = wt.activation3; break;
case 3: trigger = wt.activation4; break;
case 4: trigger = wt.activation5; break;
case 5: trigger = wt.activation6; break;
case 6: trigger = wt.activation7; break;
case 7: trigger = wt.activation8; break;
//in WeaponTrigger Update:
//if (Input.GetKey(""+activationKey1)){activation1 = true;}else{activation1 = false;}
}
void KeyUpDownTransform(){//if keyup, keydown is needed
if(trigger &∓& triggerWasReleased) {triggerDown = true;}
if(!trigger && triggerWasPulled) {triggerUp = true;}
triggerWasPulled = trigger;
triggerWasReleased = !trigger;
}
void TriggerReset(){//if using keyup,down conversion reset on the end of update()
//resetTriggers
triggerDown = false;
triggerUp = false;
}
//Then Put the functions in the Right Frame-based Functions:
void Start () {
SetWt();
}
void Update () { //or LateUpdate or even FixedUpdate
TriggerCheck(); //on start of Update/Late/Fixed
KeyUpDownTransform(); //on start of Update/Late/Fixed
//Your KeyDepending Code
TriggerReset(); //on the end of Update/Late/Fixed
}
so you convert input based on its state of the last frame. however, things that you will still miss is if the user presses AND releases the key between 2 frames (mostly ~15ms) that also have happend between 2 fixed frames. this is nearly impossible as pressing a key for only 15ms alone is pretty hard to achieve