- Home /
Using Update() or Coroutine for this problem?
Let me explain, I have a GameStates manager which acts as an FSM to control each state of the game. When the FSM starts, it first runs the "Initialize" state in which I call a function that does some initialization and sends messages to other Managers to tell them it's time to cache some references to other things.
If the initialization was successful, GameStates then sets a static boolean to true: intiDone = true, and switches to the next state, Playing.
Now my other classes rely on initDone to set themselves up. The problem is that sometimes, initDone only becomes true after Update() in those classes, and Update() uses variables that get set when initDone becomes true.
So 1 solution is to use: if( initDone == false ) return; - in Update(), but it seems like a waste of time because it's always gonna have to check it before continuing.
The other solution i thought about is instead of using Update(), I would use a coroutine, that way when initDone = true, I can send a Message to all classes that are waiting for it, and start the coroutine in each class. The coroutine would run every frame just like Update().
But, I couldn't do that for FixedUpdate(), since physics should be in FixedUpdate I cannot have a coroutine running my physics calculations.
I am running into this problem a lot because of the OnEnable() bug which force the class it belongs to to execute before any other class which doesn't have OnEnable() defined. The whole idea behind my GameStates class was to control these kind of things, and it worked great until I started using LoadLevelAdditive() to load things like HUD, Controls and Player into each scene, instead of having to manually place them into each new scene I create.
Since those classes are being loaded after the current's scene classes, it broke my GameStates logic and I am now trying to make it work with classes that come in after the initialization.
Sorry for the long post, and thanks in advance for your time! If anyone could maybe give me some advice I would really appreciate it :)
Thanks guys, Stephane
Answer by whydoidoit · Nov 18, 2012 at 10:44 PM
So you can do Physics in a coroutine if you use
yield return new WaitForFixedUpdate();
You could also use a delegate in your Update function and switch it to point to something else when you are ready - though that's probably slower than an if check - neither are going to cost you much. The delegate method is good for state machines though - because you can switch between multiple - see my FSM article on Unity Gems
Action updateFunction;
void Start()
{
updateFunction = BeforeInitUpdate;
}
void BeforeInitUpdate()
{
//Any before init update logic
if(initDone)
updateFunction = AfterInitUpdate;
}
void AfterInitUpdate()
{
//Normal update functions
}
void Update()
{
updateFunction();
}
Oh man I didn't know about yield return new WaitForFixedUpdate(); hahaha thanks for pointing that out!
I'm reading your FS$$anonymous$$ article on Unity Gems right now...I have a lot to learn about proper uses of FS$$anonymous$$, your example above makes a lot of sense and I'm kinda mad at myself for not trying to learn more about this type of stuff. You get to a point when you think you have enough knowledge to actually "Start" writing code you can use in the final version of your game - after all, at one point or another you have to stop "learning" and start "making" right? - but judging from your small code snippet above, I could have used a much better implementation then what I'm doing...
And please post this as an answer so that I can vote and approve it :)
Thanks a lot, I'm gonna try to implement this and I might have a question or 2 later if I'm struggling, if you don't $$anonymous$$d :)
Yes you have to start writing code. You have to also finish too :) But there is nothing wrong with refactoring - just not if it breaks everything.
Finish anything, then learn, then do it better next time. That's what I do!
That Unity Gems Coroutines++ article might be useful reading/watching too. It's got a nice chart of where they run at least...
Well, I have been reading articles on Unity Gems for the past 4 hours, none of them which were on FS$$anonymous$$s hahaha...there is so much really good information there, answers to questions that I have had for a while and couldn't get any clear answers on.
I need to actually get some work done tonight, so i stopped reading halfway through the FS$$anonymous$$#2 article - and also because I have a headache...too much information intake... - but I'll be back tomorrow and the day after and after and after etc...
I just wanted to say that the way you explain things is just great, very easy to read and understand, and that's very hard to do - and come by - so I am really grateful :)
You should yield before you do physics.
IEnumerator SomeCoroutine()
{
//Not physics
while(true)
{
yield return new WaitForFixedUpdate();
//Physics
}
}
Answer by Steve Steven · Nov 18, 2012 at 10:35 PM
Sorry, I didn't read this at full because is too long, I suggest you to avoid the use of the bool initDone, because Unity calls Awake and Start voids at start, after these two it will call Update, which will called every frames. So Update will always be later then Start or Awake. I don't know if this was what you was asking for.
Please Steve, I appreciate you trying to help out, but I have read some of your other answers to other questions, and most of them are wrong or not related to the actual question, which is probably because, like you yourself said, didn't read the whole question...
I suggest that you don't post answers to questions you do not understand or haven't fully read. Ins$$anonymous$$d you should use this site to ask questions yourself and gain knowledge, as there are many great users here with lots of experience to share.
I hope I did not offend you as it wasn't my intention. But you already have a bunch of thumbs down, and that's not a good start if you wish people here to help you out when you have a question.
No you didn't offend me, I didn't read the full post, because I had to go to sleep, I am sorry about this.