- Home /
Splitting one event's code between Update and fixedUpdate
I am cleaning up some code to get rid of some bad practices that I have been getting away with until now. I am well aware that you should deal with rigid bodies and forces during fixedUpdate and not Update. Right now I am not doing this. This is what I am currently doing (using psuedocode for simplicity and abstraction) because this is a general problem I need to get my head around. This script is attached to the camera.
function Update(){
if (Input.GetButtonDown("Fire1"))
{
var ray1 : Ray = camera.ScreenPointToRay(Input.mousePosition);
var hit1 : RaycastHit;
if(Physics.Raycast(ray1 , hit1))
{
//simplified psuedo code here for sake of simplicity and to keep things relevant.
Scale the mesh only (not the collider) using iTween; //So needs to be done in Update
Apply force to collider at the hit point; //This needs to be done in the Fixed update
}
}
}
All of my code for this is working fine, I'm not seeing any problems (yet) so no help needed with the implementation. Just best practice on how to extract the Apply force line and put it in the FixedUpdate. I am sure if I leave this the way it is and play the game on a faster/slower machine - I'd see something glitchy happening.
Would I need to set up another raycast in fixedUpdate with only the apply force stuff in there, keeping the original raycast check in the update function to do the scaling?! This seems wasteful and backwards. There must be a 'proper' way to do this kind of thing.
Should I create separate scripts or functions for both the scaling (update) and the force (fixedupdate), then call them both from another script during the update?
What I am trying to say in a nutshell:
One event/action is happening (object clicked on by mouse)
Two things need to happen (one in FixedUpdate, one in Update)
What is the best practise for this suposedly fairly common scenario?
Thanks so much everybody.
Answer by Bunny83 · Jul 22, 2012 at 12:06 AM
FixedUpdate is only required if you have a continous force that you want to apply. For one time impulses you can or should use Update. Never use FixedUpdate to process events. Keyboard or mouse events can be dropped or processed multiple times if they are used in FixedUpdate. This is because everything is based on the Update cycle. FixedUpdate might be called one or several times per update or in some cases not at all.
Some examples (those assume a FixedUpdate rate of 60 fps):
At high framerates (~120 fps) FixedUpdate is called every second Update call. That means if an even happens in between two FixedUpdate calls, it isn't processed.
At low framerates (~30 fps) FixedUpdate is called two times per frame. That means GetKeyDown will return true for two FixedUpdate cycles because the state only changes per frame.
So, again: Do everything in Update, only physics related stuff that is applied over several frames should be placed in FixedUpdate.
edit:
Just to clarify: FixedUpdate is called along with Update, just in a different way. It's calling is "fixed" (not fix).
Here's the basic logic how FixedUpdate works:
// C#
float gameTime = 0.0f;
float fixedTime = 0.0f;
float fixedTimeStep = 0.02f; // 1/50 == 50fps
void UnitysInternalMainLoop()
{
while(true)
{
Update();
gameTime += Time.deltaTime;
while (gameTime - fixedTime > fixedTimeStep)
{
FixedUpdate();
fixedTime += fixedTimeStep;
}
}
}
This is just pseudo code. As far as i know the fixedupdate-cycles are executed before Update, but the concept is the same.
Wow, all of that made so much sense! I really can't thank you enough for putting this in terms that helped me to actually grasp the difference. Sometimes the unity manual and scripting reference rushes over things a little too quickly for my liking!
I can see now that as I am only applying a one-time impulse that is very ti$$anonymous$$g critical it wouldn't make sense at all to put that in the FixedUpdate!! This and that the last thing you actually want to do is put a constant force on something in the Update function which could be varying greatly depending on the FPS at the time! I feel dumb for not realizing this sooner and thinking the opposite!
Thanks Bunny83!
I've just created a "small" webplayer which visualizes how FixedUpdate works. It's actually more an eye candy ;)
I love the GL class :D
Bunny83, +1, nice job 8)
a little improvements for your wish: can u add a VSync effect to this demo? 8) and can i use it in other Unity Answers to visualize how it works?
@Scroodge$$anonymous$$: Thanks ;)
Sure you can use it, hopefully i can add some more basic feature / concept explanations.
Well, the target framerate can be configured manually, so there wouldn't be much difference. The main problem is that the simulation depends on pure calculations (to be able to go forward and backward). If the simulation would be just one way, it would be easier to implement true framerate variations.
vsync is quite simple. It just delays the current frame at the end until the next vertical sync of your monitor. This could result in some strange framerate variations. They are not easy to calculate from scratch.
Without vsync i can simply do (m_Time % (1/fps)) to get the frame start ;)
If i can find the time i might take a look at it.
i know what VSync do, i just have some troubles how to describe it to others 8) but thanks 8)))
Answer by ScroodgeM · Jul 21, 2012 at 09:20 PM
answer at the end of text 8)
FixedUpdate instead of Update should be used if you interact (e.g. read) some data from physics engine. this is because if you read data in U instead of FU you can read some data twice (two frames while 1 fixed update) and make unnecessary calculations, and also you can miss some threshold if your FPS is low (1 U for 5 FU), cause FU is always has fixedDeltaTime
so you can apply forces in Update or FixedUpdate of your choise - this force will be applied only on FixedUpdate stage.
it's just little cheap to calculate for example summary force from 3 Updates and apply it once in FixedUpdate
don't calc things like raycast twice without really need.
Hey Scroodge$$anonymous$$, thanks for answering so quickly...
Not sure if I get what you're trying to say...
Are you saying that what I am doing isn't necessarily bad, just a little computationally expensive? I was under the impression that applying forces in the update function was very bad practise and can cause gameplay issues on different devices. How would you personally go about what I am trying to achieve? Yes, I am in no doubt that ray casting twice for one event is a bad idea, I'd just like a viable alternative strategy!
i just found some crazy ideas about to do double raycasts and so on. that's why i said that this script is not so bad.
just replace
Apply force to collider at the hit point;
to
Store force to apply it in FixedUpdate
and apply it
and now your script is perfect 8)
PS 'apply force' is a complex method that calculates a speeds delta and so on. so the best way is to avoid of executing this method without really needs. in your case - move it's executing from U to FU and leaving all other calculations in U is the best way
Hmm, If I store the force in the Update function then apply in the FixedUpdate, will I need to apply a force of zero to every single object every fixed frame until my stored variable actually has a value? This seems like an inefficient way to go. Or should I have an if statement in my FU that only applies the force if the force variable isn't zero? If so, wouldn't I have to then have an if statement for every single object that could potentially have a force applied?
As for your suggestion about moving the apply force function line to the FU, how would I do this without having to have another ray cast check?
all you need to apply force in FU ins$$anonymous$$d of U is to store power point and direction. just store it in U and apply in FU
but
in your case (i'd check it again) you will not apply force more then twice in a single FU cause user not able to press a key twice in 0.025 sec. so your script is realy perfect 8)